【bat】typeperfコマンド完全ガイド|CPU・メモリ・ディスク・ネットワーク使用率をバッチで監視・記録する

【bat】typeperfコマンド完全ガイド|CPU・メモリ・ディスク・ネットワーク使用率をバッチで監視・記録する bat

「バッチからCPU使用率を取得したい」「メモリ不足を自動検知して通知したい」という場面で活躍するのが typeperfコマンド です。Windowsに標準搭載されており、インストール不要でパフォーマンスカウンターをリアルタイムに取得できます。

本記事では、typeperfの基本構文から、CPU・メモリ・ディスク・ネットワークの使用率取得、CSVログへの記録、閾値アラート、タスクスケジューラとの連携、PowerShellとの組み合わせまで、実際に動作するバッチスクリプトを使って徹底解説します。

本記事で分かること

  • typeperfコマンドの基本構文とオプション一覧
  • CPU・メモリ・ディスク・ネットワーク使用率の取得方法
  • パフォーマンスデータをCSVファイルに自動記録する方法
  • 閾値を超えたときにアラートを出す監視スクリプト
  • タスクスケジューラと組み合わせた定期監視の実装
  • 複数PCの一括監視とCSVデータの後集計パターン
スポンサーリンク
  1. typeperfとは
  2. まず動かしてみる(クイック確認スクリプト)
  3. 基本構文とオプション
  4. 主要なパフォーマンスカウンター一覧
    1. CPUカウンター
    2. メモリカウンター
    3. ディスクカウンター
    4. ネットワークカウンター
  5. ディスクカウンターの有効化(diskperf)
  6. CPU使用率の取得と判定
    1. CPU使用率を取得して変数に格納する
    2. 複数回の平均CPU使用率を取得する
  7. メモリ使用率の取得と監視
    1. 利用可能なメモリ(MB)を取得する
    2. 全体メモリ使用率を計算する
  8. ディスク使用率の取得と監視
    1. ディスクI/O使用率を取得する
    2. Cドライブの空き容量を確認する
  9. ネットワーク使用率の取得と監視
    1. NIC名を確認する
    2. ネットワーク使用帯域を取得する
    3. ネットワーク帯域利用率を計算する
  10. パフォーマンスデータをCSVファイルに自動記録する
    1. 基本的なCSVログ記録
    2. 日付別フォルダに振り分けて保存する
  11. カウンターリストファイルを使った効率的な管理
  12. 閾値監視とアラートスクリプト
    1. 総合ヘルスチェックスクリプト
  13. 継続的なリアルタイム監視スクリプト
  14. タスクスケジューラと連携した定期監視
    1. タスクスケジューラへの登録
    2. 1時間ごとにパフォーマンスを記録するパターン
  15. 実践的な活用パターン
    1. パターン①:高負荷処理の前後でシステム状態を記録する
    2. パターン②:夜間バッチの実行前チェック
    3. パターン③:アプリケーション起動中のメモリ変化を記録する
    4. パターン④:複数PCのパフォーマンスを一括確認する
    5. パターン⑤:TypeperfのCSVデータをバッチで後集計する
  16. PowerShellと連携して分析・可視化する
    1. typeperfのCSVをPowerShellで集計する
    2. バッチからGet-Counterを呼び出してリアルタイム取得する
  17. typeperfでよく発生するエラーと対処法
    1. エラー①:カウンターが見つからない
    2. エラー②:日本語環境でカウンターが動かない
    3. エラー③:NIC名にスペースや特殊文字が含まれる
    4. エラー④:値が空またはゼロになる
    5. エラー⑤:管理者権限がないと一部カウンターが取得できない
    6. エラー⑥:バッチの %% 記号がコマンドプロンプトと異なる
    7. エラー⑦:for /f での for ループ変数と typeperf の出力が噛み合わない
  18. typeperf利用時の注意事項
  19. wmic・PowerShellとの使い分けまとめ
  20. よくある質問
  21. まとめ

typeperfとは

typeperf(タイプパーフ)は、Windowsのパフォーマンスモニター(perfmon)が収集しているパフォーマンスカウンターのデータをコマンドラインから取得するツールです。Windows XP以降に標準搭載されており、追加インストールは不要です。

パフォーマンスカウンターとは、CPU使用率・メモリ使用量・ディスクI/O・ネットワーク帯域など、システムの状態を数値化したものです。typeperfを使うと、これらの値をバッチファイルから直接取得し、ログに記録したり、条件分岐に使ったりできます。

比較項目 typeperf wmic PowerShell Get-Counter
標準搭載 ○ (Vista以降) ○ (XP以降) ○ (Win7以降)
取得できる情報 パフォーマンスカウンター全般 WMIクラス全般 パフォーマンスカウンター全般
CSV出力 -o オプションで直接出力 リダイレクト Export-Csv
継続的な監視 -si -sc オプション ループが必要 -Continuous
バッチとの親和性 高い(bat内で直接処理) 高い やや低い(呼び出し必要)
日本語環境の注意点 カウンター名の日本語対応あり UTF-16出力に注意 概ね問題なし

typeperfが特に向いている場面
定期的にパフォーマンスデータを収集してCSVに記録したい場合や、他のバッチ処理の前後でシステム状態を確認したいときに最適です。GUIを使わずに監視できるため、サーバーやリモート環境にも適しています。

まず動かしてみる(クイック確認スクリプト)

難しい設定の前に、実際の動作を確認しましょう。次のスクリプトを実行すると、現在のシステム状態を一括確認できます。

quick_check.bat
@echo off
setlocal enabledelayedexpansion

echo ====================================
echo  システム状態クイック確認
echo ====================================

:: CPU使用率(2回サンプルして2回目を使用)
for /f "skip=2 tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 2 -si 1 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do set CPU=%%B
)

:: 利用可能メモリ(MB)
for /f "tokens=2 delims=," %%A in ('typeperf "\\Memory\\Available MBytes" -sc 1 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do set MEM=%%B
)

:: Cドライブ空き容量率
for /f "tokens=2 delims=," %%A in ('typeperf "\\LogicalDisk(C:)\\%% Free Space" -sc 1 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do set DFREE=%%B
)

echo CPU使用率:         !CPU!%%
echo 利用可能メモリ:     !MEM! MB
echo Cドライブ空き:     !DFREE!%%

endlocal

これでtypeperfが正しく動作しているか確認できます。値が取得できない場合は、後述の「よくあるエラーと対処法」を参照してください。

基本構文とオプション

typeperfの基本構文は次のとおりです。

基本構文
typeperf "\カウンターパス" [オプション]
オプション 説明
-sc N N回だけサンプリングして終了 -sc 5
-si N サンプリング間隔(秒) -si 10
-o ファイル名 出力先CSVファイル -o perf.csv
-f CSV 出力形式をCSVに指定(デフォルト) -f CSV
-cf ファイル名 カウンターリストをファイルから読む -cf counters.txt
-q [オブジェクト] 利用可能なカウンター名を一覧表示 typeperf -q
-qx [オブジェクト] カウンター名をインスタンス付きで表示 typeperf -qx

まずは動作確認として、CPU使用率を1回だけ取得してみましょう。

