获取CPU占用率超阈值的进程名称及脚本问题排查
解决PowerShell高CPU进程检测脚本的问题
我来帮你搞定这个脚本的问题,你的代码主要有逻辑判断错误和效率低下两个核心问题,咱们一步步修正,同时帮你实现把进程名传给短信函数的功能:
先说说你原来脚本的问题
- 逻辑判断错误:你现在是遍历每个进程,只要当前进程的CPU没超过阈值,就输出「没有进程超过1%」——这显然不对,哪怕有10个高CPU进程,只要有一个进程没达标,就会触发这个错误提示。正确的逻辑应该是:先收集所有超过阈值的进程,最后判断这个集合是否为空,再决定输出什么。
- 重复调用系统接口:每次循环都调用
Get-WmiObject获取CPU核心数,这完全是重复劳动,只需要在脚本开头获取一次就行。 - 逐个获取计数器效率低:每次循环调用
Get-Counter去查单个进程的CPU使用率,不仅慢,还可能因为采样时间差导致数据不准确,应该一次性获取所有进程的计数器数据。
修正后的完整脚本
function Get-HighCpuProcess { # 一次性获取CPU核心数,避免重复调用系统接口 $cpuCores = (Get-WmiObject -Class Win32_Processor).NumberOfCores # 一次性获取所有进程的CPU使用率计数器,忽略不存在的进程计数器 $processCounters = Get-Counter "\Process(*)\% Processor Time" -ErrorAction SilentlyContinue # 收集所有超过阈值的进程(这里先保留1%做测试,你可以改成70%) $highCpuProcesses = foreach ($counter in $processCounters.CounterSamples) { # 处理计数器实例名,比如把"chrome#1"转换成"chrome" $processName = $counter.InstanceName -replace '^(.+?)(#\d+)?$', '$1' # 计算实际CPU占用率(计数器返回的是总核心的使用率,所以要除以核心数) $cpuUsage = [Decimal]::Round($counter.CookedValue / $cpuCores, 3) # 判断是否超过设定的阈值 if ($cpuUsage -gt 1) { # 用自定义对象存储进程名和使用率,方便后续处理 [PSCustomObject]@{ ProcessName = $processName CpuUsage = $cpuUsage } } } # 根据收集到的结果处理 if ($highCpuProcesses) { Write-Host "检测到高CPU占用进程:" $highCpuProcesses | Format-Table -AutoSize # 这里对接你的短信发送功能 $serverName = $env:COMPUTERNAME # 获取当前服务器名称 # 把所有高CPU进程名拼接成字符串,用逗号分隔 $processList = $highCpuProcesses.ProcessName -join ", " # 假设你的短信发送函数是Send-SMS,把参数传进去就行 # 示例:Send-SMS -Recipient "你的指定接收人" -Message "服务器 $serverName 检测到高CPU占用进程:$processList" } else { Write-Host "没有进程CPU占用率超过1%" } } # 调用函数执行检测 Get-HighCpuProcess
关键说明
- 阈值修改:把脚本里的
$cpuUsage -gt 1改成$cpuUsage -gt 70,就符合你70%的检测要求了。 - 短信函数对接:我已经帮你把服务器名(通过
$env:COMPUTERNAME自动获取)和进程列表拼接好了,直接替换成你实际的短信发送函数调用即可。 - 效率优化:一次性获取所有计数器和CPU核心数,比原来的循环调用快很多,也更稳定,适合在服务器负载高的时候运行。
内容的提问来源于stack exchange,提问作者Malin
相关产品推荐
相关产品推荐

