Udostępnij za pośrednictwem


Odbieranie zdarzenia WMI

Usługa WMI zawiera infrastrukturę zdarzeń, która generuje powiadomienia o zmianach w danych i usługach usługi WMI. Klasy zdarzeń usługi WMI dostarczają powiadomienia, gdy wystąpią określone zdarzenia.

W tym temacie omówiono następujące sekcje:

Zapytania dotyczące zdarzeń

Możesz utworzyć częściowo synchroniczne lub asynchroniczne zapytanie w celu monitorowania zmian w dziennikach zdarzeń, tworzenia procesów, stanu usługi, dostępności komputera lub wolnej przestrzeni na dysku oraz innych jednostek lub zdarzeń. W skryptach metoda SWbemServices.ExecNotificationQuery służy do subskrybowania zdarzeń. W języku C++ IWbemServices::ExecNotificationQuery jest używana. Aby uzyskać więcej informacji, zobacz Wywoływanie metody.

Powiadomienie o zmianie standardowego modelu danych WMI jest nazywane zdarzeniem wewnętrznym . __InstanceCreationEvent lub __NamespaceDeletionEvent są przykładami zdarzeń wewnętrznych. Powiadomienie o zmianie, którą dostawca wprowadza, aby zdefiniować wydarzenie dostawcy, nazywa się zdarzeniem zewnętrznym . Na przykład dostawca rejestru systemowego , dostawca zdarzeń zarządzania energią i dostawca Win32 definiują własne zdarzenia. Aby uzyskać więcej informacji, zobacz Określanie typu zdarzenia do odbioru.

Przykład

Poniższy przykład kodu skryptu to zapytanie dotyczące właściwości wewnętrznej __InstanceCreationEvent klasy zdarzeń Win32_NTLogEvent. Ten program można uruchomić w tle, a gdy wystąpi zdarzenie, zostanie wyświetlony komunikat. Jeśli zamkniesz okno dialogowe Oczekiwanie na zdarzenia, program przestanie czekać na zdarzenia. Należy pamiętać, że należy włączyć SeSecurityPrivilege.

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    WScript.Echo (objObject.TargetInstance.Message)
End Sub

Set objWMIServices = GetObject( _
    "WinMgmts:{impersonationLevel=impersonate, (security)}") 

' Create the event sink object that receives the events
Set sink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
 
' Set up the event selection. SINK_OnObjectReady is called when
' a Win32_NTLogEvent event occurs
objWMIServices.ExecNotificationQueryAsync sink,"SELECT * FROM __InstanceCreationEvent " & "WHERE TargetInstance ISA 'Win32_NTLogEvent' "

WScript.Echo "Waiting for events"

# Define event Query
$query = "SELECT * FROM __InstanceCreationEvent 
          WHERE TargetInstance ISA 'Win32_NTLogEvent' "

<# Register for event - also specify an action that
displays the log event when the event fires.#>

Register-WmiEvent -Source Demo1 -Query $query -Action {
                Write-Host "Log Event occured"
                $global:myevent = $event
                Write-Host "EVENT MESSAGE"
                Write-Host $event.SourceEventArgs.NewEvent.TargetInstance.Message}
<# So wait #>
"Waiting for events"

Poniższy przykład kodu VBScript przedstawia zdarzenie zewnętrzne __RegistryValueChangeEvent zdefiniowane przez dostawcę rejestru. Skrypt tworzy użytkownika tymczasowego przy użyciu wywołania metody SWbemServices.ExecNotificationQueryAsynci odbiera zdarzenia tylko wtedy, gdy skrypt jest uruchomiony. Poniższy skrypt jest uruchamiany w nieskończoność do czasu ponownego uruchomienia komputera, zatrzymanie usługi WMI lub zatrzymanie skryptu. Aby ręcznie zatrzymać skrypt, użyj Menedżera zadań, aby zatrzymać proces. Aby zatrzymać go programowo, użyj metody Terminate w klasie Win32_Process. Aby uzyskać więcej informacji, zobacz Ustawianie zabezpieczeń dla połączenia asynchronicznego.

strComputer = "."

Set objWMIServices=GetObject( _
    "winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default")

set objSink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")


objWMIServices.ExecNotificationQueryAsync objSink, _
    "Select * from RegistryValueChangeEvent Where Hive = 'HKEY_LOCAL_MACHINE' and KeyPath = 'SYSTEM\\ControlSet001\\Control' and ValueName = 'CurrentUser'"

WScript.Echo "Waiting for events..."

While (True) 
     WScript.Sleep (1000)
Wend

 
WScript.Echo "Listening for Registry Change Events..." & vbCrLf 

While(True) 
    WScript.Sleep 1000 
Wend 

Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext) 
    WScript.Echo "Received Registry Value Change Event" & vbCrLf & wmiObject.GetObjectText_() 
End Sub

Odbiorcy zdarzeń

