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.

 

2 replies »

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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