CPU使用率を1回取得
typeperf "\Processor(_Total)\% Processor Time" -sc 1

実行すると、次のようなCSV形式の出力が得られます。

出力例
"(PDH-CSV 4.0)","\\PCNAME\Processor(_Total)\% Processor Time"
"04/15/2025 10:30:01.500","12.567890"

1行目がヘッダー、2行目が実際の値です。バッチで値だけを取り出すには、for /fと組み合わせます(後述)。

主要なパフォーマンスカウンター一覧

typeperfで使用できる主要なカウンターを紹介します。カウンター名は英語環境と日本語環境で異なる場合があります(後述)。

CPUカウンター

カウンターパス 説明
\Processor(_Total)\% Processor Time 全コアの合計CPU使用率
\Processor(0)\% Processor Time コア0のCPU使用率
\Processor(_Total)\% Idle Time アイドル時間の割合
\Processor(_Total)\% User Time ユーザーモードのCPU使用率
\Processor(_Total)\% Privileged Time カーネルモードのCPU使用率
\System\Processor Queue Length CPUキューの長さ(過負荷の指標)

メモリカウンター

カウンターパス 説明
\Memory\Available MBytes 利用可能な物理メモリ(MB)
\Memory\% Committed Bytes In Use コミット済みメモリの使用率
\Memory\Pages/sec ページングの発生頻度(高いと要注意)
\Memory\Pool Nonpaged Bytes 非ページドプールのサイズ
\Memory\Cache Bytes ファイルシステムキャッシュのサイズ

ディスクカウンター

カウンターパス 説明
\PhysicalDisk(_Total)\% Disk Time ディスクがビジー状態の割合
\PhysicalDisk(_Total)\Avg. Disk Queue Length ディスクキューの長さ
\PhysicalDisk(_Total)\Disk Read Bytes/sec ディスク読み取り速度(バイト/秒)
\PhysicalDisk(_Total)\Disk Write Bytes/sec ディスク書き込み速度(バイト/秒)
\PhysicalDisk(_Total)\Avg. Disk sec/Transfer I/O応答時間(秒)。15ms超えは要注意
\LogicalDisk(C:)\% Free Space Cドライブの空き容量割合

ネットワークカウンター

カウンターパス 説明
\Network Interface(*)\Bytes Received/sec 受信バイト数/秒(全NIC)
\Network Interface(*)\Bytes Sent/sec 送信バイト数/秒(全NIC)
\Network Interface(*)\Bytes Total/sec 送受信合計バイト数/秒
\Network Interface(*)\Current Bandwidth NICの帯域(bps)。利用率計算に使用

日本語環境でのカウンター名について
日本語版Windowsでは \Processor\プロセッサ と表示される場合があります。ただし、typeperfではどちらの表記でも動作します。カウンター名が不明な場合は typeperf -q | findstr /i "processor" で確認してください。

ディスクカウンターの有効化(diskperf)

Windows 10/11では物理ディスクのカウンターはデフォルトで有効ですが、古いOSや一部のサーバー環境ではカウンターが無効化されていることがあります。ディスク関連のカウンターが取得できない場合は、diskperfコマンドで有効化します。

diskperfの確認と有効化
:: ディスクカウンターの状態確認(管理者権限不要)
diskperf

:: 全ディスクカウンターを有効化(管理者権限が必要)
diskperf -y

:: 有効化後、物理ディスクカウンターのみ有効化
diskperf -yv

:: 論理ディスクカウンターのみ有効化
diskperf -yd

:: 次回起動時まで無効化(現在のセッションのみ有効)
diskperf -n
オプション 説明
diskperf 現在の状態を確認
diskperf -y 物理ディスクと論理ディスクの両方を有効化
diskperf -yv 物理ディスク(PhysicalDisk)カウンターのみ有効化
diskperf -yd 論理ディスク(LogicalDisk)カウンターのみ有効化
diskperf -n カウンターを無効化

diskperfの変更はOS再起動が必要です
diskperfコマンドを実行後、設定が有効になるのは次回のOS起動からです。変更後は再起動してからtypeperfでカウンターを確認してください。

ディスクカウンター確認用スクリプト
@echo off
setlocal

:: ディスクカウンターが使えるか確認
typeperf "\PhysicalDisk(_Total)\%% Disk Time" -sc 1 -f CSV >nul 2>&1
if errorlevel 1 (
    echo [INFO] ディスクカウンターが取得できません
    echo        diskperf -y を実行して再起動してください
) else (
    echo [OK] ディスクカウンターは正常に取得できます
)

endlocal

CPU使用率の取得と判定

typeperfの出力はCSV形式のため、for /fコマンドで値を取り出します。小数点以下を含む数値のため、整数比較には工夫が必要です。

CPU使用率を取得して変数に格納する

cpu_check.bat
@echo off
setlocal enabledelayedexpansion

:: CPU使用率を1回取得(-sc 1 で1サンプルのみ)
for /f "tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 1 -f CSV 2^>nul') do (
    set "CPU_RAW=%%~A"
)

:: 小数点以下を切り捨てて整数に変換
for /f "delims=." %%B in ("!CPU_RAW!") do set "CPU_INT=%%B"

:: 先頭の " を除去(CSVの引用符対策)
set "CPU_INT=!CPU_INT:"=!"

echo CPU使用率: !CPU_INT!%%

if !CPU_INT! GEQ 80 (
    echo [警告] CPU使用率が80%%を超えています
) else (
    echo [正常] CPU使用率は正常範囲です
)

endlocal

ポイントは for /f "delims=." を使って小数点以下を切り捨てる点です。typeperfの出力には引用符が含まれるため、set "CPU_INT=!CPU_INT:"=!" で除去します。

for /f 内の %% について
バッチファイル内では % を2つ重ねて %% と書く必要があります。カウンター名に含まれる %(例: % Processor Time)も同様です。コマンドプロンプトから直接実行する場合は % 1つで構いません。

複数回の平均CPU使用率を取得する

瞬間値はノイズが多いため、数回サンプリングした平均を使うと実態に近い値が得られます。

cpu_avg.bat
@echo off
setlocal enabledelayedexpansion

:: 5秒間隔で3回サンプリング(合計15秒かかる)
set TOTAL=0
set COUNT=0

for /f "skip=2 tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 3 -si 5 -f CSV 2^>nul') do (
    set "VAL=%%~A"
    set "VAL=!VAL:"=!"
    for /f "delims=." %%B in ("!VAL!") do (
        set /a TOTAL+=%%B
        set /a COUNT+=1
    )
)

if !COUNT! GTR 0 (
    set /a AVG=TOTAL/COUNT
    echo 平均CPU使用率: !AVG!%% (!COUNT!回計測)
) else (
    echo [エラー] CPU使用率の取得に失敗しました
)

endlocal

-sc 3 -si 5 は「5秒間隔で3回サンプリング」という意味です。skip=2 でヘッダー行(1行目)とタイムスタンプ行を飛ばしています。

メモリ使用率の取得と監視

メモリの監視には「利用可能なメモリ(MB)」と「コミット使用率」の2つのカウンターが特に重要です。利用可能なメモリが一定量を下回った場合にアラートを出す方法を解説します。

