Kill a process if it reaches x% of CPU usage
我想停止正在运行的CPU使用率超过14%的进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | $process = get-process foreach ($proc in (Get-WmiObject Win32_Processor)){ if($proc.numberofcores -eq $null){ $cores++ }else{ $cores = $cores + $proc.numberofcores } } foreach($name in $process){ $processName = $name.processName foreach($hog in $processName){ $cpuusage = [Math]::round(((((Get-Counter"\\Process($processName)\\% Processor Time" -MaxSamples 2).Countersamples)[0].CookedValue)/$cores),2) if($cpuusage -gt 14){ Stop-Process -Name $processName } } } |
我收到以下错误消息,仅此而已。我希望
Stop-Process : Cannot stop process"Idle (0)" because of the following
error: Access is denied
At line:14 char:17
+ Stop-Process -Name $processName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (System.Diagnostics.Process
(Idle):Process) [Stop-Process], ProcessCommandException
+ FullyQualifiedErrorId :
CouldNotStopProcess,Microsoft.PowerShell.Commands.StopProcessCommand
我试图在第二个foreach循环中将
在阅读@JosefZ答案后,我得到了满足我课程要求的内容。在此处发布以供参考;
1 2 3 4 5 6 7 8 9 10 11 12 | $process = get-process foreach ($pro in $process){ $name = $pro.ProcessName $CpuCores = (Get-WmiObject -Class Win32_Processor).NumberOfCores $CpuValue = ((Get-Counter"\\Process($name)\\% Processor Time").CounterSamples.CookedValue)/$CpuCores $percent = [Decimal]::Round($CpuValue, 3) if($percent -ge 15){ Stop-Process -Name $name $wshell = New-Object -ComObject Wscript.Shell $wshell.Popup("Process $name was using more than $percent % CPU. We have eliminated it.",0,"Ok",0x1) } } |
请注意,性能计数器通常受访问控制列表(ACL)的保护。要获取所有可用的性能计数器,请使用"以管理员身份运行"选项打开Windows PowerShell,并且您停止进程的能力取决于您的权限。
以下脚本用于耗时CPU
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | Set-StrictMode -Version latest $process = get-process $cores = 0 foreach ($proc in (Get-WmiObject Win32_Processor)){ if($proc.numberofcores -eq $null){ $cores++ }else{ $cores = $cores + $proc.numberofcores } } ### $cores foreach($name in $process){ $processName = $name.processName if ( $processName -notmatch"^Idle" ) { foreach($hog in $processName){ $cpuusage = -1 $cpuusage = [Math]::round(((((Get-Counter"\\Process($processName)\\% Processor Time" -MaxSamples 2).Countersamples)[0].CookedValue)/$cores),2) if ($cpuusage -gt 14) { Stop-Process -Name $processName -PassThru -ErrorAction Continue ###"{0} {1} {2} {3}" -f '+', $cpuusage, $name.Id, $processName } else { if($cpuusage -ne 0){ ###"{0} {1} {2} {3}" -f '-', $cpuusage, $name.Id, $processName } } } } } |
脏溶液:
"空闲"表示"无效"(未运行或未使用)。当"系统空闲进程"位于
在MSDN上读取停止进程(
Windows PowerShell gives you flexibility for listing processes, but
what about stopping a process?The
Stop-Process cmdlet takes aName orId to specify a process
you want to stop. Your ability to stop processes depends on your
permissions. Some processes cannot be stopped. For example, if you
try to stop the idle process, you get an error:
1
2
3
4
5 PS> Stop-Process -Name Idle
Stop-Process : Process 'Idle (0)' cannot be stopped due to the following error:
Access is denied
At line:1 char:13
+ Stop-Process <<<< -Name Idle
阅读
Outputs
None,
System.Diagnostics.Process This cmdlet returns a
System.Diagnostics.Process object that represents the stopped process, if you specify thePassThru
parameter. Otherwise, this cmdlet does not generate any output.
为您提供其他指针的夫妇。首先,您应该使用
1 2 3 4 | C:\\WINDOWS\\system32> (Get-WmiObject win32_processor).NumberofCores 6 C:\\WINDOWS\\system32> (Get-WmiObject win32_computersystem).Numberoflogicalprocessors 12 |
第二,您应该使用ID而不是名称来停止该进程,因为这将导致意想不到的后果。一个简单的示例是Chrome,每个选项卡都有一个进程,所有这些进程的名称都为Chrome。因此,单个选项卡可能会出现导致CPU占用率较高的问题,但是您调用
以下示例脚本解决了这两个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #Get all cores, which includes virtual cores from hyperthreading $cores = (Get-WmiObject Win32_ComputerSystem).NumberOfLogicalProcessors #Get all process with there ID's, excluding processes you can't stop. $processes = ((Get-Counter"\\Process(*)\\ID Process").CounterSamples).where({$_.InstanceName -notin"idle","_total","system"}) #Get cpu time for all processes $cputime = $processes.Path.Replace("id process","% Processor Time") | get-counter | select -ExpandProperty CounterSamples #Get the processes with above 14% utilisation. $highUsage = $cputime.where({[Math]::round($_.CookedValue / $cores,2) -gt 14}) # For each high usage process, grab it's process ID from the processes list, by matching on the relevant part of the path $highUsage |%{ $path = $_.Path $id = $processes.where({$_.Path -like"*$($path.Split('(')[1].Split(')')[0])*"}) | select -ExpandProperty CookedValue Stop-Process -Id $id -Force -ErrorAction SilentlyContinue } |
请注意,使用