【実務・中級編】【ネットワークルート自動切り替え】WMI (Win32_IP4RouteTable) を操作したマルチホーム環境の優先メトリック変更 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptでネットワークを制御する:WMIを用いた動的メトリック変更の極意

現場で「有線と無線が切り替わらない」「特定の通信だけ遅延する」という課題に直面したことはないか? Windowsのネットワークスタックは優秀だが、マルチホーム環境においてはしばしば判断を誤る。

今回は、WMI(Windows Management Instrumentation)の深淵を覗き、`Win32_IP4RouteTable` を直接操作してネットワークの優先順位を物理的にねじ伏せる、極めて実用的な自動化手法を伝授する。

1. なぜWMI操作なのか:ルーティング制御の本質

OSのルーティングテーブルは、単なる優先順位のリストではない。各経路には「メトリック値」が割り当てられており、値が小さいほど「近道」と見なされる。

多くの現場で行われる「アダプター設定からのメトリック手動変更」は、数台なら良い。だが、数百台規模の環境でこれをやるのは、エンジニアとしての敗北だ。我々はスクリプトでこれを制御し、環境の変化に合わせて動的にルートを再定義する。

避けるべき非効率なアプローチ

  • `route change` コマンドの多用: 外部プロセスを何度も叩くのは、プロセス生成のオーバーヘッドが大きく、不安定だ。
  • WScript.Shellの過信: ネットワークインターフェースのインデックス(IfIndex)は再起動や接続状況で変動する。固定値でハードコーディングするのは愚の骨頂である。

2. プロダクションコード:動的メトリック変更スクリプト

このコードは、指定したネットワークインターフェースのメトリック値を安全に更新する設計だ。

‘ — ネットワークルート自動切り替えエンジンのコア —
Option Explicit

Const WMI_NAMESPACE = “root\cimv2”
Const TARGET_DEST = “0.0.0.0” ‘ デフォルトゲートウェイを対象とする

‘ 実行例: 有線LAN(InterfaceIndex 12)のメトリックを10に変更する
UpdateRouteMetric 12, 10

Sub UpdateRouteMetric(ifIndex, newMetric)
Dim objWMIService, colRoutes, objRoute
Dim strQuery

Set objWMIService = GetObject(“winmgmts:\\.\” & WMI_NAMESPACE)

‘ 指定したインターフェースかつデフォルトルートを特定
strQuery = “SELECT FROM Win32_IP4RouteTable WHERE Destination='” & TARGET_DEST & “‘ AND InterfaceIndex=” & ifIndex
Set colRoutes = objWMIService.ExecQuery(strQuery)

If colRoutes.Count = 0 Then
WScript.Echo “対象ルートが見つかりません。Indexが正しいか確認してください。”
Exit Sub
End If

For Each objRoute In colRoutes
‘ メトリックの更新(WMIのメソッドではなく、Setメソッドでプロパティを更新)
‘ 注意: Win32_IP4RouteTable は読み取り専用属性が多い場合、
‘ 必要に応じて SetGateWay メソッドや Network アダプター側の設定変更を併用すること
WScript.Echo “Routing: ” & objRoute.Destination & ” -> Metric: ” & newMetric

‘ 実際の実装では、ここで netsh を併用する設計が最も堅牢
‘ WMIは情報の取得には最強だが、書き込みに関してはOSの権限保護が強固であるため
Dim shell: Set shell = CreateObject(“WScript.Shell”)
shell.Run “netsh int ip set interface ” & ifIndex & ” metric=” & newMetric, 0, True
Next
End Sub

3. 開発現場における「絶対守るべき鉄則」

① 権限の壁を理解する

WMI経由であれ `netsh` であれ、ネットワーク設定の変更は管理者権限(Elevated Privilege)が必須だ。VBScriptをタスクスケジューラで走らせる際は、「最上位の権限で実行する」にチェックを入れることを忘れるな。これを怠ると、スクリプトは沈黙したまま何も起きない。

② IfIndexの動的解決

ハードコーディングは諸悪の根源だ。必ず `Win32_NetworkAdapter` クラスを事前にクエリし、`NetConnectionID`(”イーサネット”や”Wi-Fi”といった名称)から現在の `InterfaceIndex` を動的に取得するロジックを前段に置け。

③ ログと排他制御

ファイルやDBに状態を書き込む際は、必ずエラーハンドリングを入れること。

On Error Resume Next
‘ 処理…
If Err.Number <> 0 Then
‘ ログファイルへ書き出し
WriteLog “Critical Error: ” & Err.Description
End If
On Error GoTo 0

これがないスクリプトは、夜中に原因不明で停止し、翌朝のヘルプデスクを地獄に突き落とす。

4. 最後に:エンジニアとしての矜持

VBScriptは「古い」と言われることがある。だが、Windowsという巨大なOSの深部を、外部ライブラリなしで直接叩けるこの言語は、業務自動化のラストリゾートとして今なお最強だ。

今回紹介した手法をベースに、さらに「Pingによる死活監視」や「SSID情報の取得」を組み合わせれば、君の現場だけの「インテリジェントなネットワーク制御」が完成する。

自動化とは、ただ楽をすることではない。「人間が判断しなくても済む状況を、堅牢なコードで作り上げること」だ。自信を持って、コードを書き進めてほしい。

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