5

Based on How to execute a PowerShell function several times in parallel?, I'm able to do this, where I stop all running jobs, in parallel.

# Run this in parallel
$stopService {
  param($service)
  Stop-Service -Name $service.name -Force
}

$services = Get-Services | Where-Oject {$_.name -like "*XYX_*"}
Foreach($service in Sservices) {
  Start-Job -ScriptBlock $stopService -ArgumentList $service
}

$doSomethingElse

But how can I modify the code so all my parallel jobs finish first before I $doSomethingElse?. Kinda like a join() command?

Chris F
  • 14,337
  • 30
  • 94
  • 192
  • 3
    Santiago's answer solves your problem well in PowerShell v2. Note that `Start-Job` uses parallelism based on _child processes_, which is both slow and resource-intensive. In later PowerShell versions, much faster _thread_-based parallelism via `Start-ThreadJob`, from the `ThreadJob` module, is available, especially in _PowerShell (Core) 7+_, which ships with that module - see [this answer](https://stackoverflow.com/a/56612574/45375). – mklement0 Mar 05 '22 at 22:43
  • 2
    Adding to mklement0's informative and helpful comment, if you're unable to install Modules due to company policies, etc; you can also use [Runspaces](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces?view=powershellsdk-7.0.0). – Santiago Squarzon Mar 05 '22 at 22:50

1 Answers1

8

You can capture all the instances of PSRemotingJob returned by Start-Job in a variable and then wait for them either using Wait-Job or using Receive-Job -Wait -AutoRemoveJob:

$jobs = foreach($service in $services) {
    Start-Job -ScriptBlock $stopService -ArgumentList $service
}

Receive-Job $jobs -Wait -AutoRemoveJob

There are other alternatives, such as the one displayed in this answer, using a loop and WaitHandle.WaitAny Method

This answer shows a similar, more developed alternative, using a function to wait for Jobs with progress and a optional TimeOut parameter.

Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37