Wist je dat je bijna elke handeling in Windows kunt volgen? Nee, je hoeft geen geavanceerde software te kopen. De infrastructuur bewaakt gebeurtenissen zoals wanneer services starten en stoppen, wanneer iemand een bestand of map maakt, en meer is al beschikbaar via Windows Management Instrumentation (WMI)-gebeurtenissen.
WMI-gebeurtenissen zijn geen functie die specifiek is voor PowerShell, maar een van de eenvoudigste manieren om WMI-gebeurtenissen te benutten en handige tools te maken, is PowerShell. In deze stapsgewijze handleiding leer je hoe je gebruik kunt maken van WMI-gebeurtenissen met PowerShell en krijg je de vaardigheden om handige monitoringtools te bouwen!
Laten we eraan beginnen!
Vereisten
Je zult veel demonstraties zien in deze praktische handleiding. Als je wilt meedoen met een van de demonstraties, zorg er dan voor dat je het volgende hebt:
- Windows 7+ of Windows Server 2012+ – Deze handleiding zal gebruikmaken van Windows Server 2019.
- Ingelogd als gebruiker in de lokale beheerdersgroep.
- Windows PowerShell 5.1 of PowerShell 6+ – Deze handleiding zal PowerShell v7.1.2 gebruiken.
Begrip van WMI en CIM
Voordat je aan de slag kunt met WMI-gebeurtenissen, is het belangrijk om eerst de infrastructuur te begrijpen waarop ze zijn gebouwd. Hoewel deze handleiding niet diep ingaat op WMI, kun je altijd verwijzen naar de WMI-documentatie van Microsoft om meer te weten te komen.
WMI en het bijbehorende gegevensmodel, het Common Information Model (CIM), zijn modellen ingebouwd in Windows die vrijwel elk stuk informatie opslaan in een repository dat verband houdt met de interne werking van Windows en wat erop draait.
WMI en CIM zijn krachtige tools die beheerders gebruiken om Windows zowel lokaal als op afstand te beheren. Met behulp van WMI of CIM kunnen beheerders informatie opvragen over een Windows-systeem, zoals geïnstalleerde toepassingen, de status van services, bestanden op het bestandssysteem, en zo ongeveer alles.
WMI en CIM zijn de manier waarop veel enterprise-monitoringoplossingen informatie verzamelen over de gezondheid van het besturingssysteem en de toepassingen. Maar je hoeft geen dure monitoringtool te kopen om WMI te benutten; je hebt PowerShell!
Laten we beginnen met de twee basiselementen, en naarmate we verder gaan, zul je de andere benodigde elementen leren:
- Klassen: De klassen zijn de gebeurtenissen en eigenschappen waartoe de toepassing, zoals PowerShell, kan oproepen om gegevens te lezen en bij te werken. Klassen bevinden zich binnen een namespace.
- Namespace: De namespace is een container voor WMI-gerelateerde klassen. Denk eraan als een map Mijn Afbeeldingen die afbeeldingsgerelateerde inhoud bevat. Er zijn meerdere namespaces, en de meest voorkomende is CIMv2, die de meeste OS-klassen bevat. Maar, alle namespaces bevinden zich onder de grote enkele namespace Root.

