Continuously monitors the CPU usage % of top X processes
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%
- 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.
- 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 availableFileDescription
property stores that value. If it's not available then non-friendly process name is used.
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 Securitychrome 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
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} }}