Technical Implementation of CPU and Memory Usage Monitoring with PowerShell

Nov 20, 2025 · Programming · 11 views · 7.8

Keywords: PowerShell | System Monitoring | CPU Usage | Memory Monitoring | WMI | Performance Counters

Abstract: This paper comprehensively explores various methods for obtaining CPU and memory usage in PowerShell environments, focusing on the application techniques of Get-WmiObject and Get-Counter commands. By comparing the advantages and disadvantages of different approaches, it provides complete solutions for both single queries and continuous monitoring, while deeply explaining core concepts of WMI classes and performance counters. The article includes detailed code examples and performance optimization recommendations to help system administrators efficiently implement system resource monitoring.

Overview of PowerShell System Resource Monitoring Technology

In Windows system administration, accurately obtaining CPU and memory usage rates is a fundamental task for system monitoring and performance analysis. PowerShell, as Microsoft's officially recommended automation management tool, provides multiple methods for acquiring system resource usage information. This paper will deeply explore two main technical approaches based on WMI (Windows Management Instrumentation) and performance counters.

WMI Method for CPU Usage Monitoring

Using the Get-WmiObject command to query the Win32_Processor class is the most direct method for CPU monitoring. This WMI class provides detailed processor information, including current load percentage. The basic query command is as follows:

Get-WmiObject Win32_Processor | Select-Object LoadPercentage | Format-List

For multi-processor systems, this command returns independent load data for each processor. If system-wide average load calculation is needed, the Measure-Object command can be used for aggregation:

Get-WmiObject Win32_Processor | Measure-Object -Property LoadPercentage -Average | Select-Object Average

This method is suitable for monitoring scenarios requiring precision at individual processor core level, but with relatively lower real-time performance, typically with 1-2 second sampling intervals.

Performance Counter Method for System Resources

The Get-Counter command, based on the Windows Performance Counter framework, provides more granular resource monitoring capabilities. The basic command for obtaining available memory is:

Get-Counter '\Memory\Available MBytes'

The command for obtaining total processor usage is:

Get-Counter '\Processor(_Total)\% Processor Time'

The advantage of the performance counter method lies in higher real-time performance and rich metric selection. All available memory-related counters can be viewed using the ListSet parameter:

Get-Counter -ListSet *memory* | Select-Object -ExpandProperty Counter

Continuous Monitoring Script Implementation

Combining the advantages of both methods, continuous monitoring scripts can be constructed. The following example demonstrates a complete implementation for real-time CPU and memory usage monitoring:

$totalRam = (Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).Sum
while($true) {
    $date = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $cpuTime = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
    $availMem = (Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue
    $date + ' > CPU: ' + $cpuTime.ToString("#,0.000") + '%, Avail. Mem.: ' + $availMem.ToString("N0") + 'MB (' + (104857600 * $availMem / $totalRam).ToString("#,0.0") + '%)'
    Start-Sleep -s 2
}

This script samples every 2 seconds, outputting formatted monitoring information including timestamp, CPU usage rate, and available memory percentage. The monitoring loop can be terminated using Ctrl+C.

Process-Level Resource Monitoring

For more granular monitoring requirements, resource usage of individual processes can be obtained:

Get-Counter -ComputerName localhost '\Process(*)\% Processor Time' | Select-Object -ExpandProperty countersamples | Select-Object -Property instancename, cookedvalue | Sort-Object -Property cookedvalue -Descending | Select-Object -First 20 | Format-Table InstanceName,@{L='CPU';E={($_.Cookedvalue/100).toString('P')}} -AutoSize

This command returns the top 20 processes with highest CPU usage rates, facilitating identification of applications with significant resource consumption.

Remote Monitoring Implementation

PowerShell supports remote system monitoring. Through the Enter-PSSession command, connections can be established to remote computers for executing monitoring scripts:

Enter-PSSession -ComputerName MyServerName -Credential MyUserName

Remote monitoring requires proper permission configuration and network connectivity, which is particularly important for multi-server management in enterprise environments.

Technical Selection Recommendations

When selecting monitoring methods, specific requirements should be considered: WMI method is suitable for hardware information acquisition and basic monitoring, while performance counter method is more appropriate for real-time performance analysis and detailed monitoring. For production environments, combining both methods is recommended, using WMI for configuration information acquisition and performance counters for runtime monitoring.

Performance Optimization Considerations

Frequent resource queries may impact system performance. Reasonable sampling intervals should be set to avoid excessive query frequency. For long-term monitoring scenarios, consider exporting data to files or databases for subsequent analysis:

# Example data export code
$monitorData = @{
    Timestamp = Get-Date
    CPUUsage = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
    AvailableMemory = (Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue
}
$monitorData | Export-Csv -Path "C:\monitoring.csv" -Append -NoTypeInformation

Error Handling and Logging

When implementing monitoring in production environments, comprehensive error handling mechanisms must be included:

try {
    $cpuUsage = (Get-Counter '\Processor(_Total)\% Processor Time' -ErrorAction Stop).CounterSamples.CookedValue
} catch {
    Write-Error "Unable to obtain CPU usage: $($_.Exception.Message)"
    # Log to event log or file
}

Through appropriate error handling and logging, stable operation of monitoring scripts and problem diagnosis can be ensured.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.