I have written this PowerShell script to log the current CPU and RAM usage, but it seems to get the date wrong on my Windows 11 local pc.
My Code:
# Number of CPU Cores
$cpuCores = (Get-WmiObject -Class Win32_ComputerSystem).NumberOfLogicalProcessors
# Sampling interval in seconds
$sampleInterval = 1
# File path
$logFilePath = "C:\Users\walde\Desktop\PerfLog\" + (Get-Date -Format "yyyy-MM-dd") + ".txt"
# Capture total available RAM
$totalPhysicalMemory = (Get-WmiObject -Class Win32_ComputerSystem).TotalPhysicalMemory / 1MB
# First sample for CPU times and RAM usage, as well as process names
$firstSample = @{}
$processRAMUsage = @{}
$processNames = @{}
Get-Process | ForEach-Object {
$firstSample[$_.Id] = $_.TotalProcessorTime.TotalSeconds
$processRAMUsage[$_.Id] = [math]::Round(($_.WorkingSet64 / 1MB) / $totalPhysicalMemory * 100, 2)
$processNames[$_.Id] = $_.Name
}
# Wait for the next CPU sample
Start-Sleep -Seconds $sampleInterval
# Second sample for CPU times
$secondSample = @{}
Get-Process | ForEach-Object { $secondSample[$_.Id] = $_.TotalProcessorTime.TotalSeconds }
# Calculation of CPU usage and adding a timestamp
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$cpuUsage = foreach ($id in $firstSample.Keys) {
$secondCPU = $secondSample[$id]
if ($secondCPU) {
[PSCustomObject]@{
Timestamp = $timestamp
ProcessName = $processNames[$id]
CPUUsage = [math]::Round((($secondCPU - $firstSample[$id]) / $sampleInterval / $cpuCores) * 100, 2)
}
}
}
# CPU Log
$totalCPUUsage = [math]::Round(($cpuUsage | Measure-Object CPUUsage -Sum).Sum, 2)
$idleCPU = [math]::Round(100 - $totalCPUUsage, 2)
$totalAndIdleCPU = @(
[PSCustomObject]@{Timestamp = $timestamp; ProcessName = "Total CPU Usage"; CPUUsage = $totalCPUUsage},
[PSCustomObject]@{Timestamp = $timestamp; ProcessName = "Idle CPU"; CPUUsage = $idleCPU}
)
$finalCPULogData = $totalAndIdleCPU + ($cpuUsage | Sort-Object CPUUsage -Descending)
$finalCPULogData | Select-Object -First 12 | Format-Table -AutoSize #| Out-String | Out-File -FilePath ($logFilePath) -Append
# RAM Log
$totalRAMUsage = [math]::Round(($processRAMUsage.Values | Measure-Object -Sum).Sum, 2)
$idleRAM = [math]::Round(100 - $totalRAMUsage, 2)
$ramUsage = foreach ($id in $processRAMUsage.Keys) {
[PSCustomObject]@{
Timestamp = $timestamp
ProcessName = $processNames[$id]
RAMUsage = $processRAMUsage[$id]
}
}
$totalAndIdleRAM = @(
[PSCustomObject]@{Timestamp = $timestamp; ProcessName = "Total RAM Usage"; RAMUsage = $totalRAMUsage},
[PSCustomObject]@{Timestamp = $timestamp; ProcessName = "Idle RAM"; RAMUsage = $idleRAM}
)
$finalRAMLogData = $totalAndIdleRAM + ($ramUsage | Sort-Object RAMUsage -Descending)
$finalRAMLogData | Select-Object -First 12 | Format-Table -AutoSize | Out-String #| Out-File -FilePath ($logFilePath) -Append
Tried some other measuring scripts: Powershell: Monitor CPU and RAM percentage usage and send email alert But it also gets the Total CPU wrong.