利用可能なメモリ(MB)を取得する

mem_check.bat
@echo off
setlocal enabledelayedexpansion

:: 利用可能な物理メモリ(MB)を取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\Memory\\Available MBytes" -sc 1 -f CSV 2^>nul') do (
    set "MEM_RAW=%%~A"
)

:: 引用符除去・小数点以下切り捨て
set "MEM_RAW=!MEM_RAW:"=!"
for /f "delims=." %%B in ("!MEM_RAW!") do set "MEM_MB=%%B"

echo 利用可能なメモリ: !MEM_MB! MB

:: 1024MB未満の場合は警告
if !MEM_MB! LSS 1024 (
    echo [警告] 空きメモリが1GB未満です ^(!MEM_MB! MB^)
) else (
    echo [正常] メモリに余裕があります
)

endlocal

全体メモリ使用率を計算する

typeperfでは「使用率(%)」ではなく「空きMB」が取得できるため、使用率に変換するには総メモリ量が必要です。wmicで総メモリを取得して計算します。

mem_usage_rate.bat
@echo off
setlocal enabledelayedexpansion

:: 総物理メモリ(バイト)をwmicで取得
for /f "skip=1 tokens=*" %%A in ('wmic ComputerSystem get TotalPhysicalMemory 2^>nul') do (
    if not "%%A"=="" set "TOTAL_BYTES=%%A"
)

:: 先頭の空白と不要文字除去
for /f "tokens=1" %%B in ("!TOTAL_BYTES!") do set TOTAL_BYTES=%%B

:: バイト→MB変換(整数演算)
set /a TOTAL_MB=TOTAL_BYTES/1024/1024

:: 利用可能なメモリ(MB)をtypeperfで取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\Memory\\Available MBytes" -sc 1 -f CSV 2^>nul') do (
    set "FREE_RAW=%%~A"
)
set "FREE_RAW=!FREE_RAW:"=!"
for /f "delims=." %%B in ("!FREE_RAW!") do set "FREE_MB=%%B"

:: 使用率を計算
set /a USED_MB=TOTAL_MB-FREE_MB
set /a RATE=USED_MB*100/TOTAL_MB

echo 総メモリ:   !TOTAL_MB! MB
echo 使用中:     !USED_MB! MB
echo 空き:       !FREE_MB! MB
echo 使用率:     !RATE!%%

if !RATE! GEQ 90 (
    echo [警告] メモリ使用率が90%%を超えています
) else if !RATE! GEQ 70 (
    echo [注意] メモリ使用率が高めです
) else (
    echo [正常] メモリ使用率は正常です
)

endlocal

wmicを使った総メモリ取得については、wmicコマンド完全ガイドも参考にしてください。

ディスク使用率の取得と監視

ディスクの状態監視には、I/Oビジー率とディスクキュー長が重要な指標です。ディスクキュー長が2以上になるとI/Oが詰まっているサインです。

ディスクI/O使用率を取得する

disk_check.bat
@echo off
setlocal enabledelayedexpansion

:: ディスクビジー率を取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\PhysicalDisk(_Total)\\%% Disk Time" -sc 1 -f CSV 2^>nul') do (
    set "DISK_RAW=%%~A"
)
set "DISK_RAW=!DISK_RAW:"=!"
for /f "delims=." %%B in ("!DISK_RAW!") do set "DISK_INT=%%B"

:: ディスクキュー長を取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\PhysicalDisk(_Total)\\Avg. Disk Queue Length" -sc 1 -f CSV 2^>nul') do (
    set "QUEUE_RAW=%%~A"
)
set "QUEUE_RAW=!QUEUE_RAW:"=!"
for /f "delims=." %%B in ("!QUEUE_RAW!") do set "QUEUE_INT=%%B"

:: ディスク応答時間(秒)を取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\PhysicalDisk(_Total)\\Avg. Disk sec/Transfer" -sc 1 -f CSV 2^>nul') do (
    set "LATENCY_RAW=%%~A"
)
set "LATENCY_RAW=!LATENCY_RAW:"=!"

echo ディスクビジー率: !DISK_INT!%%
echo ディスクキュー長: !QUEUE_INT!
echo ディスク応答時間: !LATENCY_RAW! 秒

if !DISK_INT! GEQ 80 (
    echo [警告] ディスクI/Oが高負荷状態です
) else (
    echo [正常] ディスクI/Oは正常です
)

if !QUEUE_INT! GEQ 2 (
    echo [注意] ディスクキューが詰まっています ^(!QUEUE_INT!^)
)

endlocal

Cドライブの空き容量を確認する

ディスクの空き容量率は \LogicalDisk カウンターで取得できます。

disk_space.bat
@echo off
setlocal enabledelayedexpansion

:: Cドライブの空き容量率を取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\LogicalDisk(C:)\\%% Free Space" -sc 1 -f CSV 2^>nul') do (
    set "FREE_RAW=%%~A"
)
set "FREE_RAW=!FREE_RAW:"=!"
for /f "delims=." %%B in ("!FREE_RAW!") do set "FREE_PCT=%%B"

echo Cドライブ空き容量率: !FREE_PCT!%%

if !FREE_PCT! LSS 10 (
    echo [警告] 空き容量が10%%未満です。ディスクを確認してください
) else if !FREE_PCT! LSS 20 (
    echo [注意] 空き容量が少なくなっています
) else (
    echo [正常] ディスクの空き容量は十分です
)

endlocal

ネットワーク使用率の取得と監視

ネットワークの監視では、まずNIC(ネットワークインターフェース)の名前を確認する必要があります。インスタンス名にスペースや特殊文字が含まれることが多いため注意が必要です。

NIC名を確認する

list_nic.bat
@echo off
:: 利用可能なネットワークカウンターを表示
typeperf -q "Network Interface"

出力例:

出力例
\Network Interface(Intel[R] Ethernet Connection)\Bytes Total/sec
\Network Interface(Wi-Fi)\Bytes Total/sec
\Network Interface(Loopback Pseudo-Interface 1)\Bytes Total/sec

ネットワーク使用帯域を取得する

ワイルドカード(*)を使うと全NICの合計を取得できます。

net_check.bat
@echo off
setlocal enabledelayedexpansion

:: 全NICの受信バイト数/秒を取得
set RECV_TOTAL=0
for /f "skip=2 tokens=2 delims=," %%A in ('typeperf "\\Network Interface(*)\\Bytes Received/sec" -sc 1 -f CSV 2^>nul') do (
    set "VAL=%%~A"
    set "VAL=!VAL:"=!"
    for /f "delims=." %%B in ("!VAL!") do set /a RECV_TOTAL+=%%B 2^>nul
)

:: バイト/秒 → KB/秒 に変換
set /a RECV_KB=RECV_TOTAL/1024
echo 受信速度: !RECV_KB! KB/秒

if !RECV_KB! GEQ 102400 (
    echo [注意] 受信帯域が100MB/秒を超えています
) else (
    echo [正常] ネットワーク受信は正常範囲です
)

endlocal

ネットワーク帯域利用率を計算する

