Retrieving CPU details in Powershell - powershell

I am planning to extract the CPU details to my powershell requirement. Below is the highlighted parameter that I am trying to extract.
I have tried using Get-WmiObject Win32_Process or Get-Process but no luck with it. Can you guide with the cmdlet which can be helpful for this
Updated Question
Get-Counter '\Process(*)\% Processor Time' |
Select-Object -ExpandProperty countersamples |
Select-Object -Property instancename, cookedvalue|
Sort-Object -Property cookedvalue -Descending |
Select-Object| ft InstanceName,#{L='CPU';E={($_.Cookedvalue/100).toString('P')}} -AutoSize
I am using this code as suggested in the below comments. and below is the output which I am receiving.
However if you compare the value for PS output and the task manager screenshot, its quite different, since in task manager most of them are 0
Updated Part 2
I have extracted this code from another post.
$NumberOfLogicalProcessors=(Get-WmiObject -class Win32_processor | Measure-Object -Sum NumberOfLogicalProcessors).Sum
(Get-Counter '\Process(*)\% Processor Time').Countersamples | Sort cookedvalue -Desc | ft -a instancename, #{Name='CPU %';Expr={[Math]::Round($_.CookedValue / $NumberOfLogicalProcessors)}}
This may be working, but I would like to get your opinions on these since the value for this is dynamic and pretty difficult to verify

try this:
$Utilization = #()
Get-WmiObject Win32_PerfFormattedData_PerfProc_Process | Sort-Object -Property PercentProcessorTime -descending | ? { $_.name -inotmatch '_total|idle' } | % {$Utilization += [PSCustomObject]#{'Process Name' = $_.Name; 'pid' = $_.IDProcess; 'Usage' = $_.PercentProcessorTime}}

Related

Powershell script to list running processes and CPU utilization using Get-Counter is not returning all processes

I found the following PS command to list running processes sorted by CPU utilization:
Get-Counter -ErrorAction SilentlyContinue '\Process(*)\% Processor Time' |
Select-Object -ExpandProperty countersamples |
Select-Object -Property instancename, cookedvalue |
? {$_.instanceName -notmatch "^(idle|_total|system)$"} |
Sort-Object -Property cookedvalue -Descending |
Select-Object -First 10 |
ft InstanceName,#{L='CPU';E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}} -AutoSize
Below is the output, which appears it could be accurate, however while this ran my Antimalware Service Executable was using about 8% CPU. Why is this not showing up in the PowerShell output?
InstanceName CPU
------------ ---
msmpeng 0.39%
slack 0.19%
taskmgr 0.19%
pwsh 0.10%
todo 0.10%
dwm 0.10%
system 0.00%
creative cloud helper 0.00%
adobe desktop service 0.00%
adobeipcbroker 0.00%
Edit: The answer here gives similar results. Here is my adaptation of the answer (so it outputs it to a table instead of CSV)
$Cores = (Get-WmiObject -class win32_processor -Property numberOfCores).numberOfCores;
$LogicalProcessors = (Get-WmiObject –class Win32_processor -Property NumberOfLogicalProcessors).NumberOfLogicalProcessors;
$TotalMemory = (get-ciminstance -class "cim_physicalmemory" | % {$_.Capacity})
get-process -IncludeUserName | select #{Name="Time"; Expression={(get-date(get-date).ToUniversalTime() -uformat "%s")}},`
ID, StartTime, Handles,WorkingSet, PeakPagedMemorySize, PrivateMemorySize, VirtualMemorySize,`
#{Name="Total_RAM"; Expression={ ($TotalMemory )}},`
CPU,
#{Name='CPU_Usage'; Expression = { $TotalSec = (New-TimeSpan -Start $_.StartTime).TotalSeconds
[Math]::Round( ($_.CPU * 100 / $TotalSec) /$LogicalProcessors, 2) }},`
#{Name="Cores"; Expression={ ($Cores )}},`
#{Name="Logical_Cores"; Expression={ ($LogicalProcessors )}},`
UserName, ProcessName, Path | Sort-Object -Property CPU -Descending | Format-Table -Property ProcessName, CPU | Select -First 10
And here are the results:
ProcessName CPU
----------- ---
SearchIndexer 2898.21875
MsMpEng 1395.9375
System 1045
MsSense 612.359375
explorer 507.296875
OneDrive 467.296875
OUTLOOK 362.765625
SenseNdr 355.8125
After some tests, these results are actually worse. I ran a CPU intensive App and it shows up with the first (original) method, but it shows 1.5% even though Task Manager shows 25%. The second method, from the other SO answer, does not show the process at all.

Top 5 Processes with CPU % and Process ID using Powershell

