PowerShell 4.0下svchost.exe CPU占用超100%问题求助
问题根源分析
你的脚本出现CPU使用率超过100%的问题,主要有两个原因:
- 错误使用累计CPU时间:
TotalProcessorTime是进程从启动到当前的累计CPU占用时间,并非实时使用率。直接用这个值计算会导致结果异常,尤其是运行时间较短的进程。 - 逻辑核心数计算错误:每次循环调用
Get-WmiObject Win32_Processor,如果系统有多个物理CPU,会返回多个处理器实例,导致NumberOfLogicalProcessors变成数组,计算逻辑失效;同时重复调用也降低了脚本效率。
兼容PowerShell 4.0的修正脚本
# 获取总逻辑核心数(兼容多物理CPU场景) $totalLogicalProcessors = (Get-WmiObject -Class Win32_Processor | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum # 第一次采样:记录进程初始CPU时间、内存等信息 $firstSample = Get-Process -Name svchost | Select-Object Id, ProcessName, Path, WorkingSet, @{Name='CpuTime'; Expression={$_.TotalProcessorTime}} $startTime = Get-Date # 等待1秒采样间隔,确保能获取有效CPU时间差 Start-Sleep -Seconds 1 # 第二次采样:记录进程最新CPU时间 $secondSample = Get-Process -Name svchost | Select-Object Id, @{Name='CpuTime'; Expression={$_.TotalProcessorTime}} # 计算实时CPU使用率并整理结果 $results = foreach ($proc in $firstSample) { $secondProc = $secondSample | Where-Object { $_.Id -eq $proc.Id } # 处理采样间隔内进程退出的情况 if ($secondProc) { $cpuTimeDiff = $secondProc.CpuTime - $proc.CpuTime $sampleInterval = (Get-Date) - $startTime # 计算相对于总系统CPU的使用率(范围0-100%) $cpuUsage = [Math]::Round(($cpuTimeDiff.TotalSeconds / ($sampleInterval.TotalSeconds * $totalLogicalProcessors)) * 100, 2) $ramUsage = [Math]::Round(($proc.WorkingSet / 1MB), 2) New-Object -TypeName PSObject -Property @{ Id = $proc.Id ProcessName = $proc.ProcessName Path = $proc.Path 'CPU Usage (%)' = $cpuUsage 'RAM Usage (MB)' = $ramUsage } } } # 输出到桌面文件 $results | Format-Table -AutoSize | Out-File -FilePath "$env:userprofile\Desktop\svch_List.txt"
关键修改说明
- 总逻辑核心数计算:一次性获取所有物理CPU的逻辑核心数总和,避免循环中重复调用WMI,同时兼容多CPU场景。
- 实时采样机制:通过两次采样的CPU时间差和采样间隔计算真实的实时使用率,而非使用累计时间。
- 使用率范围控制:计算时除以
采样间隔*总逻辑核心数,得到的是进程占用总系统CPU资源的百分比,结果范围在0-100%之间,符合常规认知。 - 异常处理:增加了对采样间隔内进程退出的判断,避免脚本报错。
内容的提问来源于stack exchange,提问作者chrz997
相关产品推荐
相关产品推荐