「何MB/秒」という絶対値だけでなく、NICの最大帯域に対する「利用率(%)」を計算することでより意味のある監視ができます。

net_utilization.bat
@echo off
setlocal enabledelayedexpansion

:: NIC名を指定(typeperf -q "Network Interface" で確認した名前)
:: スペースを含む場合もそのまま記述
set NIC_NAME=Intel[R] Ethernet Connection

:: 現在の帯域(bps)を取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\Network Interface(%NIC_NAME%)\\Current Bandwidth" -sc 1 -f CSV 2^>nul') do (
    set "BW_RAW=%%~A"
)
set "BW_RAW=!BW_RAW:"=!"
for /f "delims=." %%B in ("!BW_RAW!") do set "BW_BPS=%%B"

:: 現在の送受信合計(バイト/秒)を取得
for /f "tokens=2 delims=," %%A in ('typeperf "\\Network Interface(%NIC_NAME%)\\Bytes Total/sec" -sc 1 -f CSV 2^>nul') do (
    set "BYTES_RAW=%%~A"
)
set "BYTES_RAW=!BYTES_RAW:"=!"
for /f "delims=." %%B in ("!BYTES_RAW!") do set "BYTES_SEC=%%B"

:: 帯域利用率を計算: バイト/秒 × 8 / 帯域(bps)× 100
:: 整数オーバーフロー対策: 1000で割って計算
set /a BW_KBPS=BW_BPS/1000
set /a BYTES_KBPS=BYTES_SEC*8/1000
if !BW_KBPS! GTR 0 (
    set /a UTIL=BYTES_KBPS*100/BW_KBPS
) else (
    set UTIL=0
)

echo 最大帯域:     !BW_BPS! bps
echo 現在の使用量: !BYTES_SEC! bytes/秒
echo 帯域利用率:   !UTIL!%%

if !UTIL! GEQ 80 (
    echo [警告] ネットワーク帯域の80%%以上を使用しています
) else (
    echo [正常] ネットワーク帯域は正常範囲内です
)

endlocal

帯域利用率の計算式は「Bytes/sec × 8 ÷ 帯域(bps) × 100」です。整数演算のオーバーフロー(32ビット限界)を避けるため、計算途中で1000分の1にスケールダウンしています。

継続的なネットワーク監視については、ネットワーク接続を継続監視する完全ガイドも参考にしてください。

パフォーマンスデータをCSVファイルに自動記録する

typeperfは -o オプションでCSVファイルに直接出力できます。これを使って、バックグラウンドでシステムのパフォーマンスを継続的に記録しましょう。

基本的なCSVログ記録

perf_log.bat
@echo off
setlocal

:: ログファイル名に日付を含める
set LOGDATE=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
set LOGFILE=perf_%LOGDATE%.csv

echo パフォーマンス記録開始: %LOGFILE%
echo 記録内容: CPU・メモリ・ディスク(10秒間隔 × 360回 = 1時間)

:: 10秒間隔で360回(= 1時間)のパフォーマンスを記録
typeperf ^
  "\Processor(_Total)\%% Processor Time" ^
  "\Memory\Available MBytes" ^
  "\PhysicalDisk(_Total)\%% Disk Time" ^
  "\Network Interface(*)\Bytes Total/sec" ^
  -si 10 -sc 360 ^
  -o "%LOGFILE%"

echo 記録完了: %LOGFILE%

endlocal

複数のカウンターをスペース区切りで並べると、1つのCSVファイルにまとめて記録できます。出力されるCSVのカラム構成は次のとおりです。

CSVの構造(ヘッダー行と1サンプル)
"(PDH-CSV 4.0)","\PCNAME\Processor(_Total)\% Processor Time","\PCNAME\Memory\Available MBytes","\PCNAME\PhysicalDisk(_Total)\% Disk Time"
"2025/04/15 10:00:00.000","15.234","3584.000","2.345"
"2025/04/15 10:00:10.000","8.901","3520.000","0.123"

日付別フォルダに振り分けて保存する

perf_log_daily.bat
@echo off
setlocal

:: 日付フォルダを作成
set LOGDATE=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
set LOGDIR=perf_logs\%LOGDATE%
if not exist "%LOGDIR%" mkdir "%LOGDIR%"

:: 時刻を含むファイル名
set LOGTIME=%TIME:~0,2%%TIME:~3,2%
set LOGTIME=%LOGTIME: =0%
set LOGFILE=%LOGDIR%\perf_%LOGDATE%_%LOGTIME%.csv

echo [%DATE% %TIME%] 記録開始: %LOGFILE%

:: 30秒間隔で120回(1時間分)記録
typeperf ^
  "\Processor(_Total)\%% Processor Time" ^
  "\Memory\Available MBytes" ^
  "\Memory\%% Committed Bytes In Use" ^
  "\PhysicalDisk(_Total)\%% Disk Time" ^
  -si 30 -sc 120 ^
  -o "%LOGFILE%"

echo [%DATE% %TIME%] 記録完了

endlocal

ログファイルの自動保存についてはバッチでログを出力する完全ガイドも、世代管理についてはログローテーションの実装方法も参考にしてください。

カウンターリストファイルを使った効率的な管理

監視するカウンターが多い場合、コマンドラインに全部書くと長くなります。-cf オプションを使うと、カウンターをテキストファイルで管理できます。

counters.txt(カウンターリストファイル)
\Processor(_Total)\% Processor Time
\Memory\Available MBytes
\Memory\% Committed Bytes In Use
\PhysicalDisk(_Total)\% Disk Time
\PhysicalDisk(_Total)\Avg. Disk Queue Length
\Network Interface(*)\Bytes Total/sec
perf_with_counters_file.bat
@echo off
setlocal

set CFGFILE=counters.txt
set LOGFILE=perf_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.csv

if not exist "%CFGFILE%" (
    echo [エラー] カウンターファイルが見つかりません: %CFGFILE%
    exit /b 1
)

:: カウンターファイルを使って記録
typeperf -cf "%CFGFILE%" -si 60 -sc 1440 -o "%LOGFILE%"

echo 記録完了: %LOGFILE%
endlocal

カウンターファイルのメリット
カウンターリストをファイルで管理すると、監視対象の変更がバッチファイル本体に影響しません。本番環境とテスト環境でカウンターファイルを切り替えるだけで、同じバッチを使い回せます。

閾値監視とアラートスクリプト

実務でよく使うのが「閾値を超えたらアラートを出す」パターンです。CPU・メモリ・ディスクを同時に監視して、問題があれば通知するスクリプトを作ります。

総合ヘルスチェックスクリプト

health_check.bat
@echo off
setlocal enabledelayedexpansion

set ALERT=0
set LOGFILE=health_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log

echo ================================= >> "%LOGFILE%"
echo %DATE% %TIME% ヘルスチェック開始 >> "%LOGFILE%"
echo ================================= >> "%LOGFILE%"

