Monday, August 26, 2019

ForEach-Object -Parallel - Comes to PowerShell 7 in P.3

The latest preview edition of PowerShell 7 (itself due for full release at end of Sept or thereabouts) contains a long-awaited feature - the ability to run invocations of a given script block in parallel natively.

An example: Suppose you had a script that used WMI remotely to gather/update information on a number of remote servers. Instead of doing the required operations on one server at a time, running each invocation of the script block in parallel. The ability to run script blocks in parallel has been a huge reason many folks use Workflows (which are not part of PowerShell 7). Foreach -Parallel does away with the need to use workflows just to get parallelism.

Consider the following snippet:

'Non-parallel' $Sb1 = { 1..100 | foreach-object { start-sleep -Milliseconds 100 }} Measure-command { ICM -ScriptBlock $Sb1 } $len = 0

In this sample, you run a script block 100 times. Admittedly the actual script block is not all that exciting but it's an operation that is being done in each iteration of ForEach-Object. The output shows this:

With the third preview of PowerShell 7, the ForEach-Object cmdlet has two new parameters. The first -Parallel which says to run things in parallel. The second, -Throttlelimit tells PowerShell how many separate parallel invocations are allowed. 

Let's rerun that script block but using parallelism and varying the throttle limit:

As you can see, without parallelism, this "script" takes 11.07 seconds. With parallelism, the script takes 4.93 seconds (using throttle limit of 4), 3.70 seconds (throttle limit of 8) and just 2.92 seconds (throttle limit of 12). My system is a dual-processor 6-core system by way of comparison. If you try this, you may get different results depending on your hardware.

No comments: