こんにちは!業務自動化の現場を駆け抜けてきたエンジニアの先輩です。
「マクロの記録」や「簡単なバッチファイル」から一歩進んで、本格的なWindows自動化の世界に足を踏み入れようとしているあなたへ。今日は、VBScriptとWSH(Windows Script Host)の底力を実感できる、とっておきの実用スクリプトをご紹介します。
テーマは 「WMIを使った複数拠点ネットワークのレイテンシ(応答速度)自動計測」 です。
「ネットワークの死活監視や応答速度を測りたい!」と思ったとき、多くの人は黒い画面(コマンドプロンプト)で `ping` コマンドを叩き、その文字出力を必死にパース(解析)しようとします。でも、出力のフォーマットはOSの言語設定やバージョンによって微妙に変わり、非常に泥臭いコードになりがちです。
そこで登場するのが WMI(Windows Management Instrumentation) の `Win32_PingStatus` クラスです。これを使えば、OSの奥深くから「構造化されたきれいなデータ」としてPing結果を受け取ることができます。
ここをクリアすれば、VBScriptの基礎だけでなく、Windowsの管理機構を自在に操る楽しさが一気に分かりますよ。さあ、一緒に扉を開けましょう!
—
なぜ `ping` コマンドではなく WMI なのか?
従来のバッチファイルや安易なスクリプトでは、以下のようなアプローチが取られていました。
[ping 192.168.1.1] ──> (文字出力) ──> [「バイト=32」という文字列を探して切り出す泥臭い処理]
これだと、英語環境では `Bytes=32`、日本語環境では `バイト=32` になり、スクリプトが簡単に破綻します。
一方、WMIを使うアプローチはこうです。
[WMI (Win32_PingStatus)] ──> (OSが内部でオブジェクト化) ──> [StatusCode, ResponseTime などのプロパティを直撃!]
OSがすでに解析してくれた「データ(オブジェクト)」をそのまま受け取るため、言語依存のエラーが起きず、極めて堅牢(ロバスト)な監視スクリプトが組めるのです。
—
【実践】複数拠点を一発監視するVBScriptコード
以下のコードをコピーして、メモ帳などのテキストエディタに貼り付け、拡張子を `.vbs` (例: `ping_checker.vbs`)として保存してください。
このスクリプトは、あらかじめ設定した複数のIPアドレス(本社、支店、クラウドゲートウェイなど)に対して順番にPingを飛ばし、結果をコンソール出力しつつ、デスクトップにCSVログとして綺麗に保存します。
‘ ==============================================================================
‘ スクリプト名: NetworkLatencyMonitor.vbs
‘ 概要: WMI (Win32_PingStatus) を用いた複数拠点ネットワークのレイテンシ自動計測
‘ 著者: チーフアーキテクト先輩
‘ ==============================================================================
Option Explicit
‘ エラーハンドリングの有効化(予期せぬネットワーク切断等でスクリプトが止まるのを防ぐ)
On Error Resume Next
Dim objWMIService, colPingResults, objPingResult
Dim strComputer, arrTargets, targetIP, logFilePath
Dim objFSO, objLogFile
Dim currentDateTime
‘ 1. 監視対象のIPアドレス / ホスト名リストを配列で定義
‘ ここをご自身の環境のルーターやサーバーのIPに書き換えてください
arrTargets = Array(“127.0.0.1”, “8.8.8.8”, “192.168.1.254”)
‘ 2. ログファイルの出力先設定(ユーザーのデスクトップに保存)
Dim objWshShell
Set objWshShell = CreateObject(“WScript.Shell”)
logFilePath = objWshShell.SpecialFolders(“Desktop”) & “\Network_Latency_Log.csv”
‘ 3. ファイルシステムオブジェクト(FSO)の生成とログヘッダーの書き込み
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
‘ ログファイルが存在しない場合は、CSVのヘッダー行を作成
If Not objFSO.FileExists(logFilePath) Then
Set objLogFile = objFSO.OpenTextFile(logFilePath, 2, True) ‘ 2 = ForWriting
objLogFile.WriteLine “Timestamp,TargetIP,StatusCode,ResponseTime(ms),ProtocolAddress”
objLogFile.Close
End If
‘ 追記モードでログファイルを開く (8 = ForAppending)
Set objLogFile = objFSO.OpenTextFile(logFilePath, 8, True)
‘ WMIサービスへの接続(ローカルコンピュータを対象とする)
strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
WScript.Echo “=== ネットワークレイテンシ計測を開始します ===”
‘ 4. ターゲット配列をループ処理
For Each targetIP in arrTargets
‘ 現在日時の取得
currentDateTime = Now()
‘ WMIクエリの実行(Win32_PingStatusクラスにターゲットを指定)
‘ ※ここでWMIが内部でICMPパケットを飛ばし、結果をオブジェクトとして回収します
Set colPingResults = objWMIService.ExecQuery _
(“Select From Win32_PingStatus Where Address = ‘” & targetIP & “‘”)
‘ 結果の解析
For Each objPingResult in colPingResults
‘ エラーチェック(WMIクエリ自体の失敗を防ぐ)
If Err.Number <> 0 Then
WScript.Echo “[ERROR] クエリ実行失敗: ” & targetIP & ” (” & Err.Description & “)”
Err.Clear
Else
‘ StatusCodeが 0 の場合は疎通成功
If Not IsNull(objPingResult.StatusCode) And objPingResult.StatusCode = 0 Then
WScript.Echo “[” & currentDateTime & “] 成功: ” & targetIP & _
” 応答時間: ” & objPingResult.ResponseTime & “ms”
‘ CSVログへ書き込み
objLogFile.WriteLine currentDateTime & “,” & targetIP & “,” & _
objPingResult.StatusCode & “,” & _
objPingResult.ResponseTime & “,” & _
objPingResult.ProtocolAddress
Else
‘ タイムアウトやルーティングエラーなど
WScript.Echo “[” & currentDateTime & “] 失敗/タイムアウト: ” & targetIP & _
” (StatusCode: ” & objPingResult.StatusCode & “)”
‘ 失敗時もログに残す
objLogFile.WriteLine currentDateTime & “,” & targetIP & “,” & _
objPingResult.StatusCode & “,N/A,” & targetIP
End If
End If
Next
‘ ネットワーク機器への過度な負荷を避けるため、1秒インターバルを挟む
WScript.Sleep 1000
Next
‘ 後片付け
objLogFile.Close
Set objLogFile = Nothing
Set objFSO = Nothing
Set objWMIService = Nothing
Set objWshShell = Nothing
WScript.Echo “=== 計測完了。ログはデスクトップに出力されました ===”
WScript.Quit
—
コードの核心:ここがVBScript & WMIの醍醐味!
初学者のうちにつまづきやすいポイントや、プロの現場で使われるテクニックをいくつか解説します。
1. `Option Explicit` はプロの証
スクリプトの先頭にある `Option Explicit`。「変数の宣言を強制する」というお作法です。これを書いておかないと、うっかりスペルミス(例: `targetIP` を `targatIP` と書くなど)をしたときに、VBScriptが勝手に新しい空の変数を作ってしまい、原因不明のバグに何時間も悩まされることになります。必ず書く癖をつけましょう。
2. WMIクエリのメカニズム
Set colPingResults = objWMIService.ExecQuery _
(“Select From Win32_PingStatus Where Address = ‘” & targetIP & “‘”)
SQL文に似た構文でWindowsの内部機能に問いかけています。この `Win32_PingStatus` は非常に優秀で、IPアドレスを指定してクエリを投げると、OSのネットワークスタックが実際にICMPエコー要求を送り、その結果をプロパティ(`StatusCode` や `ResponseTime` など)に詰めて返してくれます。
3. エラーハンドリングの作法 (`On Error Resume Next`)
ネットワーク監視の現場では、「一時的な回線断」「対象サーバーのシャットダウン」など、スクリプトの制御外のエラーが日常茶飯事です。
`On Error Resume Next` を宣言することで、エラーが発生してもスクリプトが途中で強制終了(クラッシュ)せず、`Err.Number` を使って優雅に対処できるようになります。
—
陥りやすい罠と現場の知恵
- ファイアウォール(Windows Defender等)の壁
計測先のサーバーやPCがWindows機の場合、標準設定では外部からのICMP(Ping)をブロックしていることがあります。スクリプトが「タイムアウト」になる場合は、まず宛先側のファイアウォール設定を確認してください。
- 実行権限の罠
WMI経由でのネットワーク操作は、基本的には一般権限で動作しますが、社内ドメインの厳格なセキュリティポリシーが敷かれている環境では、スクリプトを「管理者として実行」する必要がある場合があります。
—
おわりに
お疲れ様でした!ここまで理解できたら、もう単なる「VBScriptの初心者」ではありません。OSの管理機構(WMI)を叩き、構造化データを取り出し、ログファイルとして残すという、立派な「業務自動化エンジニア」のアーキテクチャを手に入れました。
このスクリプトをWindowsの「タスクスケジューラ」に登録すれば、1時間に1回、あるいは30分に1回、自動でオフィスのネットワーク健康診断をしてくれる強力な監視ロボットが完成します。
ここをクリアすれば、VBScriptの基本はバッチリです。ぜひ日々の業務やインフラ監視に役立ててみてくださいね。それでは、次の自動化の旅でお会いしましょう!
