監視事件

系統管理員可以使用 WMI 來監視網路上的事件。 例如:

  • 服務意外停止。
  • 伺服器變成無法使用。
  • 磁片磁碟機會填滿至 80% 的容量。
  • 安全性事件會回報給 NT 事件記錄檔。

WMI 支援事件偵測和傳遞至事件取用者,因為某些 WMI 提供者是事件提供者。 如需詳細資訊,請參閱 接收 WMI 事件

事件取用者 是要求事件通知的應用程式或腳本,然後在發生特定事件時執行工作。 您可以建立事件監視腳本或應用程式,以在事件發生時暫時監視。 WMI 也提供一組預先安裝的永久事件提供者和永久取用者類別,讓您能夠永久監視事件。 如需詳細資訊,請參閱 使用標準取用者監視和回應事件

本主題將討論下列各節:

使用暫存事件取用者

暫存事件取用者是腳本或應用程式,可傳回符合事件查詢或篩選的事件。 暫存事件查詢通常會在 C++ 應用程式中使用 IWbemServices::ExecNotificationQuery ,或在腳本和 Visual Basic 中使用 SWbemServices.ExecNotificationQuery

事件查詢會要求事件類別的實例,指定特定類型的事件,例如 Win32_ProcessTraceRegistryKeyChangeEvent

下列 VBScript 程式碼範例會在建立 Win32_ProcessTrace 實例時要求通知。 當進程啟動或停止時,就會產生這個類別的實例。

若要執行腳本,請將它複製到名為 event.vbs 的檔案,並使用下列命令列: cscript event.vbs。 您可以從腳本開始Notepad.exe或任何其他進程來查看輸出。 腳本會在五個進程啟動或停止之後停止。

此腳本會呼叫 SWbemServices.ExecNotificationQuery,這是方法的 半同步 版本。 如需呼叫 SWbemServices.ExecNotificationQueryAsync來設定非同步暫存事件訂閱的範例,請參閱下一個腳本。 如需詳細資訊,請參閱 呼叫方法。 腳本會呼叫 SWbemEventSource.NextEvent ,以在到達時取得和處理每個事件。 將腳本儲存在副檔名為 .vbs 的檔案中,並使用 CScript 在命令列上執行腳本: cscript file.vbs

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" _
    & strComputer & "\root\CIMV2") 
Set objEvents = objWMIService.ExecNotificationQuery _
    ("SELECT * FROM Win32_ProcessTrace")

Wscript.Echo "Waiting for events ..."
i = 0
Do Until i=5
    Set objReceivedEvent = objEvents.NextEvent
    'report an event
    Wscript.Echo "Win32_ProcessTrace event occurred" & VBNewLine _
        & "Process Name = " _
            & objReceivedEvent.ProcessName & VBNewLine _
        & "Process ID = " _
            & objReceivedEvent.Processid & VBNewLine _
        & "Session ID = " & objReceivedEvent.SessionID 
i = i+ 1
Loop

暫時事件取用者必須手動啟動,且不得在 WMI 重新開機或作業系統重新開機之間保存。 暫存事件取用者只能在執行時處理事件。

下列程式描述如何建立暫時事件取用者。

建立暫存事件取用者

  1. 決定要使用的程式設計語言。

    程式設計語言會決定要使用的 API。

  2. 開始撰寫暫時事件取用者應用程式的程式碼,與啟動 WMI 應用程式的方式相同。

    程式碼撰寫的第一個步驟取決於程式設計語言。 一般而言,您會登入 WMI 並設定安全性設定。 如需詳細資訊,請參閱 建立 WMI 應用程式或腳本

  3. 定義您想要使用的事件查詢。

    若要取得某些類型的效能資料,您可能需要使用高效能提供者所提供的類別。 如需詳細資訊,請參閱 監視效能資料判斷要接收的事件種類,以及 使用 WQL 進行查詢

  4. 決定進行非同步呼叫或半非同步呼叫,然後選擇 API 方法。

    非同步呼叫可讓您避免輪詢資料的額外負荷。 不過,半同步呼叫會以更高的安全性提供類似的效能。 如需詳細資訊,請參閱 呼叫方法

  5. 進行非同步或半同步方法呼叫,並包含事件查詢做為 strQuery 參數。

    針對 C++ 應用程式,呼叫下列方法:

    針對腳本,呼叫下列方法:

  6. 撰寫程式碼來處理傳回的事件物件。

    針對非同步事件查詢,請將程式碼放在物件接收的各種方法或事件中。 對於半同步事件查詢,每個物件都會在 WMI 取得時傳回,因此程式碼應該在處理每個物件的迴圈中。

