PowerShellでCPUとメモリの使用率をログに出力する方法

PowerShellでCPUとメモリの使用率をログに出力する方法は「Get-CounterでCPU percentとAvailable MBytesを同じsample時刻に取得し、上限付きのCSVへ記録します。memory使用率が必要ならtotal memoryとavailableを同じ単位で計算し、単発値ではなく時系列で判定します。」と理解すると迷いません。Windows performance counter名は表示language差があり、sample間隔・件数・保存容量を上限付きで設計する点が適用条件です。

目次

実機のcounter setから利用可能pathを選ぶ

CPU・メモリーログでは、採取するカウンターパス、サンプル間隔、最大サンプル数、保存先を先に決めます。Get-CounterのTimestampとCookedValueを数件確認し、Totalとプロセス別インスタンスを混同しないようにします。CSVは別名で作成し、予定行数と時刻範囲を検証してから長時間採取へ移行します。

  • Get-Counter -ListSetでcounter setとlocal名を確認する
  • Get-CimInstance Win32_OperatingSystemでTotalVisibleMemorySizeを確認する
  • sample interval、MaxSamples、log path、保持容量を決める
  • service accountのwrite権限とtimezoneを確認する

sample間隔と最大回数を先に決める

Processor Timeはsampling windowにおけるcounter値で、Get-Process CPUの累積秒とは別です。Available MBytesは使用中memory percentではありません。cacheの扱いやcommit pressureも別counterで確認します。瞬間spike、一時的なGC、継続高負荷を区別するにはsample間隔と期間をworkloadへ合わせます。

CounterSamplesをlong形式へ展開する

  • Get-Process CPUを瞬間率とする
  • Available MBytesをmemory使用率と表示する
  • 無限loopでAdd-Contentする
  • counter名のlanguage差を無視する
  • CSVを同じ名前へ無期限appendする

Available MBytesと使用率を分けて計算する

counterを一回取得

Get-Counter '\Processor(_Total)\% Processor Time','\Memory\Available MBytes' |
  Select-Object -ExpandProperty CounterSamples | Select-Object Path,CookedValue,Timestamp

local OS languageでcounter pathが違う場合があります。実機ListSetから選びます。

CPUとmemoryを十二回sample

$samples=Get-Counter '\Processor(_Total)\% Processor Time','\Memory\Available MBytes' -SampleInterval 5 -MaxSamples 12

一分だけのtestです。無限loopにせず実行時間を見積もります。

long format CSVへ変換

$samples.CounterSamples | Select-Object Timestamp,Path,InstanceName,CookedValue |
  Export-Csv -LiteralPath '.\perf-20260717.csv' -NoTypeInformation -Encoding utf8

counterごと一行のlong formatは後からpivotしやすく、列追加にも耐えます。

memory使用率を計算

$os=Get-CimInstance Win32_OperatingSystem
$totalMB=$os.TotalVisibleMemorySize/1024
$availableMB=$os.FreePhysicalMemory/1024
[pscustomobject]@{TotalMB=$totalMB;AvailableMB=$availableMB;UsedPercent=(($totalMB-$availableMB)/$totalMB*100)}

CIM値はKiB単位です。Get-Counterと取得時刻がずれる点を記録します。

CSVを読み戻す

Import-Csv '.\perf-20260717.csv' | Measure-Object
Import-Csv '.\perf-20260717.csv' | Select-Object -First 4

列、件数、decimal表現、文字化けを確認します。

CSVの列・encoding・保存先を固定する

monitoringは読み取りですが、短間隔・多数counter・無期限保存は負荷とdisk枯渇を招きます。MaxSamples、timeout、file size上限、rotation、ACLを設定し、credentialやprocess command lineを必要なく収集しません。log pathが満杯になったらsecurity log等を削除せず、この監視の新規出力を停止し、古い監視dataを保持policyに従って整理します。

localized path・NaN・書込失敗を検出する

Task ManagerまたはPerformance Monitorと同じ時間帯・単位で傾向を照合し、sample件数がMaxSamplesとcounter数に合うか確認します。CPU idle/load、memory allocation testを限定環境で行い、欠測、counter unavailable、disk不足を別statusへ記録します。

予定行数・Status・読み戻しでlogを検収する

Get-CounterのCounterSamplesをTimestamp、Path、InstanceName、CookedValueのlong形式へ保存します。CPU % Processor Timeはinterval値、Available MBytesは空き容量で単位が異なるため、同じpercent列へ押し込みません。

三回のCPU・memory sampleをCSVへ保存する

$samples=Get-Counter '\Processor(_Total)\% Processor Time','\Memory\Available MBytes' -SampleInterval 2 -MaxSamples 3 -ErrorAction Stop
$rows=@($samples.CounterSamples | Select-Object Timestamp,Path,InstanceName,CookedValue)
$rows | Export-Csv '.\perf-sample.csv' -NoTypeInformation -Encoding utf8
[pscustomobject]@{Rows=$rows.Count;Errors=@($samples.CounterSamples | Where-Object { $_.Status -ne 0 }).Count}

sample欠損をStatusと予定行数で検出する

  • 全counter sample取得:MaxSamples×counter instance相当の行を取得し、CookedValueが数値でTimestamp順になる
  • counter未提供:指定counterなしは0行成功にせず、localized counter setの候補をListSetで確認する
  • 採取・CSV error:PDH error、NaN、sample欠落、CSV書込errorは取得/保存別のerror件数へ分ける

Get-Process CPUの累積秒をCPU使用率として混ぜません。counter名はOS languageで変わり得るため、対象hostのGet-Counter -ListSetで確認します。同名CSVへの無制限appendを避け、rotationと容量上限を持たせます。

localized名・blank値・途中cancelを試す

$read=@(Import-Csv '.\perf-sample.csv')
[pscustomobject]@{Rows=$read.Count;BlankValues=@($read|Where-Object CookedValue -eq '').Count;First=$read[0].Timestamp;Last=$read[-1].Timestamp}

idle/load、counter不存在、localized名、disk不足、途中cancelをtestします。予定/実sample数、Path別件数、NaN/blank、CSV byte数、開始終了時刻を照合します。

二つのcounterを三回取得するfixtureなら、正常時は六行が基準です。CounterSamplesのStatus、CSV行数、blank値を読み戻し、counter pathがlocalizedされる端末ではListSetの実名へ置き換えます。

公式情報・参考資料

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次