Using start-job -scriptblock to run script; need help using parameters
-
Friday, March 01, 2013 7:34 PM
I've written a couple of PowerShell scripts to collect performance data from a group of servers. GetPerfCounters.ps1 reads a text file with a list of servers and collects and outputs the counters. StartPerfJobs.psq uses start-job to run multiple instances of GetPerfCounters.psq so I can split the work. Here's the portion of the script that uses start-job:
function StartJobs {
param ([string] $ServerList, [string] $Path)
Start-Job -ScriptBlock { c:\PerfData\GetPerfCounters.ps1 $args[0] $args[1] } -ArgumentList @($ServerList, $Path);
}This is working great and gives me what I'm looking for. Now, what I'd like to do is replace the path (c:\PerfData) in the scriptblock with the value being passed in, $Path, so that it would look something like this:
function StartJobs {
param ([string] $ServerList, [string] $Path)
Start-Job -ScriptBlock { $args[1]\GetPerfCounters.ps1 $args[0] $args[1] } -ArgumentList @($ServerList, $Path);
}
I've tried various ways, but can't get it to work. Any suggestions would be appreciated.
All Replies
-
Friday, March 01, 2013 7:47 PMModerator
Passing arguments can get clumsy.
When it starts getting complicated, I usually resort to just creating the scriptblock from an expandable string:
$sb = [scriptblock]::create("$Path\GetPerfCounters.ps1 $ServerList $Path") Start-Job -ScriptBlock $sb
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
- Marked As Answer by ButchW Monday, March 04, 2013 4:24 PM
-
Monday, March 04, 2013 1:31 PMModerator
Using named parameters with your job will also lessen the complexity that you will find by trying to use $args in the scriptblock.
function StartJobs { param ([string] $ServerList, [string] $Path) Start-Job -ScriptBlock { Param ($ServerList,$Path) ."$path\GetPerfCounters.ps1 $ServerList $Path" } -ArgumentList $ServerList, $Path } -
Monday, March 04, 2013 4:23 PM
Thanks for both of the replies.
Boe, I had tried something like that before without success. I tried it again and got this error:
The term 'c:\PerfData\GetPerfCounters.ps1 c:\PerfData\PerfServerList1.txt c:\PerfData' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (c:\PerfData\Get...txt c:\PerfData:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundExceptionI read somewhere that PowerShell can't run a string as a command, so tied adding the & operator, but still got an error.
Rob's solution with the [scriptblock]::create suggestion works.
Again, thanks to both of you for expanding my PowerShell knowledge.
Butch WEber
-
Monday, March 04, 2013 6:45 PMModerator
That is correct, instead of using "." or the ampersand "&", you would need to use Invoke-Expression to run a string like a command. This may work better.
function StartJobs { param ([string] $ServerList, [string] $Path) Start-Job -ScriptBlock { Param ($ServerList,$Path) Invoke-Expression "$path\GetPerfCounters.ps1 $ServerList $Path" } -ArgumentList $ServerList, $Path }

