Search code examples
powershellparallel-processingjobs

Powershell Execute program in parallel and wait end of execution


I need to execute a program (.exe) in a powershell script in a foreach loop, I need to wait the end of execution before doing some other tasks.

I tried this solution, the program is launched but it's closing immediately

$jobArray = New-Object -TypeName System.Collections.ArrayList

ForEach  ($item in Get-Content C:\items.txt) {                        
    
    $job = Start-Job -ScriptBlock {Start-Process "C:\Development\Console.exe" -ArgumentList /count, /Id:$item, /verbose }
    $jobArray.Add($job)
}      

Write-Verbose "started" -Verbose


#Wait for all jobs
ForEach  ($job in $jobArray) {       
  $job | Wait-Job
}

Solution

  • A process already is like a job, it runs in parallel. In fact, PowerShell jobs are also just processes, so you currently start a process just to start another process.

    Use Start-Process -PassThru without -Wait to capture a process object on which you can wait using Wait-Process.

    $processes = ForEach ($item in Get-Content C:\items.txt) {
        Start-Process -PassThru -FilePath 'C:\Development\Console.exe' -ArgumentList '/count', "/Id:$item", '/verbose'
    }      
    
    Write-Verbose "started" -Verbose
    
    # Wait for all processes
    $processes | Wait-Process
    

    As another optimization, most of the times you use a foreach or ForEach-Object loop you don't need to use ArrayList explicitly. Just assign the loop statement or pipeline to a variable and let PowerShell create an array for you in an efficient way.