ネットワークの「格」を制御せよ:WMIによるアダプタメトリック一括最適化の極意
現場のシステム管理において、最も不毛で、かつ最も頻発するトラブルの一つが「有線LANとWi-Fiの混在による経路不安定化」だ。OSの自動判定に任せれば、本来は低レイテンシであるべき有線が、Metric値の不整合でWi-Fiの裏側に隠れてしまう。
これを力技で解決する唯一にして最強の手段が、WMI(Windows Management Instrumentation)を用いた`Win32_NetworkAdapterConfiguration`への直接介入だ。VBScriptというレガシーな武器を用い、OSの挙動を意図的に捻じ曲げる、アーキテクトのための処方箋を授ける。
—
1. なぜMetric値の操作が必要なのか
Windowsのルーティングテーブルにおいて、通信経路の優先順位は「インターフェースメトリック」によって決定される。値が小さいほど優先される。
しかし、DHCP環境ではOSが勝手にこの値を決定し、時に有線(Ethernet)よりも無線(Wi-Fi)を優先させるという「ネットワークの逆転現象」が起きる。これを修正するには、管理者権限で実行されるWMI制御が不可欠だ。
2. 実践:ネットワーク優先度一括最適化スクリプト
以下のスクリプトは、単なるコードではない。オブジェクトのライフサイクルを制御し、メモリリークを許さない、実戦仕様のテンプレートだ。
‘ ————————————————————————-
‘ ネットワークアダプタ優先度設定スクリプト (PrioritySetter.vbs)
‘ 権限: 管理者権限(Run as Administrator)必須
‘ ————————————————————————-
Option Explicit
‘ メトリック値の定数定義
Const METRIC_ETHERNET = 10 ‘ 有線を最優先
Const METRIC_WIFI = 20 ‘ Wi-Fiをバックアップへ
Call SetNetworkMetrics()
Sub SetNetworkMetrics()
Dim objWMIService, colAdapters, objAdapter
Dim strQuery
‘ WMI接続: コンピュータ名”.”はローカルを指す
Set objWMIService = GetObject(“winmgmts:\\.\root\cimv2”)
‘ IPが有効なアダプタのみを抽出(IPEnabled = True)
strQuery = “SELECT FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True”
Set colAdapters = objWMIService.ExecQuery(strQuery)
For Each objAdapter In colAdapters
‘ 説明文からアダプタの種類を判定(環境に応じて文字列は調整が必要)
If InStr(1, objAdapter.Description, “Ethernet”, vbTextCompare) > 0 Then
Call ApplyMetric(objAdapter, METRIC_ETHERNET)
ElseIf InStr(1, objAdapter.Description, “Wi-Fi”, vbTextCompare) > 0 Or _
InStr(1, objAdapter.Description, “Wireless”, vbTextCompare) > 0 Then
Call ApplyMetric(objAdapter, METRIC_WIFI)
End If
Next
‘ メモリ最適化:オブジェクトの明示的解放
Set colAdapters = Nothing
Set objWMIService = Nothing
End Sub
Sub ApplyMetric(objAdapter, intMetric)
Dim intResult
‘ SetIPConnectionMetricメソッドの呼び出し
intResult = objAdapter.SetIPConnectionMetric(intMetric)
If intResult = 0 Then
WScript.Echo “Success: ” & objAdapter.Description & ” -> Metric: ” & intMetric
Else
WScript.Echo “Error: ” & objAdapter.Description & ” Code: ” & intResult
End If
End Sub
—
3. シニアエンジニアが押さえるべき「極限の知見」
オブジェクトのライフサイクル管理
VBScriptはガベージコレクションをOSのCOMレイヤーに依存している。大規模なバッチで`Set = Nothing`を怠れば、特にWMIのプロキシオブジェクトはメモリ上に残存し、後続の処理で不可解なエラーを引き起こす。必ずループの最後で明示的な解放を行うこと。
WMIの「重み」を理解せよ
WMIは強力だが、クエリの実行にはコストがかかる。大量のNICを抱えるサーバー環境等で実行する場合、`ExecQuery`の結果セットをループさせる際は、必ず必要なプロパティだけを絞り込むこと(上記クエリは`IPEnabled = True`で絞り込み、無駄なオブジェクト生成を抑制している)。
権限昇格の罠
このスクリプトは、`SetIPConnectionMetric`メソッドを呼び出す際に管理者権限を要求する。タスクスケジューラで実行する場合は「最上位の特権で実行する」にチェックを入れるのは当然として、実行ユーザーの環境変数`PATH`が汚染されていないか注意せよ。
4. 最後に:保守の哲学
このコードは10年以上前の環境でも、最新のWindows 11でも等しく動作する。これこそがVBScriptの真骨頂である。「枯れた技術」を軽視する者は、OSのアップデートごとにツールを作り直す羽目になる。
ネットワークという基盤をコードで制御する。この感覚を忘れなければ、君の管理するシステムは常に最高精度の状態で維持されるだろう。
さあ、次は君の環境でこのスクリプトを走らせ、ネットワークという名の「経路」を支配せよ。
