如何修改PowerShell脚本仅获取Windows服务的CPU使用率
修正PowerShell脚本以仅获取Windows服务的CPU使用率
原脚本的核心问题是未将性能计数器对应的进程与Windows服务做精准关联,导致无法过滤非服务进程。以下是修正后的脚本,会先收集所有运行中服务的进程ID及相关信息,再筛选出仅属于服务的进程CPU数据:
# 预获取所有运行中的Windows服务及其关联进程ID,避免重复查询 $runningServices = Get-CimInstance Win32_Service -Filter "State='Running'" | Where-Object { $_.ProcessId -ne 0 } | Select-Object ProcessId, DisplayName, Name # 获取服务进程ID的集合,用于快速判断 $serviceProcessIds = $runningServices.ProcessId | Select-Object -Unique Get-Counter "\\Process(*)\\% Processor Time" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty CounterSamples | Where-Object { $_.Status -eq 0 -and $_.InstanceName -notin "_total", "idle" -and # 匹配当前进程实例对应的进程ID,判断是否属于服务进程 ($proc = Get-Process -Name $_.InstanceName -ErrorAction SilentlyContinue) -and $proc.Id -in $serviceProcessIds } | Sort-Object CookedValue -Descending | Select-Object -First 10 @{ Name = "服务名称" Expression = { # 优先使用服务的显示名称,其次用文件描述,最后用进程名 $currentProcId = (Get-Process -Name $_.InstanceName -ErrorAction SilentlyContinue).Id $service = $runningServices | Where-Object { $_.ProcessId -eq $currentProcId } if ($service) { $service.DisplayName } else { try { $procPath = (Get-CimInstance Win32_Process -Filter "ProcessId=$currentProcId").ExecutablePath [System.Diagnostics.FileVersionInfo]::GetVersionInfo($procPath).FileDescription } catch { $_.InstanceName } } } }, @{ Name = "CPU使用率" Expression = { ($_.CookedValue / 100 / $env:NUMBER_OF_PROCESSORS).ToString("P") } } | Format-Table -AutoSize
关键修正点:
- 预查询服务信息:提前获取所有运行中服务的进程ID和显示名称,避免在循环中重复调用WMI/CIM,提升脚本执行效率。
- 精准进程关联:针对每个性能计数器的进程实例,通过
Get-Process获取其真实ID,判断是否存在于服务进程ID集合中,彻底过滤非服务进程。 - 友好名称优化:优先显示服务的官方显示名称(而非进程名),让输出更易读。
输出示例(仅包含服务进程):
服务名称 CPU使用率 ----------- ---------- NinjaRMMAgent Service 7.29% Microsoft Defender Antivirus Service 1.92% ...
内容的提问来源于stack exchange,提问作者overflowed
相关产品推荐
相关产品推荐

