PowerShell脚本无法获取CPU和内存使用率问题求助
问题分析与解决方案
原脚本核心问题
- Get-Service无CPU/内存属性:
Get-Service返回的服务对象不包含CPU和WorkingSet字段,直接调用会返回空值,这是CPU、内存数据不输出的根本原因。 - 变量名拼写错误:脚本中定义的
mem_usge与后续使用的mem_usage不一致,导致内存字段始终为空。 - 低效查询:循环内重复调用
Get-WmiObject获取服务描述,性能极差。
修正后的脚本
要获取服务的CPU和内存占用,必须关联服务对应的进程(服务本身不直接占用资源,资源由其启动的进程消耗)。以下是可直接运行的脚本:
# 一次性获取所有服务的基础信息(含进程ID、描述) $allServices = Get-CimInstance Win32_Service | Select-Object Name, DisplayName, Description, ProcessId # 获取实时CPU使用率计数器数据(需除以核心数得到正确百分比) $cpuCounters = Get-Counter "\Process(*)\% Processor Time" -ErrorAction SilentlyContinue $cpuData = $cpuCounters.CounterSamples | Select-Object InstanceName, @{Name='CPUUsage'; Expression={[Math]::Round($_.CookedValue / $env:NUMBER_OF_PROCESSORS, 2)}} # 获取所有进程的内存使用情况(转换为MB) $processes = Get-Process | Select-Object Id, Name, @{Name='MemoryUsageMB'; Expression={[Math]::Round($_.WorkingSet / 1MB, 2)}} # 关联服务、进程与资源数据 $serviceStats = foreach ($service in $allServices) { # 跳过无进程的系统服务(ProcessId为0) if ($service.ProcessId -eq 0) { continue } $targetProcess = $processes | Where-Object Id -eq $service.ProcessId if (-not $targetProcess) { continue } # 匹配进程对应的CPU使用率 $cpuUsage = $cpuData | Where-Object InstanceName -eq $targetProcess.Name | Select-Object -ExpandProperty CPUUsage -ErrorAction SilentlyContinue $cpuUsage = $cpuUsage ?? 0 [PSCustomObject]@{ "Service Name" = $service.Name "Display Name" = $service.DisplayName "CPU Usage (%)" = $cpuUsage "Memory Usage (MB)" = $targetProcess.MemoryUsageMB "Description" = $service.Description } } # 按CPU使用率降序排序,取前5并导出CSV $serviceStats | Sort-Object "CPU Usage (%)" -Descending | Select-Object -First 5 | Export-Csv -Path "ServiceReport.csv" -NoTypeInformation -Encoding UTF8
Get-Counter报错修复
若运行Get-Counter时提示“计数器路径无效”或“找不到指定计数器”,大概率是系统性能计数器损坏,执行以下命令修复:
lodctr /R
该命令会重新加载系统性能计数器库,修复损坏的计数器定义。
内容的提问来源于stack exchange,提问作者Cyber_Student
相关产品推荐
相关产品推荐