:: ---- CPU使用率 ----
for /f "tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 1 -f CSV 2^>nul') do (
    set "CPU_RAW=%%~A"
)
set "CPU_RAW=!CPU_RAW:"=!"
for /f "delims=." %%B in ("!CPU_RAW!") do set "CPU=%%B"
echo CPU使用率: !CPU!%% >> "%LOGFILE%"
if !CPU! GEQ 80 (
    echo [ALERT] CPU使用率 !CPU!%% が閾値超過 >> "%LOGFILE%"
    set ALERT=1
)

:: ---- メモリ空き容量 ----
for /f "tokens=2 delims=," %%A in ('typeperf "\\Memory\\Available MBytes" -sc 1 -f CSV 2^>nul') do (
    set "MEM_RAW=%%~A"
)
set "MEM_RAW=!MEM_RAW:"=!"
for /f "delims=." %%B in ("!MEM_RAW!") do set "MEM_MB=%%B"
echo 空きメモリ: !MEM_MB! MB >> "%LOGFILE%"
if !MEM_MB! LSS 512 (
    echo [ALERT] 空きメモリ !MEM_MB! MB が閾値未満 >> "%LOGFILE%"
    set ALERT=1
)

:: ---- ディスクビジー率 ----
for /f "tokens=2 delims=," %%A in ('typeperf "\\PhysicalDisk(_Total)\\%% Disk Time" -sc 1 -f CSV 2^>nul') do (
    set "DISK_RAW=%%~A"
)
set "DISK_RAW=!DISK_RAW:"=!"
for /f "delims=." %%B in ("!DISK_RAW!") do set "DISK=%%B"
echo ディスクビジー率: !DISK!%% >> "%LOGFILE%"
if !DISK! GEQ 80 (
    echo [ALERT] ディスクI/O !DISK!%% が閾値超過 >> "%LOGFILE%"
    set ALERT=1
)

:: ---- Cドライブ空き容量 ----
for /f "tokens=2 delims=," %%A in ('typeperf "\\LogicalDisk(C:)\\%% Free Space" -sc 1 -f CSV 2^>nul') do (
    set "DFREE_RAW=%%~A"
)
set "DFREE_RAW=!DFREE_RAW:"=!"
for /f "delims=." %%B in ("!DFREE_RAW!") do set "DFREE=%%B"
echo Cドライブ空き: !DFREE!%% >> "%LOGFILE%"
if !DFREE! LSS 10 (
    echo [ALERT] Cドライブ空き容量 !DFREE!%% が閾値未満 >> "%LOGFILE%"
    set ALERT=1
)

:: ---- 結果判定 ----
if !ALERT! EQU 1 (
    echo [結果] 問題を検出しました。ログを確認してください: %LOGFILE% >> "%LOGFILE%"
    echo [結果] 問題を検出しました
    exit /b 1
) else (
    echo [結果] すべて正常です >> "%LOGFILE%"
    echo [結果] すべて正常です
    exit /b 0
)

endlocal

このスクリプトのアラートをメール通知と組み合わせる場合は、エラー通知メールを自動送信する完全ガイドを参考にしてください。

継続的なリアルタイム監視スクリプト

typeperfの -si-sc だけでも継続監視はできますが、「閾値超過を即座に検知して何らかの処理を実行したい」場合はバッチのループと組み合わせます。

monitor_loop.bat
@echo off
setlocal enabledelayedexpansion

set CHECK_INTERVAL=30
set CPU_THRESHOLD=85
set MEM_THRESHOLD=512

echo リアルタイム監視開始(Ctrl+C で停止)
echo 間隔: %CHECK_INTERVAL%秒 / CPU閾値: %CPU_THRESHOLD%%% / メモリ閾値: %MEM_THRESHOLD%MB
echo.

:MONITOR_LOOP
    :: CPU取得
    for /f "tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 1 -f CSV 2^>nul') do (
        set "CPU_RAW=%%~A"
    )
    set "CPU_RAW=!CPU_RAW:"=!"
    for /f "delims=." %%B in ("!CPU_RAW!") do set "CPU=%%B"

    :: メモリ取得
    for /f "tokens=2 delims=," %%A in ('typeperf "\\Memory\\Available MBytes" -sc 1 -f CSV 2^>nul') do (
        set "MEM_RAW=%%~A"
    )
    set "MEM_RAW=!MEM_RAW:"=!"
    for /f "delims=." %%B in ("!MEM_RAW!") do set "MEM_MB=%%B"

    :: 表示
    echo [%TIME%] CPU: !CPU!%%  空きMEM: !MEM_MB! MB

    :: 閾値チェック
    if !CPU! GEQ %CPU_THRESHOLD% (
        echo [警告] %TIME% CPU使用率が%CPU_THRESHOLD%%%を超えました: !CPU!%% >> monitor_alert.log
        echo [警告] CPU使用率が高いです: !CPU!%%
    )
    if !MEM_MB! LSS %MEM_THRESHOLD% (
        echo [警告] %TIME% 空きメモリ不足: !MEM_MB! MB >> monitor_alert.log
        echo [警告] 空きメモリが少ないです: !MEM_MB! MB
    )

    :: 次のチェックまで待機
    timeout /t %CHECK_INTERVAL% /nobreak >nul

goto MONITOR_LOOP

endlocal

ループ内でtypeperfを呼び出す際の注意点
typeperfを1回呼び出すたびに外部プロセスが起動するため、短い間隔でループするとオーバーヘッドが大きくなります。5秒未満の間隔での監視が必要な場合は、typeperfの -sc オプションを使って1回の呼び出しで複数サンプルを取得する方法の方が効率的です。

タスクスケジューラと連携した定期監視

ヘルスチェックスクリプトをタスクスケジューラで定期実行することで、自動監視システムが構築できます。

タスクスケジューラへの登録

register_monitor.bat
@echo off
setlocal

set TASK_NAME=SystemHealthCheck
set BAT_PATH=%~dp0health_check.bat

:: 管理者権限チェック
net session >nul 2>&1
if errorlevel 1 (
    echo 管理者権限が必要です
    exit /b 1
)

:: 既存タスクがあれば削除
schtasks /query /tn "%TASK_NAME%" >nul 2>&1
if not errorlevel 1 (
    schtasks /delete /tn "%TASK_NAME%" /f
)

:: 毎時0分に実行するタスクを登録
schtasks /create ^
  /tn "%TASK_NAME%" ^
  /tr "cmd /c "%BAT_PATH%"" ^
  /sc HOURLY ^
  /mo 1 ^
  /ru SYSTEM ^
  /rl HIGHEST ^
  /f

if errorlevel 1 (
    echo [エラー] タスクの登録に失敗しました
    exit /b 1
) else (
    echo [成功] タスクを登録しました: %TASK_NAME%
)

endlocal

タスクスケジューラの詳しい使い方はschtasksコマンド完全ガイドを参照してください。

1時間ごとにパフォーマンスを記録するパターン

タスクスケジューラから呼び出す場合は、作業ディレクトリが不定になることがあります。%~dp0 を使ってスクリプトの場所を基準にするのがポイントです。

hourly_perf_record.bat
@echo off
setlocal

:: スクリプトのある場所を基準にする
cd /d "%~dp0"

set LOGDIR=logs
if not exist "%LOGDIR%" mkdir "%LOGDIR%"

