持续监控前 X 个进程的 CPU 使用百分比

Continuously monitors the CPU usage % of top X processes

我希望能够每 5 秒将前 CPU 位消费者输出到日志文件。这样我就可以看到谁在我的测试中使用了最多的 cpu。

我发现这个答案很常见:

$cpu = Get-Counter -ComputerName localhost "\Process(*)\% Processor Time" `
    | Select-Object -ExpandProperty countersamples `
    | where {$_.InstanceName -ne 'idle' } `
    | where {$_.InstanceName -ne '_total' }`
    | Select-Object -Property instancename, cookedvalue `
    | Sort-Object -Property cookedvalue -Descending `
    | Select-Object -First 5 `
    | ft @{L='Date';E={Get-Date}}, InstanceName, @{L='CPU';E={(($_.Cookedvalue/100)/$NumberOfLogicalProcessors).toString('P')}} -HideTableHeaders `
    | Format-Table -Auto | Out-String

我有 2 个问题:

  1. 有时我得到:

    Get-Counter : The data in one of the performance counter samples is not valid. View the Status property for each PerformanceCounterSample object to make sure it contains valid data.

  2. 我想获取完整的进程名称,而不是

    java      25%
    idea64    0.8%
    ...

你得到这样的输出

Name                    CPU CPUPercent Description             
----                    --- ---------- -----------             
chrome           10.4988673       8.79 Google Chrome           
powershell_ise    6.5364419       7.16 Windows PowerShell ISE  
chrome           38.0174437       4.88 Google Chrome           
chrome           26.2549683       4.87 Google Chrome           
chrome           16.9417086       3.16 Google Chrome           
cavwp            10.2648658       2.67 COMODO Internet Security
chrome           13.1820845       2.44 Google Chrome           
chrome           675.016327       2.02 Google Chrome           
7.9.7_42331    1037.1570484       1.51 BitTorrent              
chrome          340.8777851       1.02 Google Chrome                                                                  

$CPUPercent = @{
  Name = 'CPUPercent'
  Expression = {
    $TotalSec = (New-TimeSpan -Start $_.StartTime).TotalSeconds
    [Math]::Round( ($_.CPU * 100 / $TotalSec), 2)
  }
}
Get-Process -ComputerName $env:computername | 
 Select-Object -Property Name, CPU, $CPUPercent, Description |
 Sort-Object -Property CPUPercent -Descending |
 Select-Object -First 10 |format-table -autosize | out-file c:\pro.log

信用:http://powershell.com/cs/blogs/tips/archive/2013/04/16/documenting-cpu-load-for-running-processes.aspx

Get-Process -ComputerName $env:您可以在 csv 中拥有的远程计算机的计算机名

     Import-CSV c:\"computers.csv" | % { 
    $Server = $_.ServerName
    $alivetest = Test-Path "\$Server\c$\"
    If ($alivetest -eq "True")
    {Get-Process -ComputerName $server | 
 Select-Object -Property Name, CPU, $CPUPercent, Description |
 Sort-Object -Property CPUPercent -Descending |
 Select-Object -First 10 |format-table -autosize | out-file c:\pro.log}
 }}

我将尝试使用以下脚本一次回答您的两个问题:

Get-Counter "\Process(*)\% Processor Time" -ErrorAction SilentlyContinue `
  | select -ExpandProperty CounterSamples `
  | where {$_.Status -eq 0 -and $_.instancename -notin "_total", "idle"} `
  | sort CookedValue -Descending `
  | select TimeStamp,
    @{N="Name";E={
        $friendlyName = $_.InstanceName
        try {
            $procId = [System.Diagnostics.Process]::GetProcessesByName($_.InstanceName)[0].Id
            $proc = Get-WmiObject -Query "SELECT ProcessId, ExecutablePath FROM Win32_Process WHERE ProcessId=$procId"
            $procPath = ($proc | where { $_.ExecutablePath } | select -First 1).ExecutablePath
            $friendlyName = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($procPath).FileDescription
        } catch { }
        $friendlyName
    }},
    @{N="CPU";E={($_.CookedValue/100/$env:NUMBER_OF_PROCESSORS).ToString("P")}} -First 5 `
 | ft -a -HideTableHeaders

结果如下 table:

24.07.2016 21:00:53 Microsoft Edge Content Process    9,68%
24.07.2016 21:00:53 system                            0,77%
24.07.2016 21:00:53 Microsoft Edge                    0,39%
24.07.2016 21:00:53 runtimebroker                     0,39%
24.07.2016 21:00:53 Host Process for Windows Services 0,39%
  1. 按照规定,您有时会得到:

Get-Counter : The data in one of the performance counter samples is not valid. View the Status property for each PerformanceCounterSample object to make sure it contains valid data.

这与windows环境中的进程管理有关。当您执行查询时,一些进程可能会出现,其中一些可能会消失(即负责执行 wmi 查询的 wmiprvse 进程)。某些进程可能需要您拥有的更多权限。这都会导致获取进程信息时出错。可以使用 -ErrorAction SilentlyContinue 开关安全地跳过它并使用 Status -eq 0 表达式进行过滤。

  1. 您还希望看到更友好的进程名称。我不知道是否有比使用 GetVersionInfo 方法从 executable 本身获取该名称更好的方法。如果此类信息可用,FileDescription 属性 会存储该值。如果它不可用,则使用不友好的进程名称。