Previously (here and here), I've written about isolating shared services so that they run in their own process, with a specific focus on the Windows Update Automatic Updates Service (wuauserv) that typically runs in the NETSVCS SVCHOST.EXE instance. One thing that can be done once this is accomplished is to lower the priority of the process so that when the service winds up consuming 100% of the CPU, the system doesn't become unresponsive.
Since we're dealing with a service, setting the priority of such a SVCHOST.EXE process can become problematic - the service may already be running, or, because it is a service, it is not started as non-service processes are, so one is not able to use START / [LOW NORMAL HIGH REALTIME ABOVENORMAL BELOWNORMAL] to impose a priority when the process starts. One can use a utility like Task Manager or Process Explorer to set the priority of a process on an ad hoc basis, but when the service restarts or the system reboots one has to remember to set the priority again.
Though not an ideal solution the following scripts (VBS using WMI, and PowerShell) can be used to set the priority of the SVCHOST.EXE instance hosting the isolated Windows Update Automatic Updates Service service to "below normal". Note that no check is done to ensure that the SVCHOST.EXE instance is only hosting one service - if wuauserv is found to be a service inside of the process, the priority is adjusted. Note also that no error handling is implemented.
I'll try to format the code so it looks nice, but I fear I will be limited...
Here's the code for the VBS / WMI script:
Const BELOW_NORMAL = 16384
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colServices = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Service where name='wuauserv'")
For Each oService in colServices
Set colProcesses = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Process where ProcessId=" & oService.ProcessId )
For Each oProcess in colProcesses
oProcess.SetPriority(BELOW_NORMAL)
Next
Next
Here's the code for the PowerShell script:
(gps -id (get-wmiobject win32_service where {$_.name -eq "wuauserv"}).ProcessId).PriorityClass="BelowNormal"
The different values for the priority parameter of the SetPriority method of the Win32_Process WMI class can be found in the documentation for the SetPriority method.
The different values for the PriorityClass in the PowerShell script are "Normal", "Idle", "High", "RealTime", "BelowNormal", or "AboveNormal". Or, to get a list of the available options, one can use the following PowerShell command:
[ENUM]::getNames("System.Diagnostics.ProcessPriorityClass")
Once the script is in place and working, one can cause it to be invoked at will, or via scheduled task at specific times, or after logon, or any other way that one can get something to happen when Windows boots or a user logs on.
»