set LOGDATE=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
set LOGTIME=%TIME:~0,2%%TIME:~3,2%
set LOGTIME=%LOGTIME: =0%
set LOGFILE=%LOGDIR%\perf_%LOGDATE%_%LOGTIME%00.csv

:: 55分間(3300秒)を60秒間隔で記録
typeperf ^
  "\Processor(_Total)\%% Processor Time" ^
  "\Memory\Available MBytes" ^
  "\PhysicalDisk(_Total)\%% Disk Time" ^
  "\Network Interface(*)\Bytes Total/sec" ^
  -si 60 -sc 55 ^
  -o "%LOGFILE%" >nul 2>&1

echo [%DATE% %TIME%] 記録完了: %LOGFILE% >> "%LOGDIR%\record.log"

endlocal

管理者権限の自動取得についてはバッチで管理者権限を自動取得する完全ガイドを参考にしてください。

実践的な活用パターン

パターン①:高負荷処理の前後でシステム状態を記録する

バッチで重い処理(大量ファイルコピー、データベース更新など)を実行する前後でパフォーマンスを記録し、処理がシステムに与える影響を可視化します。

heavy_task_with_perf.bat
@echo off
setlocal enabledelayedexpansion

:: 処理前のスナップショット
echo === 処理前 [%DATE% %TIME%] ===
for /f "tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 1 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do echo   CPU: %%B%%
)
for /f "tokens=2 delims=," %%A in ('typeperf "\\Memory\\Available MBytes" -sc 1 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do echo   空きメモリ: %%B MB
)

:: --- ここに重い処理を書く ---
echo 処理中...
rem xcopy /e /q "\\server\large_share" "D:\backup\" >nul 2>&1

:: 処理後のスナップショット
echo === 処理後 [%DATE% %TIME%] ===
for /f "tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 1 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do echo   CPU: %%B%%
)

echo 完了
endlocal

パターン②:夜間バッチの実行前チェック

夜間の重要なバッチを実行する前に、リソースに問題がないか確認します。問題があればバッチを中断して管理者に通知します。

pre_batch_check.bat
@echo off
setlocal enabledelayedexpansion

echo [%DATE% %TIME%] 夜間バッチ実行前チェック開始

:: CPU使用率チェック(直近の値ではなく3回平均)
set CPU_SUM=0
for /f "skip=2 tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 3 -si 3 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do set /a CPU_SUM+=%%B
)
set /a CPU_AVG=CPU_SUM/3

:: 空きメモリチェック
for /f "tokens=2 delims=," %%A in ('typeperf "\\Memory\\Available MBytes" -sc 1 -f CSV 2^>nul') do (
    set "MEM_RAW=%%~A"
)
set "MEM_RAW=!MEM_RAW:"=!"
for /f "delims=." %%B in ("!MEM_RAW!") do set "MEM_MB=%%B"

:: ディスク空き容量チェック
for /f "tokens=2 delims=," %%A in ('typeperf "\\LogicalDisk(C:)\\%% Free Space" -sc 1 -f CSV 2^>nul') do (
    set "DFREE_RAW=%%~A"
)
set "DFREE_RAW=!DFREE_RAW:"=!"
for /f "delims=." %%B in ("!DFREE_RAW!") do set "DFREE=%%B"

echo CPU平均使用率: !CPU_AVG!%%
echo 空きメモリ:    !MEM_MB! MB
echo Cドライブ空き: !DFREE!%%

set NG=0
if !CPU_AVG! GEQ 60 ( echo [NG] CPU使用率が高すぎます & set NG=1 )
if !MEM_MB! LSS 1024 ( echo [NG] 空きメモリが不足しています & set NG=1 )
if !DFREE! LSS 15 ( echo [NG] ディスク空き容量が不足しています & set NG=1 )

if !NG! EQU 1 (
    echo [中断] リソース不足のためバッチを中断します
    exit /b 1
) else (
    echo [OK] リソースに問題ありません。バッチを続行します
)

endlocal

パターン③:アプリケーション起動中のメモリ変化を記録する

アプリケーション起動・終了時のメモリ使用量変化を記録することで、メモリリークの検出に活用できます。

process_perf_watch.bat
@echo off
setlocal

:: 対象プロセスのEXE名(実際の名前に合わせて変更)
set TARGET_EXE=myapp.exe

:: パフォーマンス記録をバックグラウンドで開始
start /b typeperf ^
  "\Processor(_Total)\%% Processor Time" ^
  "\Memory\Available MBytes" ^
  -si 5 -sc 360 ^
  -o "process_perf.csv" >nul 2>&1

:: メインプロセスを起動
echo [%TIME%] %TARGET_EXE% 起動
start /wait "" "%TARGET_EXE%"

echo [%TIME%] %TARGET_EXE% 終了
echo パフォーマンスログ: process_perf.csv

endlocal

プロセスの監視・検知についてはプロセスを監視して異常終了を検知する完全ガイドも参考にしてください。

パターン④:複数PCのパフォーマンスを一括確認する

typeperfのカウンターパスに \\PCName\ を付けることで、リモートPCのパフォーマンスも取得できます。ネットワーク内の複数台を一括チェックするスクリプトです。

multi_pc_check.bat
@echo off
setlocal enabledelayedexpansion

:: 監視対象PCのリスト(スペース区切りで記述)
set PC_LIST=PC001 PC002 PC003 SERVER01

set LOGFILE=multi_check_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log
echo === 複数PC一括チェック [%DATE% %TIME%] === > "%LOGFILE%"

for %%P in (%PC_LIST%) do (
    echo --- %%P --- >> "%LOGFILE%"

    :: リモートPCのCPU使用率を取得
    for /f "tokens=2 delims=," %%A in ('typeperf "\\\\%%P\\Processor(_Total)\\%% Processor Time" -sc 1 -f CSV 2^>nul') do (
        set "CPU_RAW=%%~A"
    )
    if defined CPU_RAW (
        set "CPU_RAW=!CPU_RAW:"=!"
        for /f "delims=." %%B in ("!CPU_RAW!") do (
            echo   CPU: %%B%% >> "%LOGFILE%"
            echo %%P  CPU: %%B%%
        )
    ) else (
        echo   [接続失敗] >> "%LOGFILE%"
        echo %%P  [接続失敗]
    )
    set "CPU_RAW="
)

echo.
echo ログ保存先: %LOGFILE%

endlocal

リモートPCへの接続に必要な設定
リモートPCのパフォーマンスカウンターを取得するには、対象PCで「リモートレジストリ」サービスが起動していること、Windowsファイアウォールでパフォーマンスモニターの通信が許可されていること、および適切なアクセス権限が必要です。ドメイン環境では管理者権限で実行することで多くの場合解決します。

パターン⑤:TypeperfのCSVデータをバッチで後集計する

記録済みのCSVファイルから最大値・最小値・平均値を集計するバッチスクリプトです。障害発生後の事後分析や定期レポート作成に使えます。

analyze_perf_csv.bat
@echo off
setlocal enabledelayedexpansion

set CSVFILE=%1
if "%CSVFILE%"=="" (
    echo 使い方: %~nx0 [CSVファイルパス]
    exit /b 1
)

