Parallel and ThrottleLimit Parameters added to ForEach-Object in PowerShell 7 Preview 3

Preview 3 of PowerShell 7 was released yesterday. It can be downloaded from the PowerShell repository on GitHub. Be sure to choose the preview version for the appropriate operating system. It should go without saying that anything with preview in its name should NOT be installed on a mission-critical production system.

The examples shown in this blog article are being run on a system running Windows 10 (x64). Your mileage may vary with other operating systems and/or versions.

1$PSVersionTable.PSVersion

pwsh7-preview3.jpg

One of the hot new features in this release is the addition of the ability to run ForEach-Object in parallel with the new Parallel parameter. This is different than running foreach in parallel in a workflow in Windows PowerShell.

First, I'll start by using the range operator to simply sleep 10 times for one second each as shown in the following example. Measure-Command is used to determine how long the command takes and I'll use the dotted-notation syntax style to return only the total seconds.

1(Measure-Command {
21..10 | ForEach-Object {Start-Sleep -Seconds 1}
3}).TotalSeconds

foreach-object-parallel1a.jpg

The same command is used in the next example except the Parallel parameter has been specified. You would think this should finish is about a second or so depending on the overhead, but over two seconds seems too long, although it is indeed roughly 5 times faster than the previous example.

1(Measure-Command {
21..10 | ForEach-Object -Parallel {Start-Sleep -Seconds 1}
3}).TotalSeconds

foreach-object-parallel2a.jpg

The answer to why the previous command took over two seconds is because a ThrottleLimit parameter has also been added and it defaults to a limit of 5 threads at a time. Divide the 10 times the previous command is being run by the throttle limit of 5 and that's why it took over two seconds for the previous example to complete.

In the next example, I'll specify 10 as the value for the ThrottleLimit parameter since I know the command is going to run 10 times.

1(Measure-Command {
21..10 | ForEach-Object -Parallel {Start-Sleep -Seconds 1} -ThrottleLimit 10
3}).TotalSeconds

foreach-object-parallel3a.jpg

Now those results are more like what was expected. Run something for one second 10 times in parallel and it takes about a second plus some overhead to complete.

In addition to the parameters shown in this blog article, ForEach-Object also adds TimeoutSeconds and AsJob parameters in PowerShell 7 Preview 3.

You can find more information about what's new in PowerShell 7 Preview 3 in this article that was posted on the PowerShell team blog yesterday.

µ