Querying CPU usage through PowerShell provides detailed metrics for system administrators. If you want to know how to check cpu usage using powershell, this guide will walk you through every step with clear commands and real examples.
CPU usage is a critical performance indicator. High usage can slow down servers and desktops alike. PowerShell gives you precise control over monitoring this metric without third-party tools.
You don’t need to be a scripting expert. Basic commands work fine for most tasks. Let’s start with the simplest method first.
Understanding Cpu Metrics In Powershell
Before running commands, you should know what data PowerShell can return. The main metrics include:
- Processor time percentage
- User time versus privileged time
- Idle time
- Number of logical processors
- Per-core usage breakdown
These come from Windows Management Instrumentation (WMI) or the newer CIM cmdlets. Both work in PowerShell 5.1 and PowerShell 7.
How To Check Cpu Usage Using Powershell
This is your primary method. The Get-Counter cmdlet pulls live performance data directly from the system.
Open PowerShell as Administrator. Type this command:
Get-Counter "\Processor(_Total)\% Processor Time"
You’ll see a sample output like this:
Timestamp CounterSamples
--------- --------------
3/15/2025 10:32:15 AM \processor(_total)\% processor time :
45.6789012345679
The number represents the average CPU usage over the sample interval. It refreshes every second by default.
For continuous monitoring, add the -Continuous parameter:
Get-Counter "\Processor(_Total)\% Processor Time" -Continuous
Press Ctrl+C to stop the loop. This is useful for real-time troubleshooting.
Checking Per-Core Usage
Sometimes you need to see each logical processor individually. Use this command:
Get-Counter "\Processor(*)\% Processor Time"
This returns data for every core. The output lists each instance like “0,” “1,” “2,” and so on. It helps identify uneven workload distribution.
Using Get-WmiObject For Cpu Data
An older but reliable method uses the Win32_Processor class. Run:
Get-WmiObject Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors, LoadPercentage
The LoadPercentage field shows current total CPU usage. It’s a single snapshot, not a stream.
For PowerShell 7, use the CIM version:
Get-CimInstance Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors, LoadPercentage
Monitoring Cpu Usage Over Time
Static snapshots aren’t enough for trend analysis. You need to collect data at intervals.
Create a simple loop that samples every 5 seconds:
while ($true) {
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
Write-Output "$(Get-Date -Format 'HH:mm:ss') CPU: $cpu%"
Start-Sleep -Seconds 5
}
This prints a timestamped log. You can redirect it to a file:
while ($true) {
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'),$cpu" | Out-File -FilePath C:\Logs\cpu_log.csv -Append
Start-Sleep -Seconds 10
}
Now you have a CSV file for later analysis in Excel or other tools.
Setting Up Alerts For High Cpu
You can trigger actions when CPU exceeds a threshold. This script checks every minute:
$threshold = 90
while ($true) {
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
if ($cpu -gt $threshold) {
Write-Warning "CPU at $cpu% - exceeds $threshold% threshold"
# Add email notification or log entry here
}
Start-Sleep -Seconds 60
}
Replace the Write-Warning with your preferred notification method, like Send-MailMessage.
Advanced Cpu Monitoring Techniques
PowerShell can combine CPU data with process information. This gives you granular insight into what’s consuming resources.
Identifying Top Cpu-Consuming Processes
Use Get-Process to find the heaviest processes:
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU, ID, StartTime
The CPU property shows total processor time in seconds since process start. For real-time percentage, you need a different approach.
Combine Get-Process with Get-Counter for live percentages:
$processes = Get-Process
$processes | ForEach-Object {
$proc = $_
$counter = "\Process($($proc.ProcessName))\ % Processor Time"
try {
$cpu = (Get-Counter $counter -ErrorAction Stop).CounterSamples.CookedValue
[PSCustomObject]@{
ProcessName = $proc.ProcessName
PID = $proc.Id
CPUPercent = [Math]::Round($cpu, 2)
}
} catch {
# Skip processes that don't have counters
}
} | Sort-Object CPUPercent -Descending | Select-Object -First 10
This shows the top 10 processes by current CPU usage. Note that the counter returns a percentage of a single core, so values can exceed 100% on multi-core systems.
Calculating Overall Cpu Usage From Processes
Summing process-level counters gives you total CPU usage. But it’s easier to use the _Total counter we already covered.
For historical analysis, log process data periodically:
$logPath = "C:\Logs\process_cpu.csv"
"Timestamp,ProcessName,PID,CPUPercent" | Out-File $logPath
while ($true) {
Get-Process | ForEach-Object {
$counter = "\Process($($_.ProcessName))\ % Processor Time"
try {
$cpu = (Get-Counter $counter -ErrorAction Stop).CounterSamples.CookedValue
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'),$($_.ProcessName),$($_.Id),$([Math]::Round($cpu,2))" | Out-File $logPath -Append
} catch {}
}
Start-Sleep -Seconds 30
}
This generates a detailed log but can be slow on systems with many processes. Use it sparingly.
Using Remote Computers
You can check CPU usage on remote machines too. PowerShell remoting makes this easy.
First, enable WinRM on the target computer. Then use Invoke-Command:
Invoke-Command -ComputerName "Server01" -ScriptBlock {
Get-Counter "\Processor(_Total)\% Processor Time"
}
For multiple computers:
$computers = @("Server01", "Server02", "Workstation03")
Invoke-Command -ComputerName $computers -ScriptBlock {
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
[PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
CPUPercent = [Math]::Round($cpu, 2)
Timestamp = Get-Date
}
} | Select-Object ComputerName, CPUPercent, Timestamp
This returns a clean table of results from all machines.
Using CIM Sessions For Remote Data
If WinRM is not available, use CIM sessions:
$session = New-CimSession -ComputerName "Server01"
Get-CimInstance -CimSession $session -ClassName Win32_Processor | Select-Object Name, LoadPercentage
Remove-CimSession $session
CIM sessions work over DCOM or WSMan. They’re more flexible for older systems.
Formatting Output For Readability
Raw numbers aren’t always helpful. Format your output for easy reading.
Create a custom object with calculated properties:
$cpu = Get-Counter "\Processor(_Total)\% Processor Time"
$data = [PSCustomObject]@{
Timestamp = $cpu.Timestamp
CPUPercent = [Math]::Round($cpu.CounterSamples.CookedValue, 2)
Status = if ($cpu.CounterSamples.CookedValue -gt 80) { "High" } else { "Normal" }
}
$data | Format-Table -AutoSize
Add color coding with Write-Host:
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
$color = if ($cpu -gt 80) { "Red" } elseif ($cpu -gt 50) { "Yellow" } else { "Green" }
Write-Host "CPU Usage: $([Math]::Round($cpu,2))%" -ForegroundColor $color
This makes alerts stand out immediately in your console.
Automating Cpu Checks With Scheduled Tasks
For regular monitoring, schedule a PowerShell script to run every 15 minutes.
Create a script file, say Check-CPU.ps1:
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp,$([Math]::Round($cpu,2))" | Out-File "C:\Logs\cpu_auto.csv" -Append
if ($cpu -gt 90) {
# Send alert
$body = "CPU usage at $([Math]::Round($cpu,2))% on $env:COMPUTERNAME at $timestamp"
Send-MailMessage -To "admin@company.com" -From "monitor@company.com" -Subject "High CPU Alert" -Body $body -SmtpServer "smtp.company.com"
}
Then create a scheduled task:
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\Scripts\Check-CPU.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At 0am -RepetitionInterval (New-TimeSpan -Minutes 15) -RepetitionDuration (New-TimeSpan -Days 365)
Register-ScheduledTask -TaskName "CPU Monitor" -Action $action -Trigger $trigger -RunLevel Highest
This runs every 15 minutes indefinitely. Adjust the interval as needed.
Troubleshooting Common Issues
Sometimes commands fail. Here are fixes for frequent problems.
Access Denied Errors
Many performance counters require elevated privileges. Always run PowerShell as Administrator. Right-click the PowerShell icon and select “Run as administrator.”
For remote computers, ensure your account has admin rights on the target machine.
Counter Not Found
If you see “Cannot find any performance counter sets,” the performance counters may be corrupted. Rebuild them:
lodctr /R
cd C:\Windows\System32
lodctr /R
Run these commands in an elevated command prompt. Then restart PowerShell.
Get-Counter Returns 0 Or Null
This often happens on first sample. The counter needs a baseline. Run the command twice in quick succession:
Get-Counter "\Processor(_Total)\% Processor Time" -MaxSamples 2
The second sample usually has valid data.
Comparing Powershell Versions
PowerShell 5.1 and 7 behave slightly differently with CPU commands.
In PowerShell 7, Get-Counter is available but some WMI cmdlets are deprecated. Use Get-CimInstance instead of Get-WmiObject.
PowerShell 7 also supports the -AsJob parameter for async operations:
$job = Get-Counter "\Processor(_Total)\% Processor Time" -AsJob
Receive-Job $job
This runs the counter in the background without blocking your console.
Practical Examples For Daily Use
Here are ready-to-run scripts for common scenarios.
Quick CPU Check Script
function Get-CPUUsage {
param([string[]]$ComputerName = @($env:COMPUTERNAME))
foreach ($comp in $ComputerName) {
try {
$cpu = Get-Counter -ComputerName $comp "\Processor(_Total)\% Processor Time" -ErrorAction Stop
[PSCustomObject]@{
Computer = $comp
CPUPercent = [Math]::Round($cpu.CounterSamples.CookedValue, 2)
Timestamp = $cpu.Timestamp
}
} catch {
Write-Warning "Failed to query $comp : $_"
}
}
}
Get-CPUUsage -ComputerName "Server01", "Server02"
Save this as a function in your profile for quick access.
Real-Time Dashboard
Create a live updating display:
while ($true) {
Clear-Host
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
$bar = "#" * [Math]::Round($cpu / 2)
Write-Host "CPU Usage: $([Math]::Round($cpu,2))%"
Write-Host $bar -ForegroundColor Green
Start-Sleep -Seconds 2
}
This shows a simple progress bar that updates every two seconds.
Integrating With Other Tools
PowerShell output can feed into monitoring systems like Nagios or Zabbix.
For Nagios, output the CPU value as a single number:
$cpu = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue
Write-Output "CPU_USAGE OK | cpu=$([Math]::Round($cpu,2))%;80;90"
For CSV export to Excel:
Get-Counter "\Processor(_Total)\% Processor Time" -SampleInterval 1 -MaxSamples 60 |
Select-Object -ExpandProperty CounterSamples |
Export-Csv -Path "C:\Logs\cpu_60sec.csv" -NoTypeInformation
This captures one minute of data at one-second intervals.
Frequently Asked Questions
Can I Check CPU Usage Without Admin Rights?
Yes, Get-Counter works for standard users on local machines. Remote queries usually require admin privileges. The Get-Process method also works without elevation for local data.
What’s The Difference Between Get-Counter And Get-WmiObject?
Get-Counter provides real-time streaming data with multiple samples. Get-WmiObject returns a single snapshot from WMI. Get-Counter is more accurate for live monitoring.
How Do I Check CPU Usage For A Specific Process?
Use the process counter: Get-Counter “\Process(chrome)\% Processor Time”. Replace “chrome” with your process name. For multiple instances, use the wildcard: “\Process(chrome*)\% Processor Time”.
Why Does My CPU Usage Show Over 100%?
Each core contributes up to 100%. On a quad-core system, total usage can reach 400%. The _Total counter shows the aggregate across all cores. Use per-core counters to see individual loads.
Can I Monitor CPU Usage On Linux With PowerShell?
PowerShell 7 on Linux uses different commands. Use Get-CimInstance Win32_Processor on Windows only. For Linux, use Get-Process or parse /proc/stat with Get-Content.
Final Tips For Effective Monitoring
Start with simple commands and build complexity as needed. The Get-Counter method is your best friend for accurate, real-time data.
Log data regularly to spot trends. A 90% CPU spike at 3 AM might indicate a scheduled task running amok.
Combine CPU monitoring with memory and disk checks for a complete picture. PowerShell can query all these metrics with similar commands.
Test your scripts on a non-production system first. Some counters can be resource-intensive