Graph and PowerShell Blog | About | Links
PoshRSJob v PowerShell Core Parallel shootout
21-Sep-24

When I first got into writing more advanced PowerShell scripts for checking computers on my network, I ran everything consecutively. I soon found out this was a pretty bad way of doing things, a 4 hour script would typically get stuck on a remote WMI command that had no timeout.

Out of necessity, I looked into runspaces, which basically spawns a load of PowerShell processes to check computers in parallel. The results were brilliant, a 4-hour script went down to minutes, and as you can timeout the jobs, the script would no longer get stuck.

There were a few trade-offs, CPU and memory usage can be very high, and there can be memory leaks and processes that don't get removed after the runspace completes. But, overall using runspaces is a much better way to scan a network.

While Runspaces in PowerShell 5.1 are native, they are not easily set-up, so after some trial and error I settled on the excellent PS Module from Boe Prox, PoshRSJob. The module allows for easy creation of runspaces and has settings for throttle and timeout.

After recently moving all my scripts to PowerShell Core (7.1) I wanted to try out the native foreach parallel option, but how does it compare?

Test 1: ping 2,000 computers in parallel, throttle set to 200.
PoshRSJob: 18 seconds
Foreach Parallel: 19 seconds

In this test, both handled memory usage well, with the Pwsh.exe hitting a max of 400MB.

Test 2: ping 2,000 computers in parallel, then test the SMB port.
PoshRSJob: 60 seconds
Foreach Parallel: failed

As soon as the scriptblock gets a bit more complicated we see major problems with ForEach Parallel. The memory usage exceeded 4.5GB and was still rising when I killed the process. No results were returned when the script finished, though I'm not exactly sure why. In comparison the PoshRSJob worked as expected with only a slight increase in memory.

For now, I will continue to use PoshRSJob. Generally when I'm checking all computers on the network I'm looking for a setting in the registry or via CIM, not just to simply ping them.