Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Continuously monitors the CPU usage % of top X processes

I want to be able to to output to a log file the top CPU consumers every 5 seconds. That way I will be able to see who uses the most of the cpu during my tests.

I have found this answer very common:

$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

I have 2 issues with it:

  1. Sometimes I get:

    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. I would like to get the full process name, and not

    java      25%
    idea64    0.8%
    ...
like image 548
Alex Portnoy Avatar asked Jul 24 '16 11:07

Alex Portnoy


2 Answers

I'll try to answer your two questions at once with following script:

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

This results in following 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. As specified, you sometimes get:

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.

This is related to process management in windows environment. While you execute query, some processes may appear, some of them may disappear (i.e. wmiprvse process responsible for executing wmi queries). Some processes may require more permissions you have. This all leads to error when obtaining process information. It can be safely skipped using -ErrorAction SilentlyContinue switch and filtered with Status -eq 0 expression.

  1. You also want to see more friendly process name. I don't know if there is better way of getting that name than from executable itself using GetVersionInfo method. If such information is available FileDescription property stores that value. If it's not available then non-friendly process name is used.
like image 63
Paweł Dyl Avatar answered Oct 16 '22 08:10

Paweł Dyl


you get output something like this

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                                                                  

With

$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

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

Get-Process -ComputerName $env:computername for remote computers you can have in 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}
 }}
like image 24
DisplayName Avatar answered Oct 16 '22 07:10

DisplayName