if not exist "%CSVFILE%" (
    echo [エラー] ファイルが見つかりません: %CSVFILE%
    exit /b 1
)

set COUNT=0
set SUM=0
set MAX=0
set MIN=999

:: ヘッダー行をスキップしてデータ行を処理
for /f "skip=1 tokens=2 delims=," %%A in (%CSVFILE%) do (
    set "VAL=%%~A"
    set "VAL=!VAL:"=!"
    for /f "delims=." %%B in ("!VAL!") do (
        set /a COUNT+=1
        set /a SUM+=%%B
        if %%B GTR !MAX! set MAX=%%B
        if %%B LSS !MIN! set MIN=%%B
    )
)

if !COUNT! GTR 0 (
    set /a AVG=SUM/COUNT
    echo ファイル: %CSVFILE%
    echo サンプル数: !COUNT!
    echo 平均値: !AVG!%%
    echo 最大値: !MAX!%%
    echo 最小値: !MIN!%%
) else (
    echo [エラー] データを読み取れませんでした
)

endlocal

このスクリプトはCSVの2列目(最初のカウンター値)を集計します。複数カウンターのCSVを分析する場合は tokens= の番号を変えてください。より高度な分析には、出力したCSVをExcelやPowerShellで処理するのも有効です。

PowerShellと連携して分析・可視化する

typeperfでCSVに記録したデータは、PowerShellと組み合わせることでより高度な分析ができます。バッチで記録してPowerShellで集計するという役割分担が実践的です。

typeperfのCSVをPowerShellで集計する

analyze_with_powershell.bat
@echo off
setlocal

set CSVFILE=perf_20250415.csv

:: PowerShellでCSVを集計
powershell -NoProfile -Command "^
  $data = Import-Csv -Path '%CSVFILE%' -Encoding UTF8; ^
  $cpuCol = $data | Select-Object -ExpandProperty '\\CPU\Processor(_Total)\%% Processor Time' 2>$null; ^
  if ($cpuCol) { ^
    $vals = $cpuCol | Where-Object { $_ -ne ''} | ForEach-Object { [double]$_ }; ^
    '平均CPU: ' + [math]::Round(($vals | Measure-Object -Average).Average, 1) + '%%'; ^
    '最大CPU: ' + [math]::Round(($vals | Measure-Object -Maximum).Maximum, 1) + '%%' ^
  }"

endlocal

バッチからGet-Counterを呼び出してリアルタイム取得する

typeperfで値が取れない場合のフォールバックとして、PowerShellの Get-Counter を使う方法も覚えておくと便利です。

get_counter_fallback.bat
@echo off
setlocal

:: まずtypeperfで試みる
set CPU_INT=
for /f "tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 1 -f CSV 2^>nul') do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do set CPU_INT=%%B
)

:: typeperfで取得できなかった場合はPowerShellを使う
if not defined CPU_INT (
    echo [INFO] typeperfが失敗したためPowerShellを使用します
    for /f %%A in ('powershell -NoProfile -Command "(Get-Counter '\Processor(_Total)\%% Processor Time').CounterSamples.CookedValue | ForEach-Object { [int]$_ }"') do (
        set CPU_INT=%%A
    )
)

echo CPU使用率: %CPU_INT%%%

endlocal

typeperfでよく発生するエラーと対処法

エラー①:カウンターが見つからない

エラーメッセージ
Error: No valid counters.

原因:カウンターパスの綴りが間違っているか、そのカウンターがシステムに存在しない。
対処:typeperf -q で利用可能なカウンターを確認してください。

カウンター確認コマンド
:: 利用可能なすべてのカウンターを確認
typeperf -q

:: 特定カテゴリのカウンターだけ確認
typeperf -q "Processor"
typeperf -q "Memory"
typeperf -q "PhysicalDisk"
typeperf -q "Network Interface"

エラー②:日本語環境でカウンターが動かない

日本語版Windowsでは、一部のカウンターが日本語名でしか登録されていない場合があります。

日本語カウンターの例
:: 日本語環境では日本語表記でも動作する
typeperf "\プロセッサ(_Total)\%% Processor Time" -sc 1

:: 英語名で動かない場合は -q で現在の名前を確認
typeperf -q | findstr /i "Processor"

エラー③:NIC名にスペースや特殊文字が含まれる

NIC名に [ ] などが含まれる場合、for /f での解析が複雑になります。その場合はtypeperfの -o オプションでCSVに出力してから解析する方が安全です。

NIC特殊文字対処例
@echo off
setlocal enabledelayedexpansion

:: まずCSVファイルに出力
typeperf "\Network Interface(*)\Bytes Total/sec" -sc 1 -o net_tmp.csv >nul 2>&1

:: CSVから値を読み取る
for /f "skip=1 tokens=2 delims=," %%A in (net_tmp.csv) do (
    set "VAL=%%~A"
    echo 受信合計: !VAL! bytes/sec
)

del /q net_tmp.csv 2>nul
endlocal

エラー④:値が空またはゼロになる

typeperf の初回サンプルは正しい値が取得できないことがあります(カウンターの初期化に時間がかかるため)。skip=2 で1行目のデータをスキップするか、-sc 2 で2回サンプルして2回目の値を使うと安定します。

2回目の値を使う例
@echo off
setlocal enabledelayedexpansion

:: 2回サンプルして2回目だけ取得(skip=2 でヘッダーと1回目をスキップ)
for /f "skip=2 tokens=2 delims=," %%A in ('typeperf "\\Processor(_Total)\\%% Processor Time" -sc 2 -si 1 -f CSV 2^>nul') do (
    set "CPU_RAW=%%~A"
)
set "CPU_RAW=!CPU_RAW:"=!"
for /f "delims=." %%B in ("!CPU_RAW!") do set "CPU=%%B"
echo CPU使用率(安定値): !CPU!%%

endlocal

エラー⑤:管理者権限がないと一部カウンターが取得できない

物理ディスクのカウンターなど、一部は管理者権限が必要です。タスクスケジューラ登録時は /ru SYSTEM /rl HIGHEST で高権限実行にするか、事前に権限チェックを入れましょう。

権限チェック付き実行
@echo off
net session >nul 2>&1
if errorlevel 1 (
    echo [エラー] このスクリプトは管理者権限で実行してください
    exit /b 1
)
:: 以降に監視処理を記述

エラー⑥:バッチの %% 記号がコマンドプロンプトと異なる

バッチファイル内では %%% と書きますが、コマンドプロンプトから直接入力する場合は % 1つです。バッチファイルで試してうまくいかないとき、コマンドプロンプトで動作確認する際はこの違いに注意してください。

コマンドプロンプトで直接実行する場合
:: コマンドプロンプト上では %% ではなく % を1つ使う
typeperf "\Processor(_Total)\% Processor Time" -sc 1
バッチファイル内で記述する場合
:: バッチファイル内では %% と2つ書く
typeperf "\Processor(_Total)\%% Processor Time" -sc 1

エラー⑦:for /f での for ループ変数と typeperf の出力が噛み合わない