下列腳本程式碼範例是 Win32_ProcessTrace 腳本的非同步版本。 因為非同步作業會立即傳回,所以對話方塊會在等候事件時讓腳本保持作用中。

腳本具有SWbemSink OnObjectReady事件的事件處理常式,而不是呼叫SWbemEventSource.NextEvent來接收每個事件。

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & _
    strComputer & "\root\CIMV2") 
Set EventSink = WScript.CreateObject( _
    "WbemScripting.SWbemSink","SINK_")

objWMIservice.ExecNotificationQueryAsync EventSink, _
    "SELECT * FROM Win32_ProcessTrace WITHIN 10"
WScript.Echo "Waiting for events..."

i = 0
While (True)
    Wscript.Sleep(1000)
Wend

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    Wscript.Echo "Win32_ProcessTrace event has occurred."
    i = i+1
    If i = 3 Then WScript.Quit 0 
End Sub

注意

非同步回呼,例如副程式所 SINK_OnObjectReady 處理的回呼,可讓未經驗證的使用者將資料提供給接收。 為了獲得更好的安全性,請使用半同步通訊或同步通訊。 如需詳細資訊,請參閱下列主題:

 

使用永久事件取用者

永久事件取用者會在明確取消註冊之前執行,然後在 WMI 或系統重新開機時啟動。

永久事件取用者是系統上 WMI 類別、篩選和 COM 物件的組合。

下列清單會識別建立永久事件取用者所需的元件:

  • COM 物件,包含實作永久取用者的程式碼。
  • 新的永久取用者類別。
  • 永久取用者類別的實例。
  • 包含事件查詢的篩選。
  • 取用者與篩選之間的連結。

如需詳細資訊,請參閱 隨時接收事件

WMI 提供數個永久取用者。 預先安裝包含程式碼的取用者類別和 COM 物件。 例如,您可以建立及設定 ActiveScriptEventConsumer 類別的實例,以在事件發生時執行腳本。 如需詳細資訊,請參閱 使用標準取用者監視和回應事件。 如需使用 ActiveScriptEventConsumer的範例,請參閱 根據事件執行腳本

下列程式描述如何建立永久事件取用者。

建立永久事件取用者

  1. 向您使用的命名空間註冊事件提供者

    某些事件提供者只能使用特定的命名空間。 例如, __InstanceCreationEventWin32 提供者 支援的內建事件,預設會向 \root\cimv2 命名空間註冊。

    注意

    您可以使用註冊中用來建立跨命名空間訂用帳戶之__EventFilterEventNamespace屬性。 如需詳細資訊,請參閱 實作跨命名空間永久事件訂閱

     

  2. 向事件類別所在的命名空間註冊事件取用者提供者

    WMI 會使用事件取用者提供者來尋找永久的事件取用者。 永久事件取用者是收到事件時 WMI 啟動的應用程式。 若要註冊事件取用者,提供者會建立 __EventConsumerProviderRegistration的實例。

  3. 建立 類別的實例,此實例代表您要使用的永久事件取用者。

    事件取用者類別衍生自類別 __EventConsumer。 設定事件取用者實例所需的屬性。

  4. 使用 regsvr32 公用程式向 COM 註冊取用者。

  5. __EventFilter建立事件 篩選類別的實例。

    設定事件篩選實例的必要欄位。 __EventFilter的必要欄位為NameQueryLanguageQueryName屬性可以是這個類別實例的任何唯一名稱。 QueryLanguage屬性一律設定為 「WQL」。 Query屬性是包含事件查詢的字串。 當永久事件取用者的查詢失敗時,就會產生事件。 事件的來源為 WinMgmt、事件識別碼為 10,而事件種類為 Error。

  6. 建立 __FilterToConsumerBinding 類別的實例,以將邏輯事件取用者與事件篩選產生關聯。

    WMI 會使用關聯來尋找與事件相關聯的事件取用者,該事件符合事件篩選中指定的準則。 WMI 會使用事件取用者提供者來尋找要啟動的永久事件取用者應用程式。