Hey, Scripting Guy! Can I Use Windows PowerShell to Lower the Priority of a Process?

Hey, Scripting Guy! Can I Use Windows PowerShell to Lower the Priority of a Process?

  • Comments 3
  • Likes

Bookmark and Share 

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a problem with a rather annoying program at work. The program starts up and runs with high priority. When it does this, my computer is slow as a snail, and as unresponsive as a bear hibernating in the winter. I would like to use Windows PowerShell to lower the priority of this process. Can this be done?

-- CS

 

Hey, Scripting Guy! AnswerHello CS, Microsoft Scripting Guy Ed Wilson here. Speaking of winter, the Scripting Wife and I are heading to Raleigh, North Carolina, this weekend to visit some friends, and to see an ice show. It should be pretty cool. (As an aside, I have visited nearly one-quarter of all the countries in the world, but this will be my first visit to the capital city of my home state. So I am psyched.)

CS, you mention bears. One thing to keep in mind about hibernating bears in the winter is that not all bears actually hibernate. Polar bears do a sort of waking hibernation that allows them to conserve food, but I imagine if you came across one, he would be rather responsive. Just a safety tip as it were—it might be somewhat interesting if one were to awaken a 1,500-pound (680-kilogram) bear that was snoozing because he was hungry. My favorite polar bear is named Knut, and the Scripting Wife and I had the opportunity to meet him in Berlin, Germany, when I was there teaching a Windows PowerShell class. We went to the Berlin Zoological Garden and spent a lovely day taking pictures and walking around. As you can see from this photo I took, Knut is no longer a little cub, but he is still cute.

Photo Ed took in Berlin, Germany, of Knut the polar bear

 

CS, you can use Windows Management Instrumentation (WMI) to work with the priority of a process in Windows PowerShell. To see the priority of a process (such as Notepad) use the Get-WmiObject cmdlet to query the Win32_Process class. You could use this command (or using the gwmi alias and positional arguments, it would be gwmi Win32_process), but you would get back several pages of information about every process on your computer:

Get-WmiObject -Class win32_process

To limit the information that is returned to only the Notepad process, you can add a filter to your command (gwmi win32_process -f "name='notepad.exe'" using the alias, positional arguments, and partial parameter completion):

Get-WmiObject win32_process -Filter "name='notepad.exe'"

Using only the filter to limit results to the Notepad process may be just ducky for you. Depending on how busy I am, I may simply search through the 60 lines of output and find the priority property to see at what priority the process is currently running. This is shown in the following image.

Image of searching through lines of code for priority property


If I have more time, I may pipe the results to the Format-Table cmdlet and choose the properties I am interested in examining. This is illustrated here:

PS C:\> gwmi win32_process -f "name='notepad.exe'" | Format-Table name, priority, Handle -AutoSize

 

name        priority Handle

----        -------- ------

notepad.exe        6 4236

 

 

PS C:\>

At any rate, MSDN documentation tells us that the priority property of the Win32_Process WMI class is reported as a range of numbers from 0 (lowest) to 31 (highest).

To set the priority of a process, use the SetPriority method. The thing that is confusing is that the SetPriority method takes an integer to tell it which priority to set; however, it is a different number than the one that you retrieve from the priority property. To use this method, you need to refer to the table on MSDN that details the allowed values and their meanings. Table 1 is a summary of those values.

Table 1  Values and Meanings of the SetPriority Method

Value

Meaning

64 (0x40)

Idle

16384 (0x4000)

Below Normal

32 (0x20)

Normal

32768 (0x8000)

Above Normal

128 (0x80)

High Priority

256 (0x100)

Real Time

 

To change the priority of a process, you need to connect directly to the process. The SetPriority method is what is called an instance method, and therefore we need to return an instance of a process. To do this, use the key property of the class. The key property for Win32_Process is Handle (MSDN reports the key property qualifier). Use the WMI class accelerator to connect to the specific instance of the WMI class. The code to do this is shown here:

[wmi]"win32_process.handle='4236'"

When that line of code is run, the results appear that are shown in the following image.

Image of what is shown when line of code runs

 

Now that I know that the command is returning the exact Notepad process that I am interested in working with, it is time to call the SetPriority method. To do this we modify the command just a little bit, as seen here where we change the priority of the Notepad process to a very low priority:

PS C:\> ([wmi]"win32_process.handle='4236'").setPriority(64)


__GENUS          : 2
__CLASS          : __PARAMETERS
__SUPERCLASS     :
__DYNASTY        : __PARAMETERS
__RELPATH        :
__PROPERTY_COUNT : 1
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
ReturnValue      : 0



PS C:\>

 

CS, that is all there is to using WMI to change the priority of a process. WMI Week will continue tomorrow when we will talk about…wait a minute.

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Might this be an alternative solution (using the calculator as the process)?

    $p = Get-Process -Name calc

    $p.PriorityClass = [System.Diagnostics.ProcessPriorityClass]::Normal

  • PerH - Good question.  I would like to see it answered

  • @PerH, ZicaBunGon

    That will just as well as going the WMI route. That is one of the great things about PowerShell in that there are usually more than one way to accomplish the same goal.