Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running tasks parallel in powershell

I have a PowerShell script like this:

Foreach ($file in $files) {     [Do something]     [Do something]     [Do something] } 

This way one file is treated after the other. I want to treat 4 files at the same time.

I know of the foreach -parallel loop, but that does the [do something] tasks in parallel. I basically want to run the whole foreach loop in parallel.

How can I achieve this in PowerShell?

like image 333
Werner Schoemaker Avatar asked Apr 28 '17 17:04

Werner Schoemaker


People also ask

Can PowerShell run commands in parallel?

One of the most welcome new features in PowerShell 7 is the ability to perform parallel execution of script blocks. This new parallel execution capability can drastically reduce the amount of time it takes to process ForEach-Object loops.

Is multithreading possible in PowerShell?

Starting in PowerShell 7.0, the ability to work in multiple threads simultaneously is possible using the Parallel parameter in the Foreach-Object cmdlet.

What is parallel PowerShell?

The Parallel parameter runs commands in a script block in parallel. You can enclose a Parallel script block in a ForEach -Parallel script block. The target computers in a workflow, such as those specified by the PSComputerName workflow common parameter, are always processed in parallel.


2 Answers

You might look into Jobs or runspaces. Here is an example of Jobs:

$block = {     Param([string] $file)     "[Do something]" } #Remove all jobs Get-Job | Remove-Job $MaxThreads = 4 #Start the jobs. Max 4 jobs running simultaneously. foreach($file in $files){     While ($(Get-Job -state running).count -ge $MaxThreads){         Start-Sleep -Milliseconds 3     }     Start-Job -Scriptblock $Block -ArgumentList $file } #Wait for all jobs to finish. While ($(Get-Job -State Running).count -gt 0){     start-sleep 1 } #Get information from each job. foreach($job in Get-Job){     $info= Receive-Job -Id ($job.Id) } #Remove all jobs created. Get-Job | Remove-Job 

In the above code I have it where each $file is running in parallel with eachother (Up to 4 running simultaneously).

EDIT: In response to the comments, here is some documentation about scriptblocks. The short reason about why you must include the parameter is because unlike PowerShell functions, scriptblocks can't specify parameters outside of the braces {}.

like image 172
CuriousOne Avatar answered Sep 18 '22 14:09

CuriousOne


Powershell 7 introduces foreach-object -parallel:

https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/

Your script would then say

$files | ForEach-Object -parallel {     [Do something]     [Do something]     [Do something] } 
like image 44
staale.skaland Avatar answered Sep 17 '22 14:09

staale.skaland