With PowerShell 7 a new feature was introduced: Foreach-Object -Parallel. The parallel feature will speed up loops in PowerShell. In this blog post I will compare the old technique with the new one and I am sure the reader will be in for a surprise. Let’s jump in.
Let’s say you have a script with loops and this script takes a long time to complete. You want to make your script run faster, but you have figured out there is currently no easy way to do that.
Then it’s time to change to PowerShell 7, because Foreach-Object -Parallel opens parallel threads and iterates each item in the loop in parallel. That will significantly speed up the runtime of the loop.
What is Foreach-Object -Parallel ?
Foreach-Object -Parallel provides parallel processing of input objects. PowerShell will only process 5 input objects at a time. This limit can be increased with the -ThrottleLimit parameter.
Example:
$test = 'sid-500.com','orf.at','8.8.8.8','cnn.com' $test | ForEach-Object -Parallel {Test-Connection -TargetName $_}
Now we see how much use it is.
Comparing foreach | Foreach-Object | Foreach-Object -Parallel
I’ve prepared a sample for a better understanding. I will do some port scanning to test if a port is open or not. Furthermore I use Measure-Command to measure how long the code will run. The objective is to compare the old technique with the new one.
foreach ()
The first code will test host 192.0.78.24 (sid-500.com) with foreach (). The tested port numbers are 443 (HTTPS), 80 (HTTP), 53 (DNS) and 88 (Kerberos).
Measure-Command { $port = '443','80','53','88' foreach ($p in $port) { Test-NetConnection -ComputerName 192.0.78.24 -Port $p -WarningAction Ignore }} | Select-Object Minutes,Seconds
Here is the result:
Ok, that took about 1 minute and 18 seconds. By the way, all codes were exectued in Visual Studio Code which is at that time the default editor of PowerShell 7.
Foreach-Object
Next, I will try Foreach-Object without parallel processing.
Measure-Command { $port = '443','80','53','88' $port | ForEach-Object {Test-NetConnection -ComputerName 192.0.78.24 -Port $_ -WarningAction Ignore} } | Select-Object Minutes,Seconds
The same here.
Which brings me to the new feature.
Foreach-Object -Parallel
First of all, as mentioned at the beginning, keep in mind that Foreach-Object -Parallel is limited to 5 script blocks at a time. This setting can be increased by the -ThrottleLimit Parameter. No problem here, I will only use 4 parallel processing objects.
What speed advantages will it bring? Here it is in action.
Measure-Command { $port = '443','80','53','88' $port | ForEach-Object -Parallel {Test-NetConnection -ComputerName 192.0.78.24 -Port $_ -WarningAction Ignore} } | Select-Object Minutes,Seconds
This is more than twice as fast! Fantastic!
More about the new parallel feature here: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7
Have fun speeding up your script with PowerShell 7 and Foreach-Object -Parallel.
Categories: PowerShell
function axadd($add){
return $add + 5
}
1..5 | ForEach-Object -Parallel { axadd($_); sleep 1; } -ThrottleLimit 5
Whats is wrong in this code ? or there is a problem with -Paralle, as not identifying function axadd.
Error
axadd: The term ‘axadd’ is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
LikeLike
function axadd($add){
return $add + 5
}
1..5 | ForEach-Object -Parallel { axadd($_); sleep 1; } -ThrottleLimit 5
what’s wrong in this code ? or it’s a bug with -Parallel
LikeLike
I’m so late lol I just got around to mentioning this feature in my blog. I will upload examples when I have more time.
LikeLike