typeperfの出力には改行コードや空行が含まれる場合があり、for /f が意図通りに動かないことがあります。まずは一時ファイルに出力してから読み込む方法を試してみてください。

一時ファイル経由の安全な取得
@echo off
setlocal enabledelayedexpansion

set TMPFILE=%TEMP%\perf_tmp.csv

:: 一時ファイルに出力
typeperf "\Processor(_Total)\%% Processor Time" -sc 1 -o "%TMPFILE%" >nul 2>&1

:: 一時ファイルから読み込み
for /f "skip=1 tokens=2 delims=," %%A in ("%TMPFILE%") do (
    set "V=%%~A"
    set "V=!V:"=!"
    for /f "delims=." %%B in ("!V!") do set CPU=%%B
)

del /q "%TMPFILE%" 2>nul

echo CPU使用率: !CPU!%%

endlocal

typeperf利用時の注意事項

注意点 詳細
初回サンプルの精度 最初の1サンプルは「前回との差分計算」が未完了のため0や異常値になることがある。-sc 2 で2回取得し、2回目を使うとよい。
カウンター名のOS差異 Windows 10/11と2019/2022 Serverでカウンター名が異なる場合がある。本番適用前に対象環境で typeperf -q を確認すること。
ディスクカウンターの有効化 物理ディスクのカウンターは diskperf -y コマンドで有効化が必要な場合がある。Windows 10以降はデフォルトで有効だが、一部のサーバーOSでは無効になっている。
パフォーマンスオーバーヘッド typeperf自体の監視オーバーヘッドは軽微だが、非常に短い間隔(1秒未満)での呼び出しはループと組み合わせると無視できないCPU消費になる。
長時間のCSV記録 長期間記録するとCSVファイルが大きくなる。月次クリーンアップとセットで運用すること。30秒間隔で6カウンターを1日記録した場合、1日あたり約0.5MBが目安。
仮想環境での注意 Hyper-VゲストVMやVMware上では物理ディスクカウンターが仮想ディスクの値になる。ホストとゲストの数値を混同しないよう注意。

wmic・PowerShellとの使い分けまとめ

用途 推奨ツール 理由
CPU/ディスクのリアルタイム使用率 typeperf パフォーマンスカウンターを直接取得。継続監視・CSV記録に最適
総メモリ量・CPU種類などの静的情報 wmic WMIクラスで詳細な構成情報を取得できる
プロセス別のCPU/メモリ使用量 wmic または PowerShell typeperfはシステム全体のみ。プロセス別にはwmic process getが便利
複数PC一括監視 typeperf(カウンターパスに\\PC名\指定)またはPowerShell typeperfはリモートカウンターパスに対応。PowerShellはより柔軟
バッチファイルからの簡単な呼び出し typeperf 外部モジュール不要。for /f で値を取り出しやすい
CSV/グラフ形式での詳細レポート PowerShell Export-Csv 柔軟なフォーマット指定が可能
ネットワーク帯域利用率の計算 typeperf Bytes/sec と Current Bandwidth を組み合わせて計算できる

よくある質問

Qtypeperfで取得した値が常に0や負の値になります。
A初回サンプルは0になることがよくあります。-sc 2 で2回サンプリングし、skip=2 で2回目の値を取得してください。また、ディスクカウンターは diskperf -y が必要な場合があります。
Qカウンターパスが分からない場合はどうすればいいですか?
Atypeperf -q で全カウンターを表示できます。多すぎる場合は typeperf -q "Memory" | more のようにカテゴリで絞り込むか、パフォーマンスモニター(perfmon)のGUIでカウンターを追加してカウンターパスを確認するのが確実です。
Qfor /fでtypeperfの値を取り出せない場合はどうすればいいですか?
Aまず typeperf ... -sc 1 を直接実行して出力を確認してください。NIC名にカンマが含まれる場合は delims=, での解析が崩れます。その場合は -o tmp.csv で一度ファイルに出力してから読み込む方法を使ってください。
QtypeperfはリモートPCのパフォーマンスを取得できますか?
A可能です。カウンターパスの先頭に \\PCName\ を付けると、ネットワーク越しにリモートPCのカウンターを取得できます(ファイアウォールの許可とリモートレジストリサービスの起動が必要)。ただし複数PCの一括監視にはPowerShellのほうが扱いやすい場合もあります。
Qタスクスケジューラから実行するとtypeperfが動かない場合があります。
Aディスクや物理カウンターは管理者権限が必要です。タスク登録時に /ru SYSTEM /rl HIGHEST を指定してください。また、cd /d "%~dp0" でスクリプトのディレクトリに移動する処理を先頭に入れると、作業ディレクトリ問題を防げます。
QCPU使用率が100%近くを示しているのに実際はそうでない気がします。
Aプロセッサのインスタンスが _Total と個別コア(0, 1, 2…)の2種類あります。_Total が全コアの平均です。仮想化環境(Hyper-VゲストVM・VMware)では仮想CPUの値になる点も注意が必要です。また、パフォーマンスカウンターのリフレッシュには1〜2秒かかるため、瞬間的なスパイクは検出できないことがあります。
Q長期間の記録でCSVファイルが大きくなりすぎます。
A日次・週次でログファイルを分割する設計にするか、不要なカウンターを減らしてください。30秒間隔で6カウンターを1日記録した場合、1日あたり約0.5MBが目安です。自動削除にはログローテーションを組み合わせてください。
QWindowsのバージョンによって動作が違うことはありますか?
AWindows 10/11と2019/2022 Serverでは基本的な動作は同じですが、カウンター名が一部異なる場合があります。特に仮想化環境(Hyper-V, VMware)では物理ディスクカウンターが正確でないことがあります。本番適用前に対象OSで動作確認することをおすすめします。
Qtypeperfとperfmonは何が違いますか?
Aperfmon(パフォーマンスモニター)はGUIベースのツールで、グラフ表示やデータコレクターセットの管理ができます。typeperfはperfmonのコマンドライン版で、バッチファイルやスクリプトからパフォーマンスカウンターを取得するのに適しています。長期的な記録にはperfmonのデータコレクターセット機能、バッチでの一時的な取得にはtypeperfが向いています。

まとめ

typeperfコマンドを使うと、追加インストールなしでCPU・メモリ・ディスク・ネットワークのパフォーマンス情報をバッチから取得・記録できます。

やりたいこと コマンド例
CPU使用率を1回取得 typeperf "\Processor(_Total)\% Processor Time" -sc 1
10秒間隔で1時間CSVに記録 typeperf "..." -si 10 -sc 360 -o log.csv
カウンター名を調べる typeperf -q "Memory"
複数カウンターをまとめて記録 typeperf "CPU..." "MEM..." -si 30 -o log.csv
カウンターリストファイルを使う typeperf -cf counters.txt -si 60 -o log.csv
ディスクカウンターを有効化 diskperf -y(管理者権限+再起動が必要)
リモートPCのCPUを取得 typeperf "\\PCName\Processor(_Total)\% Processor Time" -sc 1

監視スクリプトを組み合わせることで、人手ゼロの自動ヘルスチェックシステムが構築できます。まずは typeperf -q でどんなカウンターが使えるか確認するところから始めてみてください。