$parallelCount = 2 $jobList = New-Object System.Collections.ArrayList $jobStatus = New-Object System.Collections.ArrayList $null = $jobList.Add({start-sleep -seconds 10; write-host "10 seconds done"}) $null = $jobList.Add({start-sleep -seconds 20; write-host "20 seconds done"}) $null = $jobList.Add({start-sleep -seconds 30; write-host "30 seconds done"}) Write-Debug "$(get-date): starting jobs" while ($jobList.Count -gt 0 -or $jobStatus.Count -gt 0) { $runCount = $([Math]::Min($parallelCount,$jobList.Count)) foreach($i in 1..$runCount) { if($runCount -gt 0) { $j = Start-Job -ScriptBlock $jobList[0] $null = $jobStatus.Add($j) Write-Debug "$(Get-Date): started job: $($jobList[0])" $jobList.Remove($jobList[0]) } } $null = Wait-Job -Job $jobStatus -Any $completedJob = $jobStatus | ? {$_.State -eq "Completed"} if($completedJob) { Receive-Job -Job $completedJob $completedJob | % { $jobStatus.Remove($_) } } }