WMI vs. CIM
WMI en CIM zijn beide methoden om te communiceren met het repository op een Windows-systeem dat veel informatie bevat en om te werken met WMI-gebeurtenissen (meer hierover later). Maar beide methoden hebben een paar verschillen, voornamelijk de manier waarop beheerders er op afstand mee communiceren.
WMI begon met Windows NT4 en was de oorspronkelijke (en enige) manier om te communiceren met het repository. Wanneer je een Windows-systeem beheert met WMI, gebruikt Windows Distributed Component Object Model (DCOM). DCOM is een protocol op afstand dat WMI gebruikt om informatie bloot te stellen binnen het gegevensrepository op een Windows-machine.
Om over een netwerk te werken, maakt DCOM gebruik van Remote Procedure Call (RPC). Om te communiceren over een netwerk, maakt RPC gebruik van dynamische poortreeksen, wat soms een uitdaging is voor firewalls en Network Address Translation (NAT)-apparaten.
Als je problemen hebt met RPC, bekijk dan het artikel Test RPC Connections with the Dynamic Ports.
Microsoft heeft besloten om CIM te benutten om een modernere benadering te bieden voor interactie met het gegevensrepository in Windows. In plaats van RPC gebruikt CIM WS-MAN (Web-Service for Management), een HTTP-protocol dat veel geschikter is voor extern beheer.
Gedurende dit artikel en andere artikelen kunnen de termen WMI en CIM door elkaar worden gebruikt. Het gegevensrepository waarmee beide beheermethoden interageren, wordt doorgaans een WMI-repository genoemd. Bijna alle termen verwijzen naar WMI, terwijl CIM doorgaans wordt genoemd in PowerShell-cmdlets.
WMI vs. CIM en PowerShell
Gelukkig heb je wat opties als het gaat om WMI en CIM met PowerShell. PowerShell ondersteunt beide manieren om met het gegevensrepository te communiceren. Wanneer je het Get-Command
-commando uitvoert in PowerShell, zie je mogelijk verschillende Wmi
-cmdlets zoals Get-WmiObject
, Invoke-WmiMethod
, Remove-WmiObject
, Register-WmiEvent
en Set-WmiInstance
.
Als je Windows PowerShell 3 of hoger gebruikt (wat je beter doet!), zie je ook enkele vergelijkbaar genoemde cmdlets zoals Get-CimInstance
, Get-CimClass
en Remove-CimInstance
.
Welke PowerShell-cmdlets moet je gebruiken? Het antwoord is eenvoudig; de CIM-cmdlets. CIM is de nieuwe standaard waar Microsoft zich op richt. De WMI-cmdlets zijn zelfs niet beschikbaar in PowerShell Core!
WMI bevragen: De basisprincipes
Voordat je met WMI-events aan de slag kunt, moet je begrijpen hoe je WMI kunt bevragen met PowerShell. Het bevragen van informatie uit het WMI-repository is de meest voorkomende toepassing van WMI-gegevens.
Om WMI-gegevens in de PowerShell-wereld te bevragen, is de Get-CimInstance
-cmdlet je vriend. Deze cmdlet heeft verschillende manieren om WMI-gegevens te bevragen, maar deze tutorial zal zich richten op de Query
-parameter. De Query
-parameter stelt je in staat om een Windows Query Language (WQL) query op te geven om WMI te bevragen.
Bijvoorbeeld, misschien wil je alle WMI-instanties in de Win32_Service
-klasse vinden. Net als bij SQL zou je de query Select * from Win32_Service
gebruiken, zoals hieronder weergegeven. Het asterisk (*
) vertelt WMI om alle eigenschappen van elke gevonden instantie terug te geven.

In het bovenstaande voorbeeld heb je alle instanties van elke service in de Win32_Service
-klasse gevonden, maar wat als je er slechts een paar wilt vinden? In dat geval zou je de WHERE
-clausule gebruiken. De WHERE
-clausule creëert een filter om alleen instanties terug te geven die aan een specifieke voorwaarde voldoen.
De WHERE
-clausule vertelt Get-CimInstance
alleen om instanties terug te geven waar de instantie-eigenschap overeenkomt met een specifieke waarde. Bijvoorbeeld, misschien wilt u alleen de service-instanties vinden waar de State
-eigenschap Running
is. Als dat het geval is, zou u de WHERE
-clausule Where State='Running'
definiëren, zoals hieronder getoond.
U kunt hieronder zien dat Get-CimInstance
alleen de service-instanties heeft teruggegeven waar de State
-eigenschap gelijk was aan Running
.

