views:

44

answers:

1

I have a very simple Powershell v1.0 script to kill processes by name:

$target = $args[0]
get-process | where {$_.ProcessName -eq $target} | stop-process -Force

which works. However, when I just had

get-process | where {$_.ProcessName -eq $args[0]} | stop-process -Force

it wouldn't find any processes. So why does the argument need to be copied into a local variable for the code to work?

+4  A: 

This came up yesterday in another post. Basically a scriptblock { <script> } gets its own $args that represents unnamed arguments passed into it e.g.:

PS> & { $OFS=', '; "`$args is $args" } arg1 7 3.14 (get-date)
$args is arg1, 7, 3.14, 03/04/2010 09:46:50

The Where-Object cmdlet is using a scriptblock for you to provide arbitrary script which it evaluates to either true or false. In the Where-Object case, there are no unnamed arguments passed into the scriptblock so $args should be empty.

You've found one work-around. The one I would suggest is to use a named parameter e.g.:

param($Name, [switch]$WhatIf)
get-process | where {$_.Name -eq $Name} | stop-process -Force -WhatIf:$WhatIf
Keith Hill
I see. And as I didn't initially use a scriptblock, that would explain why my code was working for a while.I have been using PowerShell for some months now, on and off, and I'm trying very hard to like it, but it's hard work.
Charles Anderson
I think they were onto something when they named it "Power"Shell. It is very powerful but with that power comes complexity. Fortunately the speed of information transfer over the internet makes it easy and quick to get help from a large community of folks who have already climbed PowerShell's somewhat steep learning curve.
Keith Hill