PowerShell

PowerShell 7: Foreach-Object -Parallel

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:

Anmerkung 2020-03-01 094459.png

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

Anmerkung 2020-03-01 094257.png

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

Anmerkung 2020-03-01 094946.png

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.

 

4 replies »

  1. 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.

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.