Reputation: 34677
There's this powershell script which can set processes' priorities from "Idle" to "Realtime" but some tools offer another priority level which drops a process's priority even below:
How to set that in Powershell?
Upvotes: 6
Views: 7232
Reputation: 31
Following on from Peter Friend's answer above, I wrote a powershell script that updates all 3 of the priorities in question (CPU, Memory and IO). I'll post it here because this is the #1 result in google for this question.
You can run it from Powershell like this -
.\SetProcessPriority.ps1 -ProcessName sqlservr -CpuPriorityClass Idle -MemoryPriority 1 -IoPriority 0
SetProcessPriority.ps1 code -
[CmdletBinding()]
Param (
[string]$ProcessName = "sqlservr",
[string]$CpuPriorityClass = "Idle",
[int]$MemoryPriority = 1,
[int]$IoPriority = 0
)
# If you can't run, execute this first from an elevated PowerShell Prompt - set-executionpolicy remotesigned
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
Break
}
Add-Type @"
using System;
using System.Runtime.InteropServices;
namespace SysWin32
{
public enum PROCESS_INFORMATION_CLASS
{
ProcessMemoryPriority,
ProcessInformationClassMax,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public uint Information;
}
public partial class NativeMethods {
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="GetCurrentProcess", SetLastError=true)]
public static extern System.IntPtr GetCurrentProcess();
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="OpenProcess", SetLastError=true)]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="SetProcessInformation", SetLastError=true)]
public static extern bool SetProcessInformation(System.IntPtr hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, System.IntPtr ProcessInformation, uint ProcessInformationSize) ;
}
}
namespace SysWinNT
{
public enum PROCESS_INFORMATION_CLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessTlsInformation,
ProcessCookie,
ProcessImageInformation,
ProcessCycleTime,
ProcessPagePriority,
ProcessInstrumentationCallback,
ProcessThreadStackAllocation,
ProcessWorkingSetWatchEx,
ProcessImageFileNameWin32,
ProcessImageFileMapping,
ProcessAffinityUpdateMode,
ProcessMemoryAllocationMode,
ProcessGroupInformation,
ProcessTokenVirtualizationEnabled,
ProcessConsoleHostProcess,
ProcessWindowInformation,
MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum
}
public partial class NativeMethods {
[System.Runtime.InteropServices.DllImportAttribute("ntdll.dll", EntryPoint="NtSetInformationProcess")]
public static extern int NtSetInformationProcess(System.IntPtr hProcess, PROCESS_INFORMATION_CLASS processInformationClass, System.IntPtr ProcessInformation, uint ProcessInformationSize);
}
}
namespace WSG.Utils
{
public class PermissionsSetter
{
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const string SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege";
public const string SE_AUDIT_NAME = "SeAuditPrivilege";
public const string SE_BACKUP_NAME = "SeBackupPrivilege";
public const string SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege";
public const string SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege";
public const string SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege";
public const string SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege";
public const string SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege";
public const string SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege";
public const string SE_DEBUG_NAME = "SeDebugPrivilege";
public const string SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege";
public const string SE_IMPERSONATE_NAME = "SeImpersonatePrivilege";
public const string SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege";
public const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
public const string SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege";
public const string SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege";
public const string SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege";
public const string SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege";
public const string SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege";
public const string SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege";
public const string SE_RELABEL_NAME = "SeRelabelPrivilege";
public const string SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege";
public const string SE_RESTORE_NAME = "SeRestorePrivilege";
public const string SE_SECURITY_NAME = "SeSecurityPrivilege";
public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
public const string SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege";
public const string SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege";
public const string SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege";
public const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
public const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
public const string SE_TCB_NAME = "SeTcbPrivilege";
public const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";
public const string SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege";
public const string SE_UNDOCK_NAME = "SeUndockPrivilege";
public const string SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege";
public static bool AddPrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
public static bool RemovePrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_DISABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
}
}
"@
$OverallResult = 0
[void][WSG.Utils.PermissionsSetter]::AddPrivilege([WSG.Utils.PermissionsSetter]::SE_DEBUG_NAME)
[void][WSG.Utils.PermissionsSetter]::AddPrivilege([WSG.Utils.PermissionsSetter]::SE_INC_BASE_PRIORITY_NAME)
$Process = Get-Process $ProcessName
$ProcessId = $Process.id
Try
{
$Process.PriorityClass=$CpuPriorityClass
}
Catch
{
Write-host -BackgroundColor Black -ForegroundColor Red "Error setting process priority - $($_.Exception.Message)"
pause
$OverallResult = 1
exit $OverallResult
}
Write-Host -ForegroundColor Green ("Set CPU piority on {0} ({1}) to be {2}" -f $ProcessName, $ProcessId, $CpuPriorityClass)
# 4096 or 0x1000 = PROCESS_QUERY_LIMITED_INFORMATION
# 1056763 or 0x00101ffb = PROCESS_ALL_ACCESS
$DesiredAccess = 0x00101ffb
$InheritHandle = $false
$hProcess = [SysWin32.NativeMethods]::OpenProcess($DesiredAccess, $InheritHandle, $ProcessId);
$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($hProcess -eq 0)
{
Write-Host -BackgroundColor Black -ForegroundColor Red "Failed to open Win32 process. Error: $(([ComponentModel.Win32Exception] $LastError).Message)"
pause
$OverallResult = 2
exit $OverallResult
}
Write-Host -ForegroundColor Green ("Successfully got handle - {0}" -f $hProcess)
$memInfo = New-Object SysWin32.PROCESS_INFORMATION
$memInfo.Information = $MemoryPriority
$memInfoSize = [System.Runtime.Interopservices.Marshal]::SizeOf($memInfo)
$memInfoPtr = [System.Runtime.Interopservices.Marshal]::AllocHGlobal($memInfoSize)
[System.Runtime.Interopservices.Marshal]::StructureToPtr($memInfo, $memInfoPtr, $false)
$result = [SysWin32.NativeMethods]::SetProcessInformation($hProcess, [SysWin32.PROCESS_INFORMATION_CLASS]::ProcessMemoryPriority, $memInfoPtr, $memInfoSize)
$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
if (!$result)
{
$OverallResult = 3
Write-Host -BackgroundColor Black -ForegroundColor Red ("Failed to set memory piority on {0} ({1}) to be {2}. Error: {3}" -f $ProcessName, $ProcessId, $MemoryPriority, ([ComponentModel.Win32Exception]$LastError).Message)
}
else
{
Write-Host -ForegroundColor Green ("Set memory piority on {0} ({1}) to be {2}." -f $ProcessName, $ProcessId, $MemoryPriority)
}
$ioInfo = New-Object SysWin32.PROCESS_INFORMATION
$ioInfo.Information = $IoPriority
$ioInfoSize = [System.Runtime.Interopservices.Marshal]::SizeOf($ioInfo)
$ioInfoPtr = [System.Runtime.Interopservices.Marshal]::AllocHGlobal($ioInfoSize)
[System.Runtime.Interopservices.Marshal]::StructureToPtr($ioInfo, $ioInfoPtr, $false)
$result = [SysWinNT.NativeMethods]::NtSetInformationProcess($hProcess, [SysWinNT.PROCESS_INFORMATION_CLASS]::ProcessIoPriority, $ioInfoPtr, $ioInfoSize)
$LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
if ($result -ne 0)
{
$OverallResult = 4
Write-Host -BackgroundColor Black -ForegroundColor Red ("Failed to set IO piority on {0} ({1}) to be {2}. Result: {3}. Error: {4}" -f $ProcessName, $ProcessId, $IoPriority, $result, ([ComponentModel.Win32Exception]$LastError).Message)
}
else
{
Write-Host -ForegroundColor Green ("Set IO piority on {0} ({1}) to be {2}" -f $ProcessName, $ProcessId, $IoPriority)
}
[void][WSG.Utils.PermissionsSetter]::RemovePrivilege([WSG.Utils.PermissionsSetter]::SE_INC_BASE_PRIORITY_NAME)
[void][WSG.Utils.PermissionsSetter]::RemovePrivilege([WSG.Utils.PermissionsSetter]::SE_DEBUG_NAME)
exit $OverallResult
Upvotes: 3
Reputation: 67
Here's a PowerShell one-liner for reducing a process priority:
(get-process msosync).PriorityClass='BelowNormal'
In this PowerShell context, the valid values of PriorityClass can be one of: Normal, Idle, High, RealTime, BelowNormal, AboveNormal
You can test the results with this one-liner:
get-process msosync | Select-Object Name,PriorityClass,CPU | Format-Table -AutoSize
Upvotes: 0
Reputation: 780
It is not clear to me whether the IO priority can be set. The SetProcessInformation() call takes a PROCESS_INFORMATION_CLASS as an argument and that only defines ProcessMemoryPriority. I was having problems with a powershell script getting run out of task manager with a memory priority of 2 which was killing me. I am new to the PInvoke stuff and using it from PowerShell so I've probably violated at least one best practice, but the snippet below solved my problem.
The Add-Type stuff to load the functions via C#:
Add-Type @"
using System;
using System.Runtime.InteropServices;
namespace SysWin32
{
public enum PROCESS_INFORMATION_CLASS
{
ProcessMemoryPriority,
ProcessInformationClassMax,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct MEMORY_PRIORITY_INFORMATION
{
public uint MemoryPriority;
}
public partial class NativeMethods {
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="GetCurrentProcess")]
public static extern System.IntPtr GetCurrentProcess();
[System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint="SetProcessInformation")]
public static extern bool SetProcessInformation(System.IntPtr hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, System.IntPtr ProcessInformation, uint ProcessInformationSize) ;
}
}
"@
And here is the example using the functions:
$myProcessHandle = [SysWin32.NativeMethods]::GetCurrentProcess()
$memInfo = New-Object SysWin32.MEMORY_PRIORITY_INFORMATION
$memInfo.MemoryPriority = 5
$memInfoSize = [System.Runtime.Interopservices.Marshal]::SizeOf($memInfo)
$memInfoPtr = [System.Runtime.Interopservices.Marshal]::AllocHGlobal($memInfoSize)
[System.Runtime.Interopservices.Marshal]::StructureToPtr($memInfo, $memInfoPtr, $false)
$result = [SysWin32.NativeMethods]::SetProcessInformation($myProcessHandle, [SysWin32.PROCESS_INFORMATION_CLASS]::ProcessMemoryPriority, $memInfoPtr, $memInfoSize)
$result
Using procexp I was able to verify that my powershell script is now running with a memory priority of 5.
Upvotes: 4