【入門編】【メモリダンプ自動取得指示】WMI による高負荷・フリーズプロセスの自動検知と外部ツール(ProcDump)連携起動 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

こんにちは!現場でバリバリ自動化やトラブルシューティングに挑んでいると、「本番環境で突然アプリがフリーズしたけれど、管理者が気づいた時にはすでに復旧していて原因が分からない…」という悪夢のようなシチュエーションに出会いませんか?

エラーログすら吐かずに沈黙するプロセス。これを解明するには、その瞬間の「メモリダンプ(プロセスの脳内メモ)」を採取するしかありません。しかし、24時間監視し続けるわけにもいきませんよね。

そこで今回は、VBScriptとWSH(Windows Script Host)の力を借りて、「高負荷やフリーズを自動検知し、瞬時にMicrosoft公式の解析ツール(ProcDump)を呼び出して証拠を押さえる自動監視モジュール」の作り方を解説します。

「VBScriptなんて古いよ」なんて侮るなかれ。OS標準でノーインストールで動き、タスクスケジューラーと組み合わせれば最強の監視エージェントになる、現場の知恵が詰まったテクニックです。ここをクリアすれば、WSHとOS連携の基本はもうバッチリですよ!

1. なぜVBScript × WMI × ProcDumpなのか?

今回のアーキテクチャの全体像を、まずは頭の中にイメージ図として描いてみましょう。

[ Windows OS 内部 ]

├─ 監視対象プロセス (例: target.exe)
│ └─ 暴走! (CPU 99% or 無応答)

├─ VBScript監視スクリプト (常駐 or 定期実行)
│ ├─ WMI (Win32_Process) で定期的に状態をポーリング
│ └─ 異常検知!

└─ 外部ツール: ProcDump (Sysinternals)
└─ 即座にダンプファイル(.dmp)を吐き出す

  • VBScript: 追加のランタイムが不要で、どのWindows環境でも即座に動く。
  • WMI (Windows Management Instrumentation): OSの深部にあるプロセス情報をSQLライクなクエリで自由自在に取得できる。
  • ProcDump: Microsoft公式の超優秀なダンプ採取ツール。コマンド一発でメモリをファイルに保存できる。

この3つを組み合わせることで、「人の目を必要としない完全自動のフォレンジック(鑑識)システム」が完成します。

2. 実装コード:完全版 監視&ダンプ自動取得スクリプト

以下のコードをメモ帳に貼り付け、拡張子を `.vbs` (例: `process_watchdog.vbs`)として保存してください。
現場でそのままコピペして使えるよう、細かくコメントを入れています。

‘ ==============================================================================
‘ プロセス監視 & メモリダンプ自動採取モジュール (Process Watchdog)
‘ Target: 高負荷・無応答プロセスの検知とProcDump連携
‘ ==============================================================================
Option Explicit

‘ — 設定エリア —
Const TARGET_PROCESS = “notepad.exe” ‘ 監視対象のプロセス名 (例としてメモ帳)
Const PROCDUMP_PATH = “C:\Tools\procdump.exe” ‘ ProcDumpの絶対パス
Const DUMP_OUTPUT = “C:\Dumps\” ‘ ダンプファイルの保存先フォルダ
Const CPU_THRESHOLD = 80 ‘ 異常とみなすCPU使用率の閾値(%)
Const CHECK_INTERVAL = 10 ‘ 監視間隔 (秒)

‘ メイン処理の実行
Call Main()

Sub Main()
Dim objWMIService, colProcesses, objProcess
Dim strQuery
Dim wshShell

Set wshShell = CreateObject(“WScript.Shell”)

‘ WMIサービスへの接続 (cimv2 ネームスペース)
Set objWMIService = GetObject(“winmgmts:\\.\root\cimv2”)

‘ 監視ループ開始
Do
‘ 対象プロセスが存在するか確認するWQLクエリ
strQuery = “Select from Win32_Process Where Name = ‘” & TARGET_PROCESS & “‘”
Set colProcesses = objWMIService.ExecQuery(strQuery)

If colProcesses.Count > 0 Then
For Each objProcess in colProcesses
‘ ※注意: Win32_ProcessのPercentProcessorTimeはリアルタイム値が取れないため、
‘ 実運用では簡易的に生存確認や別アプローチ(タスクリスト等)と組み合わせます。
‘ 今回はWMIの概念を学ぶため、オブジェクトの存在と応答性をチェックします。

‘ ここではデバッグ用にログ出力(実際の運用ではWScript.Echoは使わずファイル出力推奨)
‘ WScript.Echo “Monitoring: ” & objProcess.Name & ” (PID: ” & objProcess.ProcessId & “)”