WMI-gebeurtenissen: De Acties van WMI
WMI bevat een grote verzameling informatie over duizenden items in Windows. U kunt die informatie bereiken door ernaar te vragen zoals u hierboven heeft gedaan, maar het heeft ook een andere minder bekende functie; WMI-gebeurtenissen.
In Windows kunnen op elk moment honderden gebeurtenissen plaatsvinden. Wanneer u verschillende functies van Windows gebruikt zoals het maken van bestanden, stoppen en starten van services, installeren van software, of iets anders, wordt waarschijnlijk een WMI-gebeurtenis geactiveerd.
Praktisch elke actie die op Windows wordt uitgevoerd, kan via een WMI-gebeurtenis worden blootgelegd. Wanneer een actie op Windows wordt uitgevoerd, activeert Windows een gebeurtenis via zijn interne infrastructuur. Standaard kunt u deze gebeurtenissen niet zien; ze vinden op de achtergrond plaats. Om deze gebeurtenissen te zien, moet u zich erop abonneren.
Het bouwen van een Service Monitoring Script met PowerShell
Om te demonstreren hoe WMI-gebeurtenissen werken, in plaats van u te vervelen met tonnen informatie, laten we in plaats daarvan een nuttig hulpmiddel bouwen. Aangezien WMI-gebeurtenissen plaatsvinden wanneer er een gebeurtenis plaatsvindt in Windows, kunt u met behulp daarvan handige monitoringtools maken.
Misschien wil je een bericht schrijven naar een logbestand wanneer de status van een Windows-service verandert op een kritieke server. Vervolgens kun je je abonneren op de WMI-gebeurtenissen die deze acties triggeren wanneer ze plaatsvinden. Wanneer je je abonneert op de gebeurtenis en de gebeurtenis wordt getriggerd, kun je een actie uitvoeren zoals het loggen naar een bestand, het versturen van een e-mail, of zowat alles wat je kunt doen met PowerShell.
In plaats van een dure bewakingsoplossing te kopen, kan een eenvoudig PowerShell-script een geweldige monitoringtool voor de arme man zijn! Als je er klaar voor bent, open je PowerShell-console en laten we beginnen!
Het vinden van de CIM-klasse
Binnen WMI, zoals statische instanties, worden gebeurtenissen opgeslagen in klassen. Deze klassen bevatten alle statische gegevens die je hierboven hebt opgevraagd en waar wijzigingen in die instanties worden getriggerd. Je kunt een lijst vinden van alle CIM-klassen in de Microsoft-documentatie.
Om alle CIM-klassen te vinden, voer je het Get-CimClass
-cmdlet uit zonder parameters. Het Get-CimClass
-cmdlet retourneert standaard alle klassen in de ROOT/cimv2
-namespace. De ROOT/cimv2
-namespace is de “hoofd”namespace waarin bijna alle interessante Windows-klassen zijn opgeslagen.
Je kunt hieronder echter zien dat er veel klassen worden geretourneerd.

Misschien heb je wat onderzoek gedaan en eindelijk ontdekt dat Windows-services allemaal zijn opgeslagen in de Win32_Service
. Dus, wanneer je de naam van de klasse weet, gebruik dan de ClassName
-parameter om de naam te specificeren, zoals hieronder wordt getoond.

Het vinden van de eigenschappen van de CIM-klasse
Zodra je weet naar welke klasse je moet kijken, moet je vervolgens uitzoeken welke eigenschap je moet bekijken. Wanneer de waarde van een instantie-eigenschap verandert (of een hele instantie wordt gemaakt of verwijderd), wordt er een gebeurtenis geactiveerd. Je moet die statusverandering vastleggen. Om dat te doen, moet je weten welke eigenschap je wilt controleren.
Om die eigenschap te vinden, inspecteer je de CimClassProperties
-PowerShell-objecteigenschap op de CIM-klasse-instantie die je hebt bevraagd in de vorige sectie.
Let hieronder op dat een van die eigenschappen de State
-eigenschap is.

Nu je weet naar welke CIM-klasse en -eigenschap je wilt luisteren, is het tijd om je te abonneren op het WMI-evenement!
Het opzetten van een WMI-evenementenabonnement: Het overzicht op hoog niveau
Het opzetten van een WMI-evenementenabonnement kan een verwarrende taak zijn als je er nog nooit een hebt gemaakt. Om je te helpen de acties recht te houden, laten we eerst het bos zien voordat we de bomen bespreken en de basisstappen uiteenzetten.
Het maken van een WMI-evenementenabonnement vereist vier ruwe stappen:
- Het samenstellen van de WQL-query – Net zoals bij het opvragen van statische gegevens, moet je een WQL-query maken die overeenkomt met het type WMI-gebeurtenis dat je wilt zien. Maar in tegenstelling tot het opvragen van de gegevensopslagplaats, moet je in de query een paar meer ingewikkelde componenten gebruiken, zoals systeemklassen en controlecycli (hier later meer over).
- Het maken van de gebeurtenisfilter – Nadat je de WQL-query hebt gemaakt, moet je de gebeurtenisfilter maken. De gebeurtenisfilter registreert de WQL-query in CIM.
- Het maken van de consument – De consument definieert de actie die moet worden ondernomen wanneer de gebeurtenisfilterquery een wijziging in de klasse retourneert. Bijvoorbeeld, telkens wanneer de status van een service wordt gestart, gestopt, gemaakt of verwijderd, triggert de consument een actie.
- Het koppelen van de gebeurtenisfilter aan de consument – De lijm die de Windows WMI-query verbindt met de consument. De binding is wat de consument op de hoogte brengt wanneer de gebeurtenisfilter een overeenkomst heeft ontvangen.
Wanneer je al deze items samenvoegt, creëer je een abonnement.

