VBScriptで「待機」の概念を覆せ。WMI非同期イベント監視によるスマートな自動化術
こんにちは。自動化の現場でVBScriptを使い倒しているエンジニアです。
多くの人がVBScriptで「ファイルが作成されたか監視したい」「プロセスが起動したか検知したい」と考えたとき、真っ先に思いつくのが「ループさせてSleepで待機する(ポーリング)」という手法でしょう。
‘ 【アンチパターン】これではCPUを無駄に浪費し、即応性も低い
Do
If FSO.FileExists(“C:\Target.txt”) Then Exit Do
WScript.Sleep 1000 ‘ 1秒おきにチェック
Loop
これ、実は非常に「素人臭い」やり方です。CPUリソースを食いつぶす上に、タイミングによっては検知にラグが生じます。
今日は、Windowsの心臓部であるWMI (Windows Management Instrumentation) の「非同期クエリ」を使い、OSに「何かが起きたら教えてくれ」と伝える、真にスマートな監視手法を伝授します。
—
1. WMIイベント駆動の考え方
通常のスクリプトは「上から下へ」流れて終了しますが、イベント駆動は「待機し、何かが起きたら割り込む」という動きをします。
- ポーリング(悪い例): 「来た? まだ? 来た? まだ?」と聞き続ける(CPU負荷:高)
- イベント駆動(今回の手法): 「何かが起きたら呼んでくれ」とOSに登録し、自分は眠る(CPU負荷:ほぼゼロ)
これを実現するのが `SWbemServices.ExecNotificationQuery` です。
—
2. 実践:プロセス起動をリアルタイムに検知する
まずは、特定のプロセス(例:`notepad.exe`)が起動した瞬間に検知するスクリプトです。
‘ — プロセス監視スクリプト —
Dim objWMIService, colMonitoredEvents
‘ WMIに接続
Set objWMIService = GetObject(“winmgmts:\\.\root\cimv2”)
‘ イベントクエリを定義 (Win32_ProcessStartTrace はプロセス開始を監視)
‘ 5秒間隔でチェックする設定 (Within 5)
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
(“SELECT FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA ‘Win32_Process'”)
WScript.Echo “監視を開始しました。メモ帳を起動してみてください…”
Do
‘ NextEventメソッドでイベント発生を待機(ここで処理が止まり、CPUを消費しない)
Dim objLatestEvent
Set objLatestEvent = colMonitoredEvents.NextEvent
‘ イベント発生時の処理
Dim procName
procName = objLatestEvent.TargetInstance.Name
WScript.Echo “★検知!プロセスが起動しました: ” & procName
‘ 特定のプロセスなら何かアクションを起こす
If procName = “notepad.exe” Then
WScript.Echo “-> メモ帳が起動されたので、管理者へ通知します。”
End If
Loop
このコードの要点
1. `ExecNotificationQuery`: OSに対して監視の契約を結びます。
2. `WITHIN 5`: 5秒以内に検知するという「解像度」を指定します。これがないとWMIは正常に動作しません。
3. `NextEvent`: これが重要です。ここでスクリプトはOSからの通知を静かに待ちます。イベントが飛んでくるまでスクリプトは完全に休止状態になります。
—
3. 陥りやすいエラーと回避策
初心者が必ずぶつかる壁がいくつかあります。
Q1. スクリプトが途中で止まってしまう
A. WMIのクエリ発行時に権限が必要な場合があります。必ずスクリプトを「管理者として実行」してください。
Q2. `__InstanceCreationEvent` って何?
A. WMIには「クラスのインスタンスが生成された瞬間に飛ばすイベント」が用意されています。ファイル監視の場合は `CIM_DataFile` をターゲットにすることで、ファイル作成イベントを捉えることも可能です。
Q3. 終了させるには?
A. このスクリプトは無限ループです。タスクマネージャーから `wscript.exe` を終了させるか、スクリプト内に `If` 文で特定のキー押下や条件分岐による `WScript.Quit` を設けてください。
—
4. なぜ今、VBScriptを学ぶのか?
「今はPowerShellの時代だ」と言う人もいるでしょう。しかし、VBScriptはWindowsに標準で組み込まれており、追加インストールや実行ポリシーの変更なしでどこでも動くという圧倒的な「即時性」があります。
現場で「今すぐこのサーバーに小さな監視ツールを置いてくれ」と言われたとき、PowerShellの複雑なセキュリティ設定に悩むより、この数行のVBScriptをメモ帳で書いて渡す方が、エンジニアとしての価値が高い場面は山ほどあります。
—
最後に
今回紹介した「非同期イベント監視」は、ただの便利なテクニックではありません。「システムに負荷をかけない」というアーキテクトとしての哲学です。
マクロの記録で生成されたゴミコードを卒業し、OSのイベントを直接叩く――。これこそが、皆さんが「ただの作業者」から「自動化エンジニア」へ進化するための第一歩です。
何か不明点があれば、またいつでも聞いてください。応援していますよ。