I tried this script
Get-Counter -ErrorAction SilentlyContinue '\Process(*)\% Processor Time' |
Select -ExpandProperty countersamples |
?{$_.instanceName -notmatch "^(idle|_total|system)$"} |
Sort -Descending cookedvalue |
Select -First 5 #{
L='ProcessName';
E={[regex]::matches($_.Path,'.*process\((.*)\)\\% processor.*').groups[1].value}
},
#{
L='CPU';
E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}
},
#{
L='ProcessId';
E={((Get-Counter "\Process([regex]::matches($_.Path,'.*process\((.*)\)\\% processor.*').groups[1].value)\ID Process" -ErrorAction SilentlyContinue).CounterSamples).Cookedvalue}
}
I am able to get ProcessName and CPU % columns but not ProcessID
ProcessName CPU ProcessId
----------- --- ---------
firefox#4 0.58%
svchost#11 0.19%
firefox#6 0.19%
dwm 0.10%
svchost#39 0.10%
Make sure you request both the % Processor Time and ID Process counter from each counter instance, then use Group-Object to group them together.
Worth noting is that you don't need regex to correlate the two, simply group on the first part of the counter path (\Process(notepad#3)). Regex is also not needed for extracting the process name, since each sample already has an InstanceName property with the corresponding process name.
Once you've correlated name + process ID + sample value, you can start sorting, and then finally format the CPU percentage:
Get-Counter '\Process(*)\ID Process','\Process(*)\% Processor Time' -ErrorAction SilentlyContinue |
ForEach-Object {
$_.CounterSamples |
Where-Object InstanceName -NotMatch '^(?:idle|_total|system)$' |
Group-Object {Split-Path $_.Path} |
ForEach-Object {
[pscustomobject]#{
ProcessName = $_.Group[0].InstanceName
ProcessId = $_.Group |? Path -like '*\ID Process' |% RawValue
CPUCooked = $_.Group |? Path -like '*\% Processor Time' |% CookedValue
}
} |Sort-Object CPUCooked -Descending |
Select-Object -First 5 -Property *,#{Name='CPUPercentage';Expression={'{0:P}' -f ($_.CPUCooked / 100 / $env:NUMBER_OF_PROCESSORS)}} -ExcludeProperty CPUCooked
}

-Property time / Not showing time. PowerShell

I have a quick question about powershell. If I write $event1 = Get-EventLog system | Where-Object {$_.EventID -eq 6006} | Select-Object -first 1 -Property Index it only displays the index. Which is right... But if I write $event1 = Get-EventLog system | Where-Object {$_.EventID -eq 6006} | Select-Object -first 1 -Property Time The time is not showing up... Just a blank row. What am I doing wrong. I fond nothing on the internet about that probem. So maybe you could help me. I am a beginner btw :)
As commented, there is no property called Time. Use TimeGenerated or TimeWritten instead.
$event1 = Get-EventLog System | Where-Object {$_.EventID -eq 6006} | Select-Object -First 1 -Property TimeGenerated
However, the docs say that
"Get-EventLog uses a Win32 API that is deprecated. The results may not be accurate. Use the Get-WinEvent cmdlet instead."
To change to Get-WinEvent the following gets you what you want:
$event1 = Get-WinEvent -LogName System | Where-Object {$_.Id -eq 6006} | Select-Object -First 1 -Property TimeCreated

How to execute several cmdlets in powershell script?

I have written this script to get some information about my Virtual Machine. When I execute this script the last two cmdlets (lines) don't execute, but when I execute them alone they run properly.
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, SystemName,
#{n='Size (GB)'; e={$_.Size / 1GB -as [int]}},
#{n='Freespace (GB)'; e={$_.Freespace / 1GB -as [int]}};
$TotalMemory = (Get-CimInstance Win32_OperatingSystem).TotalVisibleMemorySize / (1024*1024)
$UsedMemory = (Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / (1024*1024)
$TotalMemory = [math]::Round($TotalMemory,2)
$UsedMemory = [math]::Round($UsedMemory,2)
$TotalMemory
$UsedMemory
Get-CimInstance Win32_Processor | Select-Object -Property NumberOfCores;
Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | Select-Object Sum;
What is the problem?
Any comments would be appreciated.
This question has been asked a million times. Format-table is being implicitly run, and it doesn't handle different sets of columns well. All the objects are there. You can pipe the whole script to format-list. You can put get-date at the very beginning. A known object with a format file at the beginning fixes it. You can output more than 4 properties with the first object. I tried to ask for a warning to be added a while ago: format-table should at least warn when it doesn't display properties #7871
Looks like out-gridview has similar struggles: Not all properties displayed
This appears to be one of PowerShell's weird quirks. I am not sure why it happens, but if someone else does I will happily edit my answer to include it.
You will need to specifically tell it to write the output to the console. There are a couple ways of doing this.
The first, and probably messiest, would be to pass it as a parameter to Write-Host or Write-Output.
Write-Host (Get-CimInstance Win32_Processor | Select-Object -Property NumberOfCores)
Write-Host (Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | Select-Object Sum)
(Another way of doing this would be to assign them both to variables, and pass the variables to the cmdlet)
The second way would be to pipe it to Write-Host or Write-Output
Get-CimInstance Win32_Processor | Select-Object -Property NumberOfCores | Write-Host
Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | Select-Object Sum | Write-Host
And finally, the third (and in my opinion cleanest) way would be to pipe it to a code block that references the property directly
Get-CimInstance Win32_Processor | %{$_.NumberOfCores}
Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | %{$_.Sum}
Hope this helps!

How can know the usage of CPU of a windows service in an interval of time with PowerShell?

I am a beginner with PowerShell, How can know the usage of CPU of a windows service in an interval of time (for example for one hour) with PowerShell?
Something like this:
Get-Service | Get-counter
Thank so much
For CPU usage you need to use the get-process commandlet and then map the process name with the corresponding service.
Here is one of the past discussion thread where the get-process is discussed
Listing processes by CPU usage percentage in powershell
Sample code here
$Details = #()
$AllRunningServices = Get-CimInstance -class win32_service | Where-Object {$_.State -eq 'Running'} | Select-Object ProcessId , Name
foreach($procid in $AllRunningServices)
{
$Details += Get-Process | Where-Object {$_.Id -eq $procid.ProcessId} | Select-Object ProcessName, Id, CPU , #{Name = "serviceName" ; Expression={$procid.Name}}
}
$Details |Sort-Object -Property CPU -Descending | ft