How to Limit Resource Usage of PowerShell Scripts

Imagine that you want to run a PowerShell script on a server, but you know that the script might use a lot of resources and impact performance. In this article, I’ll show you how you can limit the resources used when running PowerShell code.

PowerShell scripts can use a lot of resources. And that can be a problem if you need to run a script on a production server without impacting performance. But there are a couple of tactics you can use to limit the resources PowerShell scripts use. PowerShell jobs let you run code asynchronously. So, rather than executing each line in a script one after another, you can set up two or more jobs to run your code concurrently. By organizing your code into script blocks that run as jobs, you get more control over resource usage.

PowerShell jobs

Jobs are run in the background but return control to PowerShell without waiting for the code to complete. Jobs provide you with control over how resources are used too. But PS Jobs put a strain on system resources because they create a new PowerShell host process for each job. So, they aren’t always the most efficient way to run PowerShell code.

Start-Job -ScriptBlock { Get-Process -Name lsass }

Once you start a job, you can use Receive-Job to get the output. In the code below, I get the job’s ID number using Get-Job and then pipe the object generated by Get-Job to Receive-Job, which displays the output in the terminal window.

Get-Job -Id 1 | Receive-Job
Image #1 Expand
Figure1 9
How to Limit Resource Usage of PowerShell Scripts (Image Credit: Russell Smith)

PowerShell thread jobs (PS ThreadJobs)

PowerShell 6 introduced PS ThreadJobs, which let run multiple threads in a single process. This improves performance while reducing overhead.

Start-ThreadJob -ScriptBlock { Get-Process -Name lsass }

Get-Job -Id 1 | Receive-Job

Because PS Jobs run in a PowerShell host process, there is a lot of flexibility in how they can be configured to run. For example, you can set the job to run as a different user, set a working directory, or run the job using a different version of PowerShell.

PS ThreadJobs don’t provide the same flexibility as PS Jobs, but it is possible to limit the number of threads created to restrict the system resources consumed. By default, PS ThreadJobs are limited to 5 threads. But using the -ThrottleLimit parameter, you can lower or raise that number:

Start-ThreadJob -ScriptBlock { Get-Process -Name lsass } -ThrottleLimit 2
Image #2 Expand
Figure2 4
How to Limit Resource Usage of PowerShell Scripts (Image Credit: Russell Smith)

ForEach-Object -Parallel parameter

Finally, PowerShell 7 introduced the -Parallel parameter for the ForEach-Object cmdlet. It forces each ForEach-Object loop to run in its own PS ThreadJob. Each loop gets to run in its own thread. You can also apply a throttle limit, just like when using the Start-ThreadJob cmdlet.

The command below writes Hello 1,2 etc. (#Image 3) to the terminal window with a 1 second delay between each loop. But because each loop is running in parallel, you see the output appear instantly.

1..5 | ForEach-Object -Parallel { "Hello $_"; sleep 1; } -ThrottleLimit 5
Image #3 Expand
Figure3 2
How to Limit Resource Usage of PowerShell Scripts (Image Credit: Russell Smith)

 

PowerShell jobs give you some flexibility in how your code runs. Careful planning and script optimization can help make sure that scripts run efficiently without overwhelming host resources.