Het samenstellen van de WQL-query
A WQL query for a WMI event looks a bit different than performing a simple query with Get-CimInstance
. Below you’ll find a typical WMI event query.
Aangezien de WQL-query er in eerste instantie misschien intimiderend uitziet, laten we deze opsplitsen en begrijpen hoe elk onderdeel werkt.
De Systeemklasse
In het voorbeeld van Get-CimInstance
had je ontdekt dat je op de hoogte wilt worden gesteld wanneer er een wijziging wordt aangebracht in een instantie van de klasse Win32_Service
. Je hebt nog steeds deze klasse nodig, maar in plaats van een WQL-query die er zo uitziet:
In plaats daarvan begint de query als volgt. De hoofdklasse die je aan het bevragen bent, is niet de klasse die de instantie bevat waarover je op de hoogte wilt worden gesteld. In plaats daarvan is de klasse een systeemklasse.
Systeemklassen zijn een interne klasse die het type van wijziging vertegenwoordigt die het evenement met zich meebrengt. Een WMI-evenement heeft vier typen systeemklassen:
- InstanceModificationEvent – Controleert op wijzigingen in de eigenschapswaarden van een instantie in een klasse. Deze klasse wordt gebruikt omdat je een eigenschapswaarde
Status
wilt controleren op een instantie (service) van de klasseWin32_Service
. - InstanceCreationEvent – Controleert op nieuwe instanties. Als je bijvoorbeeld wilt controleren op nieuwe gecreëerde services, zou je deze systeemklasse gebruiken.
- InstanceDeletionEvent – Controleert op verwijderde instanties. Als je bijvoorbeeld services wilt controleren die zijn verwijderd, zou je deze systeemklasse gebruiken.
- InstanceOperationEvent – Deze systeemklasse controleert op alle soorten gebeurtenissen, wijzigingen, creaties en verwijderingen.
Voor ons monitoringscript ziet het begin van de WQL-query er als volgt uit:
WMI-systeemklassen beginnen altijd met twee underscores (__) gevolgd door de naam van de klasse.
Het Controlecircuit
Vervolgens heb je het controlecircuit. Het controlecircuit bevat het trefwoord binnen
en een waarde die een peilinterval voorstelt, uitgedrukt in seconden.
WMI-gebeurtenissen zijn niet realtime, dus je moet een bepaald interval definiëren voor je abonnement om wijzigingen te controleren. Als je bijvoorbeeld het controlecircuit op 10 instelt, controleert het abonnement elke 10 seconden op een wijziging sinds het laatste peilinterval. Als er een wijziging wordt gevonden, activeert het de gebruiker.
Als een instantie wordt gewijzigd, gemaakt of verwijderd, afhankelijk van de systeemklasse binnen het peilinterval, wordt de wijziging niet gedetecteerd! Overweeg de frequentie die je nodig hebt, maar zorg ervoor dat het CPU- en geheugenvriendelijk is!
Voor het voorbeeld van de servicedetectie in de tutorial, laten we het controlecircuit op 10 instellen om elke 10 seconden WMI te peilen voor een wijziging in een Windows-service. De WQL-query wordt uitgebreider!
De Filter
Tenslotte, om de WQL-query te voltooien, moet je een filter definiëren om de instanties die worden geretourneerd door de systeemklasse te beperken. Je moet dat filter in onderstaande vorm definiëren. In dit geval heet de CIM-klasse die je wilt controleren de TargetInstance
.
ISA
is een operator die een query toepast op de subklassen van een gespecificeerde klasse.
Aangezien de tutorial een abonnement bouwt om Windows-services te monitoren, zou je het filter als volgt maken:
Zoals het nu is, zoekt de filter naar Win32_Service
in alle gevallen. Als je slechts één eigenschap wilt monitoren, misschien een specifieke service, zou je de AND
-operator gebruiken.
De AND– of OR-operatoren voegen andere voorwaarden toe om nauwkeurigere resultaten te krijgen.
De tutorialfilter (en de hele query) is nu compleet zoals de codefragment hieronder laat zien.
Het maken van de gebeurtenisfilter
Nu je de queryfilter hebt, is de rest van het proces veel gemakkelijker te begrijpen! Je moet nu de gebeurtenisfilter maken om die query te gebruiken. Een gebeurtenisfilter is eigenlijk een andere CIM-instantie die deel uitmaakt van de __EventFilter
-klasse binnen de Root/subscription
-namespace.
Hieronder vind je een codefragment met alles wat je nodig hebt. Het onderstaande script wijst de WQL-query toe aan de variabele $FilterQuery
. Vervolgens maakt het een hashtable aan met elk van de vereiste eigenschappen en waarden die de gebeurtenisfilter nodig heeft. Daarna wordt de New-CimInstance
cmdlet uitgevoerd om uiteindelijk het gebeurtenisfilter te creëren.
Het resulterende CIM-instantieobject wordt vervolgens opgeslagen in een variabele ($CIMFilterInstance
) voor later gebruik.
Voer nu Get-CimInstance
uit om te verifiëren dat de nieuwe CIM-instantie van __EventFilter
is gemaakt.