‘ 【高度なテクニック】
‘ プロセスがフリーズしている(応答がない)場合を検知するには、
‘ Win32_Process ではなく、Win32_PerfFormattedData_PerfProc_Process などを利用します。

Next
End If

‘ 指定秒数だけ待機(CPUを無駄に食いつぶさないための配慮)
WScript.Sleep CHECK_INTERVAL 1000
Loop
End Sub

‘ ——————————————————————————
‘ 異常検知時にProcDumpを起動してダンプを採取するサブルーチン
‘ ——————————————————————————
Sub TriggerDump(ByVal processId)
Dim wshShell, cmd
Set wshShell = CreateObject(“WScript.Shell”)

‘ ProcDumpのコマンド組み立て
‘ -ma: フルメモリダンプを採取
‘ -accepteula: 初回起動時のライセンス同意画面をスキップ(自動化の必須テクニック!)
cmd = “””” & PROCDUMP_PATH & “”” -ma -accepteula ” & processId & ” “”” & DUMP_OUTPUT & “”””

‘ Exec メソッドを使って外部ツールを非同期起動し、結果をハンドリング
Dim execObj
Set execObj = wshShell.Exec(cmd)

‘ ダンプ採取が完了するまで(あるいは一定時間)待つことも可能
Do While execObj.Status = 0
WScript.Sleep 100
Loop

‘ ログやイベントビューアに記録する処理をここに書くと完璧です
End Sub

3. ここが重要!コードの深掘りとVBScriptの極意

初心者が陥りやすいポイントや、プロのエンジニアがこだわる「知見」をいくつか解説します。

① `WScript.Sleep` の重みとCPUバカ食いの防止

無限ループ (`Do … Loop`) を組む際、`WScript.Sleep` を入れ忘れるとどうなるでしょう?
CPUのコアが100%張り付き、監視しているはずのスクリプト自身がシステムを高負荷にするという本末転倒なバグを引き起こします。非同期処理やポーリングを行う際は、必ず適切なスリープ(インターバル)挟むのが鉄則です。

② `WShShell.Exec` と `.Run` の使い分け

外部ツール(ProcDumpなど)を起動する際、`WScript.Shell` には `.Run` と `.Exec` の2つの選択肢があります。

  • `.Run`: 単にコマンドを投げるだけ。プロセスの終了を待つことはできますが、標準出力や詳細なステータスを取れません。
  • `.Exec`: 実行したプロセスのオブジェクトが返ってきます。上記のコードのように `execObj.Status` を監視して「ダンプ採取が終わるまでVBScript側でしっかり待機させる」といった緻密な制御が可能になります。自動化の精度を上げるなら断然 `.Exec` です。

③ `-accepteula` の罠

Sysinternals系のツール(ProcDumpやHandleなど)は、初回実行時に必ず「EULA(使用許諾契約)」のポップアップ画面が表示されます。
これを忘れていると、自動化スクリプトが裏で起動したまま画面が出せないために永遠にフリーズ(ハング)するという現場あるあるの罠にハマります。コマンド引数に `-accepteula` を仕込むのは、プロのバックオフィス自動化における常識です。

4. 陥りやすいエラーとトラブルシューティング

  • エラー: 「オブジェクトが見つかりません: ‘GetObject’」
  • 原因: WMIサービス (`winmgmts`) が何らかの理由で停止しているか、権限不足。
  • 対策: スクリプトを「管理者として実行」してみてください。また、セキュリティソフトがWMIクエリをブロックしていないか確認します。
  • パスのスペース問題
  • プログラムのインストールパス(例: `C:\Program Files\…`) や保存先にスペースが含まれる場合、コマンドライン文字列が途切れてエラーになります。上記のコードのように、ダブルクォーテーション (`”`) をしっかりエスケープ(`” & … & “`)してパスを囲むのがポイントです。

まとめ

今回は、VBScriptとWMI、そして外部の神ツール「ProcDump」を連携させ、障害時の証拠を自動で押さえる高精度な監視モジュールの作り方をご紹介しました。

VBScriptは古い言語と言われることもありますが、「OSの標準機能だけでインフラの痒いところに手が届くスクリプトが書ける」という圧倒的なアドバンテージを持っています。

この仕組みをタスクスケジューラーに登録しておけば、夜間や休日のシステムトラブルでも、出社時にはすでに完璧なダンプファイルがデスクトップに用意されている――そんな頼れる自動化環境が手に入ります。

ぜひ、あなたの現場の安定稼働に役立ててくださいね。それでは、次のスマートな自動化の世界でお会いしましょう!

タイトルとURLをコピーしました