小ネタです。
ある場面において、プロセスの優先順位*1 を変更する機会があります。そんな時、良く紹介されているのは、 タスクマネージャーからの優先度の変更ですね。

しかし、長時間のプロセス、かつ処理ごとにプロセスが立ち上がり直す場合には、やってられません。ということで、PowerShellで変更する方法を見てみましょう。
プロセスの取得
まずは、プロセスを取得してみましょう。
Get-Process*2で見てみましょう。
PS> Get-Process -Name powershell | select * # 省略 PriorityClass : Normal
PriorityClass を設定する
単純に、タスクマネージャーで表示される優先度をセットすればokです。
$ps = Get-Process -Name powershell $ps.PriorityClass = "High"
これで、優先度が変更されます。

PriorityClassはNoteProperty担っています。
PS> Get-Process -Name powershell | select PriorityClass | Get-Member TypeName: Selected.System.Diagnostics.Process Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() PriorityClass NoteProperty System.Diagnostics.ProcessPriorityClass PriorityClass=Normal
ご存知の通り、[System.Diagnostics.ProcessPriorityClass]はEnumです。
PS [System.Diagnostics.ProcessPriorityClass] IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True ProcessPriorityClass System.Enum
設定可能な定義を確認できます。
PS> [Enum]::GetNames([System.Diagnostics.ProcessPriorityClass]) Normal Idle High RealTime BelowNormal AboveNormal
ここまでわかっていれば、さくっとファンクションにします。
コード
GitHubにおいておきます。
全文です。
function Set-ProcessPriorityClass { [CmdletBinding()] param ( [parameter( mandatory, position = 0, valueFromPipeline, valueFromPipelineByPropertyName)] [string[]] $Name, [parameter( mandatory = 0, position = 1, valueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [System.Diagnostics.ProcessPriorityClass] $Priority, [parameter( mandatory = 0, position = 2)] [switch] $WhatIf ) begin { DATA message { ConvertFrom-StringData ` " PriorityNotChange = Process Name '{0}' Priority '{1}' was already same as Priority '{2}' you set. Skip priority change. PriorityChange = Process Name '{0}' changed Priority from '{1}' to '{2}'. ProcessNotFound = Process Name '{0}' not found. Skip priority change. " } } process { foreach ($n in $Name) { try { # Get process $ps = Get-Process | where Name -eq $n # process exist check if ($null -ne $ps) { # what if check if ($PSBoundParameters.WhatIf.IsPresent) { $Host.UI.WriteLine(("What if: " + $message.PriorityChange -f $ps.Name, $ps.PriorityClass, $Priority)) } else { # process priority check if ($ps.PriorityClass -ne $Priority) { # execute Write-Verbose ($message.PriorityChange -f $ps.Name, $ps.PriorityClass, $Priority) $ps.PriorityClass = $Priority } else { # priority want to change was same as current. Write-Verbose ($message.PriorityNotChange -f $ps.Name, $ps.PriorityClass, $Priority) } } } else { # process missing Write-Warning ($message.ProcessNotFound -f $n) } } finally { # dispose item if ($ps -ne $null){$ps.Dispose()} } } } }
利用方法
いわゆるPowerShellファンクションとして利用可能です。 Nameには、複数のプロセスをまとめて指定可能です。
パラメータ指定
パラメータを指定してもいいですね。 もちろんPriorityは、インテリセンスに候補もでます。
PS> Set-ProcessPriorityClass -Name "powershell" -Priority High -Verbose VERBOSE: Process Name 'powershell' changed Priority from 'Normal' to 'High'.
パイプライン渡し
パイプラインからも渡せます。
PS> Get-Process | where Name -eq PowerShell | Set-ProcessPriorityClass -Priority Normal -Verbose VERBOSE: Process Name 'powershell' changed Priority from 'High' to 'Normal'.
スプラッティング渡し
いわゆるSplatting = HashTableに定義して渡す手法も可能です。
PS> $param = @{Name = "powershell"; Priority = "High"} PS> Set-ProcessPriorityClass @param -Verbose VERBOSE: Process Name 'powershell' changed Priority from 'Normal' to 'High'.
WhatIf
-WhatIfスイッチを付けることで、実行しないでどうなるかも事前に確認可能です。*3
PS> Get-Process | where Name -eq PowerShell | Set-ProcessPriorityClass -Priority Normal -Verbose -WhatIf What if: Process Name 'powershell' changed Priority from 'High' to 'Normal'.
まとめ
あとは好きなようにイベントを処理しましょう。