首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

VBScript WMI 監聽網路連線/斷線事件實現:MSNdis 狀態類別訂閱與事件驅動架構

     編輯:更多程式設計知識

利用 WMI 事件訂閱機制 (ExecNotificationQuery) 監聽網路介面卡連線/斷線狀態變化,基於 MSNdis_StatusMediaConnect 與 MSNdis_StatusMediaDisconnect 類別,實現無輪詢、即時響應的網路狀態監控。

一、監聽網路連線事件

' === NetConnectMonitor.vbs ===
strComputer = "."

Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
' 訂閱連線事件
Set colEvents = objWMI.ExecNotificationQuery("SELECT * FROM MSNdis_StatusMediaConnect")

WScript.Echo "Monitoring network CONNECT events... (Ctrl+C to stop)"

Do While True
    ' 同步阻塞等待下一事件
    Set objEvent = colEvents.NextEvent
    
    WScript.Echo "=== Network CONNECTED ==="
    WScript.Echo "Adapter: " & objEvent.InstanceName
    WScript.Echo "Time:    " & Now
    WScript.Echo ""
Loop

二、監聽網路斷線事件

' === NetDisconnectMonitor.vbs ===
strComputer = "."

Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
' 訂閱斷線事件
Set colEvents = objWMI.ExecNotificationQuery("SELECT * FROM MSNdis_StatusMediaDisconnect")

WScript.Echo "Monitoring network DISCONNECT events... (Ctrl+C to stop)"

Do While True
    Set objEvent = colEvents.NextEvent
    
    WScript.Echo "=== Network DISCONNECTED ==="
    WScript.Echo "Adapter: " & objEvent.InstanceName
    WScript.Echo "Time:    " & Now
    WScript.Echo ""
Loop

三、合併版:單一腳本雙向監聽

' === NetStatusMonitor.vbs ===
Option Explicit

Dim strComputer, objWMI, colConnect, colDisconnect, objEvent
strComputer = "."

Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
Set colConnect = objWMI.ExecNotificationQuery("SELECT * FROM MSNdis_StatusMediaConnect")
Set colDisconnect = objWMI.ExecNotificationQuery("SELECT * FROM MSNdis_StatusMediaDisconnect")

WScript.Echo "Network Status Monitor Started - " & Now
WScript.Echo "Listening on root\wmi for MediaConnect/Disconnect..."
WScript.Echo "Press Ctrl+C to stop."
WScript.Echo ""

' 使用非同步事件接收器 (SWbemSink) 實現並發監聽
Dim sinkConnect, sinkDisconnect
Set sinkConnect = WScript.CreateObject("WbemScripting.SWbemSink", "Connect_")
Set sinkDisconnect = WScript.CreateObject("WbemScripting.SWbemSink", "Disconnect_")

objWMI.ExecNotificationQueryAsync sinkConnect, "SELECT * FROM MSNdis_StatusMediaConnect"
objWMI.ExecNotificationQueryAsync sinkDisconnect, "SELECT * FROM MSNdis_StatusMediaDisconnect"

' 保持腳本運行
Do While True
    WScript.Sleep 1000
Loop

' === 事件處理函數 ===
Sub Connect_OnObjectReady(objEvent, objAsyncContext)
    LogEvent "CONNECTED", objEvent.InstanceName
End Sub

Sub Disconnect_OnObjectReady(objEvent, objAsyncContext)
    LogEvent "DISCONNECTED", objEvent.InstanceName
End Sub

Sub LogEvent(action, adapter)
    Dim logLine
    logLine = "[" & FormatDateTime(Now, 2) & " " & FormatDateTime(Now, 4) & "] " & _
              action & " - Adapter: " & adapter
    WScript.Echo logLine
    ' 可擴展:寫入日誌檔、發送郵件、觸發 API 等
    ' Dim fso, logFile
    ' Set fso = CreateObject("Scripting.FileSystemObject")
    ' Set logFile = fso.OpenTextFile("net_monitor.log", 8, True)
    ' logFile.WriteLine logLine
    ' logFile.Close
End Sub

四、關鍵技術點解析