Consumer maken
Vervolgens is het tijd om de consumer te maken of de actie die zal plaatsvinden wanneer Windows de WMI-gebeurtenis activeert. Bij het maken van de consumer heb je enkele opties, afhankelijk van het type actie dat je wilt activeren.
- ActiveScriptEventConsumer – Voert een script uit in een willekeurige scripttaal zoals VBscript.
- CommandLineEventConsumer – Start een proces
Zorg ervoor dat de ACL van het uitvoerbare bestand correct is gedefinieerd om te voorkomen dat iemand het EXE-bestand vervangt door een kwaadaardig binair bestand.
- LogFileEventConsumer – Maakt een tekstlogboek.
- NTEventLogEventConsumer – Schrijft een gebeurtenis naar het Windows-gebeurtenislogboek.
- SMTPEventConsumer – Verstuurt een e-mail.
Voor deze tutorial gebruiken we het type LogFileEventConsumer
om naar een logboekbestand te schrijven wanneer de service die overeenkomt met de WQL-query wordt gewijzigd.
Elke consumentenklasse heeft zijn eigen parameters, dus controleer de
CimClassProperties
voor meer details over elke klasse, bijv.(Get-CimClass -ClassName __NTEventLogEventConsumer).CimClassProperties
.
Zodra je de consument hebt gemaakt, controleer opnieuw of deze bestaat met Get-Ciminstance
.

Het binden van het gebeurtenisfilter en de consument
Uiteindelijk is het tijd om deze abonnement af te ronden en het gebeurtenisfilter en de consument aan elkaar te binden! Zoals je misschien al geraden hebt, betekent het maken van de binding dat je nog een CIM-instantie moet maken. Deze keer moet je een nieuwe instantie maken in de klasse __FilterToConsumerBinding
.
De onderstaande codefragment gebruikt de twee eerder gemaakte instanties (het filter en de consument) als een hashtable die de eigenschappen definieert die nodig zijn om een nieuwe instantie te maken. Het wordt vervolgens doorgegeven aan New-CimInstance
zoals eerder om de binding te maken.
Zoals altijd, bevestig dat de binding is gemaakt door opnieuw Get-CimInstance
uit te voeren.
Zoals je kunt zien, bevat de binding informatie over zowel het Filter
als de Consument
.

Testen van het abonnement
Je bent eindelijk klaar! Het is tijd om de vruchten van je werk te testen! Het enige wat je nu hoeft te doen, is de status van de BITS-service wijzigen om te zien of PowerShell een vermelding schrijft naar het logbestand op C:\MyCIMMonitoring.txt.
Afhankelijk van de status van de BITS-service, stop of start het of herstart het gewoon met de Restart-Service
cmdlet.
Wacht ongeveer 10 seconden en controleer de C:\MyCIMMonitoring.txt. Je zou nu de Text
moeten zien in het logbestand dat je hebt gedefinieerd bij het maken van de consument.

Om alle WMI-eventactiviteit te controleren, bekijk het Windows-eventlogboek op het pad Toepassingen en Services Logboek\Microsoft\Windows\WMI-Activity\Operationeel.
Het stoppen en opruimen van de abonnement
Zodra je klaar bent met het abonnement, is het tijd om het op te ruimen. Om het WMI-eventabonnement te stoppen en te verwijderen, moet je de gebeurtenisfilter, consument en bindingsexemplaren verwijderen.
Verwijder de gebeurtenisfilter door eerst het exemplaar te vinden met Get-CimInstance
.

Verwijder vervolgens de consument op dezelfde manier.

Verwijder tot slot de binding. De eigenschap om de binding te vinden is een beetje anders. In plaats van de eigenschap Naam
heeft het bindingsexemplaar een eigenschap Filter
die eigenlijk een object is met een eigenschap Naam
.

Conclusie
WMI/CIM is een handig en krachtig systeem om informatie over Windows te vinden en het te monitoren met WMI-events. Het monitoren van wijzigingen met WMI-events geeft je een goed zicht en een snellere reactie op mogelijke problemen, waardoor het gemakkelijker wordt om voor elk evenement een reactie te automatiseren.
Voor een geweldig real-world voorbeeld, bekijk Hoe u Active Directory-wijzigingen kunt bijhouden met WMI-gebeurtenissen.
Source:
https://adamtheautomator.com/your-goto-guide-for-working-with-windows-wmi-events-and-powershell/