VBScriptを「ブラックボックス」にしない:例外発生時のフォレンジック・キャプチャ実装論
多くの現場でVBScriptは「レガシーな負債」と揶揄される。だが、それはVBScriptが悪いのではない。VBScriptが提供するWSH(Windows Script Host)という極めて軽量な実行環境を、正しく制御できていないエンジニアの怠慢だ。
今日は、本番環境で「なぜか止まる」VBScriptに対し、事後検証を不可能にしないための「例外発生時・全画面自動キャプチャ・モジュール」を伝授する。
なぜ、VBScriptでキャプチャを実装するのか
VBScript単体には画面をキャプチャするAPIは存在しない。しかし、我々には`WScript.Shell`と、背後に控える強力な.NET Frameworkがある。
エラーログだけでは「何が起きたか」は推測できても、「画面上で何が起きていたか」までは分からない。このモジュールを組み込むことで、スクリプトが死ぬ瞬間のデスクトップを画像として残す。これは障害調査における「ブラックボックス・レコーダー」となる。
—
実装の核:PowerShell経由でのGDI+呼び出し
VBScriptから直接Win32 APIを叩くのは非効率かつ不安定だ。ここでは、.NETの`System.Drawing`を呼び出すワンライナーのPowerShellを、`WScript.Shell`で非同期実行する。
【実装コード】ErrorSnapshot.vbs
Option Explicit
‘ メイン処理のサンプル
Sub Main()
On Error Resume Next
‘ ここでわざとエラーを起こすテスト
Dim x: x = 1 / 0
If Err.Number <> 0 Then
‘ エラー発生時にキャプチャ実行
CaptureDesktop “C:\Logs\Error_” & Replace(Now(), “:”, “-“) & “.png”
WScript.Echo “致命的エラーを検知:画面キャプチャを保存しました。”
Err.Clear
End If
End Sub
‘ 障害発生時のスナップショット・キャプチャ
Sub CaptureDesktop(filePath)
Dim shell, psCmd
Set shell = CreateObject(“WScript.Shell”)
‘ .NETのSystem.Drawingを使用して画面をキャプチャするPowerShellコマンド
‘ 外部プロセスとして実行し、VBScript側のメモリを汚染しない
psCmd = “powershell -Command “”Add-Type -AssemblyName System.Drawing; ” & _
“$bmp = New-Object System.Drawing.Bitmap([System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width, [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height); ” & _
“$graphics = [System.Drawing.Graphics]::FromImage($bmp); ” & _
“$graphics.CopyFromScreen(0, 0, 0, 0, $bmp.Size); ” & _
“$bmp.Save(‘” & filePath & “‘, [System.Drawing.Imaging.ImageFormat]::Png); ” & _
“$bmp.Dispose(); $graphics.Dispose();”””
‘ 0: ウィンドウ非表示, False: 終了を待機しない(高速化)
shell.Run psCmd, 0, False
‘ オブジェクトの明示的解放(メモリ管理の鉄則)
Set shell = Nothing
End Sub
Call Main()
—
シニアエンジニアが意識すべき「極限の知見」
このコードをただコピペするだけでは素人だ。真に理解すべきは、以下の3点である。
1. プロセス分離による耐障害性の確保
`WScript.Shell.Run`でPowerShellを呼び出す際、あえて別プロセスで実行している。もしキャプチャ処理自体が重くてクラッシュしても、メインのVBScript側が巻き込まれることはない。これがシステム連携における「疎結合」の極意だ。
2. メモリ・リークの徹底排除
VBScriptのエンジンは、COMオブジェクトの参照カウントを管理する。`Set object = Nothing`を怠ると、大量のバッチ処理の中でメモリが徐々に食いつぶされる。特にWSHのようなロングランが想定される環境では、変数はスコープを最小化し、不要になった瞬間に解放せよ。
3. 実行ポリシーと権限の考慮
PowerShellを呼び出す際、サーバー環境では「実行ポリシー(ExecutionPolicy)」が障壁になることがある。`powershell -ExecutionPolicy Bypass`を付与することで、セキュリティ要件をクリアしつつ、緊急時のデバッグを確実に実行させるテクニックが求められる。
結びに代えて
「スクリプトが止まった。原因不明だ。ログにも残っていない」
このような言葉を吐くエンジニアは、二流である。システムは常に壊れるものだ。重要なのは、「壊れた瞬間をどのように記録に残すか」という設計思想である。
VBScriptという古き良き言語は、今なおWindowsの心臓部で静かに動いている。この「ブラックボックス・レコーダー」を実装し、あなたのシステムの保守運用レベルを一段階引き上げろ。それが、伝説的なアーキテクトへの第一歩だ。