技術點說明注意事項
命名空間root\wmi (非標準 cimv2)NDIS 狀態類別僅在 root\wmi 可用
事件類別MSNdis_StatusMediaConnect / Disconnect對應 NDIS_STATUS_MEDIA_CONNECT/DISCONNECT
同步 vs 非同步NextEvent 阻塞 / ExecNotificationQueryAsync 回調非同步支援並發多事件源
事件屬性InstanceName (網卡名稱)、Active (布林)可關聯 Win32_NetworkAdapter 獲取詳細資訊
權限需求需管理員權限或 WMI 權限標準用戶可能無法訂閱 root\wmi

五、事件屬性擴展:關聯網卡詳細資訊

Sub LogEvent(action, instanceName)
    Dim objWMI, colAdapters, adapter, desc, mac, speed
    Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
    
    ' 關聯 Win32_NetworkAdapter 獲取描述、MAC、速度
    Set colAdapters = objWMI.ExecQuery("SELECT * FROM Win32_NetworkAdapter WHERE Name = '" & instanceName & "'")
    For Each adapter In colAdapters
        desc = adapter.Description
        mac = adapter.MACAddress
        speed = adapter.Speed
    Next
    
    WScript.Echo "[" & Now & "] " & action
    WScript.Echo "  Instance: " & instanceName
    WScript.Echo "  Description: " & desc
    WScript.Echo "  MAC: " & mac
    WScript.Echo "  Speed: " & FormatNumber(speed / 1000000, 0) & " Mbps"
    WScript.Echo ""
End Sub

六、部署為 Windows 服務 (持續運行)

' === 安裝為服務 (需 SRVANY/Non-Sucking Service Manager) ===
' 1. 安裝 NSSM: nssm install NetMonitor
' 2. 設定:
'    Path: C:\Windows\System32\wscript.exe
'    Arguments: C:\Scripts\NetStatusMonitor.vbs
'    Startup: Automatic
' 3. 啟動: nssm start NetMonitor

' === 或使用 Windows 任務排程器 ===
' 觸發器: 開機時 / 使用者登入時
' 動作: wscript.exe C:\Scripts\NetStatusMonitor.vbs
' 設定: 使用最高權限執行、不儲存密碼

七、PowerShell 現代化實現 (推薦)

# Register-WmiEvent 原生支援非同步事件訂閱
$action = {
    $event = $Event.SourceEventArgs.NewEvent
    $adapter = $event.InstanceName
    $time = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $type = if ($Event.SourceIdentifier -like "*Connect*") { "CONNECTED" } else { "DISCONNECTED" }
    Write-Host "[$time] $type - Adapter: $adapter"
    
    # 關聯網卡詳細資訊
    $nic = Get-CimInstance Win32_NetworkAdapter -Filter "Name='$adapter'"
    if ($nic) { Write-Host "  Desc: $($nic.Description), MAC: $($nic.MACAddress), Speed: $($nic.Speed/1Mb) Mbps" }
}

Register-WmiEvent -Namespace "root\wmi" -Class "MSNdis_StatusMediaConnect" -SourceIdentifier "NetConnect" -Action $action
Register-WmiEvent -Namespace "root\wmi" -Class "MSNdis_StatusMediaDisconnect" -SourceIdentifier "NetDisconnect" -Action $action

Write-Host "Monitoring started. Press Ctrl+C to stop."
# 保持運行
while ($true) { Start-Sleep 10 }

# 清理
Get-EventSubscriber | Unregister-Event

八、適用場景與限制

適用場景限制
伺服器網路斷線告警需管理員權限,標準用戶受限
筆記本乾淨/接入網路觸發同步虛擬網卡 (Hyper-V, VPN) 也會觸發事件
嵌入式裝置網路狀態上報WMI 服務異常時監聽失效
安全審計:未授權網卡啟用檢測無法區分物理拔插 vs 軟體啟停
總結:WMI 事件訂閱提供了優雅的「推模式」網路監控,避免輪詢 CPU 佔用。VBScript 版適合輕量部署、無 PowerShell 環境;生產環境強烈建議使用 PowerShell Register-WmiEvent 或 C# ManagementEventWatcher,享受更豐富的事件處理管線、錯誤恢復與診斷能力。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved