使用Get-Counter的PowerShell脚本无法完整返回进程CPU占用信息
进程CPU统计不准确、进程遗漏问题分析与解决
第一个脚本的问题解析
1. CPU使用率计算错误
Get-Counter返回的\Process(*)\% Processor Time计数器中,CookedValue代表该进程在所有逻辑处理器上的CPU使用率总和(比如4逻辑核机器,单进程占满1核时,该值为100)。你的计算式多做了一次除以100的操作,导致结果被缩小100倍——正确的实时CPU使用率应该是CookedValue / 逻辑处理器总数,再转成百分比就和任务管理器显示一致。
2. MsMpEng进程遗漏原因
- 权限不足:读取系统进程的性能计数器需要管理员权限,普通权限下无法获取MsMpEng这类系统进程的CPU数据。
- 瞬时采样偏差:默认单次采样可能刚好错过MsMpEng的高负载时段,导致其未进入前10结果。
- 正则过滤逻辑无问题,MsMpEng的实例名不会被
^(idle|_total|system)$匹配过滤。
第二个脚本的问题解析
1. 核心逻辑错误:用累计CPU时间替代实时使用率
Get-Process的CPU属性是进程从启动到当前的累计CPU运行秒数,你基于此计算出的是进程生命周期内的平均使用率,而非任务管理器显示的短周期实时使用率。高负载应用如果刚启动,累计CPU时间较短,排序时会被累计时间长的进程压制,无法进入前10。
2. 进程遗漏原因
- 权限限制:
Get-Process -IncludeUserName需要管理员权限才能获取系统进程(如MsMpEng)的用户名信息,普通权限下这类进程会被跳过或无法返回完整数据。 - 排序维度错误:按累计CPU时间排序,而非实时使用率,导致刚启动的高负载进程无法被选中。
修正后的可行方案
方案1:优化第一个脚本的计算与采样逻辑
# 获取总逻辑处理器数(适配多CPU场景) $totalLogicalCores = (Get-CimInstance Win32_Processor).NumberOfLogicalProcessors | Measure-Object -Sum | Select-Object -ExpandProperty Sum # 采样2次、间隔2秒取平均,提升结果准确性 Get-Counter -ErrorAction SilentlyContinue '\Process(*)\% Processor Time' -SampleInterval 2 -MaxSamples 2 | Select-Object -ExpandProperty countersamples | Group-Object InstanceName | Select-Object @{Name='进程名';Expression={$_.Name}}, @{Name='平均CPU总和';Expression={($_.Group.CookedValue | Measure-Object -Average).Average}} | Where-Object {$_.进程名 -notmatch "^(idle|_total|system)$"} | Sort-Object -Property '平均CPU总和' -Descending | Select-Object -First 10 | Format-Table 进程名,@{Label='CPU使用率';Expression={($_.平均CPU总和 / $totalLogicalCores).ToString('P')}} -AutoSize
- 改进点:多次采样取平均减少瞬时偏差,修正CPU使用率计算逻辑,适配多CPU机器的逻辑核心统计。
方案2:使用CIM实例获取实时CPU使用率(推荐)
$totalLogicalCores = (Get-CimInstance Win32_Processor).NumberOfLogicalProcessors | Measure-Object -Sum | Select-Object -ExpandProperty Sum Get-CimInstance Win32_PerfFormattedData_PerfProc_Process | Where-Object {$_.Name -notmatch "^(idle|_total|system)$"} | Sort-Object -Property PercentProcessorTime -Descending | Select-Object -First 10 | Format-Table Name, @{Label='CPU使用率';Expression={($_.PercentProcessorTime / $totalLogicalCores).ToString('P')}} -AutoSize
- 优势:
Win32_PerfFormattedData_PerfProc_Process直接返回格式化后的实时CPU使用率数据,无需额外计算;权限足够时可获取所有进程(包括MsMpEng)的准确数据。
内容的提问来源于stack exchange,提问作者user736893
相关产品推荐
相关产品推荐

