I'm not sure whether to call this a need for multi-threading, job-based, or async, but basically I have a Powershell script function that takes several parameters and I need to call it several times with different parameters and have these run in parallel.
Currently, I call the function like this:
Execute "param1" "param2" "param3" "param4"
How can I call this multiple times without waiting for each call to Execute return to the caller?
Currently I'm running v2.0 but I can update if necessary
EDIT: here's what I have so far, which doesn't work:
$cmd = { param($vmxFilePath,$machineName,$username,$password,$scriptTpath,$scriptFile,$uacDismissScript,$snapshotName) Execute $vmxFilePath $machineName $username $password $scriptTpath $scriptFile $uacDismissScript $snapshotName } Start-Job -ScriptBlock $cmd -ArgumentList $vmxFilePath, $machineName, $username $password, $scriptTpath, $scriptFile, $uacDismissScript, $snapshotName
I get an error:
cannot convert 'system.object[]' to the type 'system.management.automation.scriptblock' required by parameter 'initializationscript'. specified method is not supported
EDIT2: I've modified my script but I still get the error mentioned above. Here's my mod:
$cmd = { param($vmxFilePath,$machineName,$username,$password,$scriptTpath,$scriptFile,$uacDismissScript,$snapshotName) Execute $vmxFilePath $machineName $username $password $scriptTpath $scriptFile $uacDismissScript $snapshotName } Start-Job -ScriptBlock $cmd -ArgumentList $vmxFilePath, $machineName, $username $password, $scriptTpath, $scriptFile, $uacDismissScript, $snapshotName
You can execute parallel jobs in Powershell 2 using Background Jobs. Check out Start-Job and the other job cmdlets.
Normally, when you use the ForEach-Object cmdlet, each object piped to the cmdlet is processed sequentially. But with the new ForEach-Object -Parallel parameter set, you can run all script in parallel for each piped input object.
PowerShell does not provide an async or await keyword. The PowerShell engine itself has a tendency to very single-threaded unless you take steps to use Start-Job or Start-ThreadJob . Because of this, you'll need to take care when calling async methods in .
To pass multiple parameters you must use the command line syntax that includes the names of the parameters. For example, here is a sample PowerShell script that runs the Get-Service function with two parameters. The parameters are the name of the service(s) and the name of the Computer.
No update necessary for this. Define a script block and use Start-Job
to run the script block as many times as necessary. Example:
$cmd = { param($a, $b) Write-Host $a $b } $foo = "foo" 1..5 | ForEach-Object { Start-Job -ScriptBlock $cmd -ArgumentList $_, $foo }
The script block takes 2 parameters $a
and $b
which are passed by the -ArgumentList
option. In the example above, the assignments are $_
→ $a
and $foo
→ $b
. $foo
is just an example for a configurable, but static parameter.
Run Get-Job | Remove-Job
at some point to remove the finished jobs from the queue (or Get-Job | % { Receive-Job $_.Id; Remove-Job $_.Id }
if you want to retrieve the output).
Here's a quick bogus scriptblock for the purpose of testing:
$Code = { param ($init) $start = Get-Date (1..30) | % { Start-Sleep -Seconds 1; $init +=1 } $stop = Get-Date Write-Output "Counted from $($init - 30) until $init in $($stop - $start)." }
This scriptblock can then be passed on to Start-Job
, with for example 3 parameters (10, 15, 35)
$jobs = @() (10,15,35) | % { $jobs += Start-Job -ArgumentList $_ -ScriptBlock $Code } Wait-Job -Job $jobs | Out-Null Receive-Job -Job $jobs
This creates 3 jobs, assign them to the $jobs
variable, runs them in parallel and then waits for these 3 jobs to finish, and retrieves the results:
Counted from 10 until 40 in 00:00:30.0147167. Counted from 15 until 45 in 00:00:30.0057163. Counted from 35 until 65 in 00:00:30.0067163.
This did not take 90 seconds to execute, only 30.
One of the tricky parts is to provide -Argumentlist
to Start-Job
, and include a param()
block inside the ScriptBlock. Otherwise, your values are never seen by the scriptblock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With