Zdarzenia można monitorować lub wykorzystywać przy użyciu następujących odbiorców, gdy skrypt lub aplikacja działa:

  • Tymczasowi użytkownicy zdarzeń

    konsument tymczasowy to aplikacja kliencka usługi WMI, która odbiera zdarzenie WMI. Usługa WMI zawiera unikatowy interfejs, który służy do określania zdarzeń, które WMI ma wysyłać do aplikacji klienckiej. Tymczasowy odbiorca zdarzeń jest uważany za tymczasowy, ponieważ działa tylko wtedy, gdy został on specjalnie załadowany przez użytkownika. Aby uzyskać więcej informacji, zobacz Odbieranie zdarzeń na czas działania aplikacji.

  • Konsumenci zdarzeń stałych

    konsument trwały jest obiektem COM, który może odbierać zdarzenie WMI w dowolnym momencie. Użytkownik zdarzenia trwałego używa zestawu trwałych obiektów i filtrów do przechwytywania zdarzenia WMI. Podobnie jak tymczasowy odbiorca zdarzeń, konfigurujesz serię obiektów i filtrów WMI, które przechwytują zdarzenia WMI. Gdy wystąpi zdarzenie zgodne z filtrem, usługa WMI ładuje stałego odbiorcę zdarzeń i powiadamia go o zdarzeniu. Ponieważ użytkownik trwały jest implementowany w repozytorium WMI i jest plikiem wykonywalnym, który jest zarejestrowany w usłudze WMI, trwały odbiorca zdarzeń działa i odbiera zdarzenia po jego utworzeniu, a nawet po ponownym uruchomieniu systemu operacyjnego, o ile usługa WMI jest uruchomiona. Aby uzyskać więcej informacji, zobacz Odbieranie zdarzeń przez cały czas.

Skrypty lub aplikacje odbierające zdarzenia mają specjalne zagadnienia dotyczące zabezpieczeń. Aby uzyskać więcej informacji, zobacz Zabezpieczanie zdarzeń WMI.

Aplikacja lub skrypt może używać wbudowanego dostawcy zdarzeń WMI, który dostarcza standardowych klas odbiorców. Każda standardowa klasa konsumenta odpowiada na zdarzenie z inną akcją, wysyłając wiadomość e-mail lub wykonując skrypt. Nie musisz pisać kodu dostawcy, aby użyć standardowej klasy odbiorców do utworzenia trwałego odbiorcy zdarzeń. Więcej informacji można znaleźć w Monitorowanie i reagowanie na zdarzenia za pomocą standardowych odbiorców.

Dostarczanie zdarzeń

Dostawca zdarzeń to składnik COM, który wysyła zdarzenie do Instrumentacji zarządzania Windows (WMI). Możesz utworzyć dostawcę zdarzeń w celu wysłania zdarzenia w aplikacji C++ lub C#. Większość dostawców zdarzeń zarządza obiektem usługi WMI, na przykład aplikacją lub elementem sprzętu. Więcej informacji znajdziesz w Pisanie dostawcy zdarzeń.

Zdarzenie zaplanowane lub powtarzające się jest zdarzeniem, które występuje w ustalonym czasie.

Usługa WMI udostępnia następujące sposoby tworzenia zdarzeń czasowych lub powtarzających się dla Twoich aplikacji.

  • Standardowa infrastruktura zdarzeń firmy Microsoft.
  • Wyspecjalizowana klasa czasomierza.

Aby uzyskać więcej informacji, zobacz Odbieranie wydarzenia zaplanowanego lub cyklicznego. Podczas pisania dostawcy zdarzeń, należy uwzględnić informacje dotyczące zabezpieczeń, które zostały zidentyfikowane w Bezpieczne dostarczanie zdarzeń.

Zaleca się skompilowanie stałych subskrypcji zdarzeń w przestrzeni nazw \root\subscription. Aby uzyskać więcej informacji, zobacz Implementowanie trwałych subskrypcji zdarzeń między przestrzeniami nazw.

Limity subskrypcji

Sondowanie zdarzeń może obniżyć wydajność dostawców, którzy obsługują zapytania dotyczące ogromnych zestawów danych. Ponadto każdy użytkownik, który ma dostęp do odczytu do przestrzeni nazw z dynamicznymi dostawcami, może przeprowadzić atak typu "odmowa usługi" (DoS). Usługa WMI utrzymuje limity przydziału dla wszystkich użytkowników łącznie oraz dla każdego odbiorcy zdarzeń w pojedynczym wystąpieniu __ArbitratorConfiguration znajdującym się w przestrzeni nazw \root. Te limity przydziału są globalne, a nie dla każdej przestrzeni nazw. Nie można zmienić limitów przydziału.

Usługa WMI obecnie wymusza przydziały przy użyciu właściwości __ArbitratorConfiguration. Każdy limit przydziału ma wartość na użytkownika oraz łączną wersję obejmującą wszystkich użytkowników, a nie w podziale na przestrzenie nazw. W poniższej tabeli wymieniono przydziały, które mają zastosowanie do właściwości __ArbitratorConfiguration.

Całkowity/NaUżytkownika Kwota
ŁącznaLiczbaTymczasowychSubskrypcji
TymczasoweSubskrypcjeNaUżytkownika
10 000
1,000
Łączna liczba stałych subskrypcji
StałeSubskrypcjeNaUżytkownika
10 000
1,000
SumaryczneInstrukcjeGłosowania
InstrukcjeAnkietowaniaNaUżytkownika
10 000
1,000
PollingMemoryTotal
PamięćAnkietowaNaUżytkownika
10 000 000 (0x989680) bajtów
5000 000 (0x4CB40) bajtów

Administrator lub użytkownik z uprawnieniami FULL_WRITE w przestrzeni nazwowej może modyfikować pojedyncze wystąpienie __ArbitratorConfiguration. Usługa WMI śledzi limity przydziałów na użytkownika.

Korzystanie z WMI