Artykuły

A A A
Drukuj Ekportuj do PDF
Opublikowane: 2011.06.29 6:00 | Bartosz Bielawski | Aktualizacja: 2011.06.29 8:25

Zdarzenia WMI (WMI Events) i PowerShell

tagi: WMI
Artykuł dotyczący pracy ze zdarzeniami WMI w Windows Powershell. Obejmuje obsługę zdarzeń w oparciu o wbudowany w PowerShell v2.0 cmdlet Register-WmiEvent, jak i o moduł PowerEvents.

Wprowadzenie

Ostatnio na WSS pojawiła się seria artykułów dotyczących WMI, nie będę więc powtarzał tego, co ktoś już dokładnie opisał. WMI w praktyce to olbrzymie źródło informacji, potencjalne narzędzie administracji i element, który pozwala śledzić zmiany w systemie – zarówno na poziomie sprzętu, jak i oprogramowania. Artykuł ten obejmuje ostatni z tych aspektów — śledzenia zmian w systemie – ale siłą rzeczy sięgać też będzie do pozostałych elementów.

Zdarzenia

Cała idea posługiwania się „zdarzeniami” nieco odwraca to, do czego administratorzy systemów przywykli. Na ogół naszą intencją jest spowodować zmianę w systemie w oparciu o nasze działanie: zatrzymujemy proces, restartujemy serwis, usuwamy pliki tymczasowe. Praca ze zdarzeniami wymaga działań niejako odwrotnych: reagujemy na to, co się w systemie dzieje. Proces zostaje zatrzymany, plik usunięty, serwis zrestartowany. To, co się dzieje dalej, zależy od naszych potrzeb. Zwykle śledząc takie zmiany pragniemy uzyskać raport (czy to w dzienniku systemowym, czy w zwykłym logu tekstowym), czasem chcemy automatycznie na takie zdarzenie zareagować (ponownie uruchomić proces, wysłać e-mail). Wymaga więc to od nas pewnej proaktywności i przewidywania tego, co się w systemie może wydarzyć (i jak najlepiej na takie wydarzenie zareagować).

Rejestracja

WMI jako baza jest olbrzymie. Odwzorowuje właściwie każdy fragment aktywności systemu. Każda zmiana w WMI może generować zdarzenie, jest więc zrozumiałe, że domyślnie większość zdarzeń nie jest rejestrowanych. Dodatkowo WMI pozwala rejestrować również zdarzenia nie dotyczące jego samego. Aby więc z bogactwa tego skorzystać trzeba mieć jakieś narzędzie, które pozwoli zarejestrować obsługę interesującego nas zdarzenia. I tu w grę wchodzą dwa scenariusze. Po pierwsze możemy potrzebować rejestracji tymczasowej. Jest to przydatne w sytuacji, gdy robimy coś nietypowego, co może przynieść negatywne skutki i wolelibyśmy pojawienie się tych skutków monitorować na bieżąco. Druga możliwość to rejestracja permanentna. Przydaje się wtedy, gdy interesujące nas zdarzenie może wydarzyć się w każdej chwili i w związku z tym chcielibyśmy je monitorować bez przerwy, od momentu, gdy system wystartuje, do momentu, gdy zostanie wyłączony.

PowerShell a WMI

Choć PowerShell nie jest jedyną opcją, przy pomocy której administrator może „skonsumować” bogactwo jakie niesie ze sobą możliwość wykorzystywania zdarzeń WMI, to jednak osobiście preferuję to narzędzie w każdym aspekcie pracy z WMI: pobieranie obiektów, korzystanie z metod, obsługa zdarzeń. Elementem decydującym jest możliwość pracy interaktywnej, poszczególne elementy można w prosty sposób przetestować, a gdy efekt nas zadowala – zapisać w formie skryptu. Obsługę zdarzeń przedstawię w oparciu o pytanie, które padło na forum WSS. Jeden z jego uczestników chciał rejestrować zdarzenie podpięcia do systemu urządzeń USB.

Register-WmiEvent

To polecenie to klucz do świata zdarzeń WMI. Pozwala ono „podpinać” się do zdarzeń WMI na czas życia sesji (lub do momentu usunięcia subskrypcji poleceń Unregister-Event). Zaletą tego rozwiązania jest to, że samo polecenie jest dość przystępne i w przypadku klas „stworzonych” do obsługi zdarzeń nie wymaga od nas nawet znajomości składni języka zapytań WMI (WQL):

Register-WmiEvent -Class Win32_ProcessStartTrace -Action {
$Nowy = $EventArgs.NewEvent
$Kiedy = $Event.TimeGenerated
$Rodzic = Get-Process -Id $Nowy.ParentProcessId
"{0}: Z procesu: {1} ({2}) uruchomiono {3} ({4})" -f $Kiedy,
$Rodzic.ProcessName, $Rodzic.Id,
$Nowy.ProcessName, $Nowy.ProcessId | Out-Host
}

Skrypt 1

Część użytych tutaj zmiennych wymagała znajomości automatycznie generowanych przez to polecenie obiektów ($Event, $EventArgs) jak i nieco znajomości „wnętrzności” (NewEvent.ProcessName/ProcessId). To wszystko jednak można łatwo sprawdzić odpowiednio modyfikując skrypt przypisany do parametru Action.

Nie zmienia to faktu, że gdy wymogi są nieco bardziej zawiłe najlepiej wykorzystać wszystkie możliwości, jakie daje składnia WQL (więcej informacji można znaleźć w darmowm e-booku autorstwa Ravikanth Chaganti WMI Query Language via PowerShell”). Po pierwsze dlatego, że składnia ta pozwala nam nieco dokładniej filtrować zdarzenia zanim trafią one do Action (a filtrować najkorzystniej jest zwykle jak najwcześniej i jak najbliżej źródła danych). Po drugie dlatego, że zapytanie WQL użyte do rejestracji tymczasowej możemy zwykle z powodzeniem wykorzystać do rejestracji trwałych.

Wracając do naszego przykładu rejestrowania wszystkich przypinanych do systemu urządzeń USB: interesują nas wszystkie nowe instancje klasy Win32_PnpEntity, których DeviceId zaczyna się od ciągu znaków USB. Jak to zapytanie wyglądałoby w WQL (do takich zapytań polecam używać herestring-ów, dają pełną elastyczność zapisu i łamania linii)?

$Query = @"
SELECT * FROM __InstanceCreationEvent WITHIN 10
WHERE TargetInstance ISA 'Win32_PnpEntity'
AND TargetInstance.DeviceID LIKE 'USB%'
"@

Jak widać WQL to młodszy (i uboższy) brat SQL. Tak czy inaczej dość szybko można „chwycić” podstawowe reguły gry i zacząć pisać zapytania dostosowane do naszych potrzeb. Samo zapytanie to jednak nie wszystko – chcieliśmy informację o podpinanych urządzeniach zapisać w pliku. Do tego użyjemy pola Action. Dla większej wygody dobrze też taką subskrypcję nazwać. Polecenie nam puchnie, więc dla większej czytelności skorzystamy ze „splattingu”.

$Rejestracja = @{
SourceIdentifier = 'USB'
Action = {
"{0}: dodano urzadzenie - {1}" -f $event.TimeGenerated,
$EventArgs.NewEvent.TargetInstance.Caption |
Out-File -FilePath C:\Windows\usb.log -Append
}
}
Register-WmiEvent @Rejestracja -Query $Query

Jak widać użyliśmy wcześniej zdefiniowanego zapytania. Oprócz tego pozostałe parametry umieściliśmy w obiekcie słownikowym (hashtable), w parach parametr – wartość parametru. Użycie takiego obiektu (zwracam uwagę na @ zamiast $ w czasie używania) zamiast podawania parametrów „w linii” nazywa się właśnie „splatting”. Chciałem jeszcze zwrócić uwagę, że zdarzenie w PowerShell ma całkiem przyjazny format pola TimeGenerated (jest to obiekt System.DateTime) – nie da się tego powiedzieć o informacji zwracanej przez WMI, o czym przekonamy się używając permanentnych subskrypcji.

skrypt 2

PowerEvents

Tak jak wcześniej wspomnieliśmy wbudowane w PowerShell 2.0 polecenia nie udostępniają narzędzi do „podpinania” się do zdarzeń na stałe. Zamknięcie okna PowerShell kończy żywot naszych subskrypcji. Dlatego wyżej przedstawiony skrypt rejestrujący wydarzenia jest użyteczny ale nie praktycznych: potrzebne jest coś co zachowa konfigurację WMI pomiędzy restartami komputera.

Na szczęście wspólnota zbudowana wokół PowerShella zwykle stara się braki niwelować. Tak jest i w tym wypadku: Trevor Sullivan stworzył moduł PowerEvents, dzięki któremu możemy tworzyć trwałe mechanizmy w WMI, które będą reagować na zdarzenia. Temat jest bardzo obszerny, polecam zapoznanie się z dokumentacją dołączoną do modułu, jak i filmami, które na stronie projektu są umieszczone. Przypadek z forum WSS w zasadzie wymaga czterech kroków (zakładam, że $Query cały czas jest zdefiniowane): # Zaimportowac modul...
Import-Module PowerEvents
# Stworzyć Event Filter używając zdefiniowanego wcześniej $Query
$USBFilter = New-WmiEventFilter -Name USB -Query $Query
# Stworzyć Event Consumer (zapisujący logi do pliku tekstowego)
$DoLogu = @{
ConsumerType = 'LogFile'
Name = 'USB'
Text = '%TIME_CREATED%: Dodano urządzenie - %TargetInstance.Caption%'
FileName = 'C:\windows\usb.log'
}
$USBConsumer = New-WmiEventConsumer @DoLogu
# Powiązać oba elementy ze sobą
New-WmiFilterToConsumerBinding -Filter $USBFilter -Consumer $USBConsumer

To wszystko. Od tej pory nie powinno nam umknąć żadne podpięte do komputera urządzenie USB.

Niestety, TIME_CREATED wygląda paskudnie. Jego opis może przyprawić o zawrót głowy:

This is a 64-bit value that represents the number of 100-nanosecond intervals after January 1, 1601. The information is in the Coordinated Universal Time (UTC) format.

Nie muszę chyba nikogo przekonywać, że taka liczba wymaga raczej konwersji na coś bardziej czytelnego dla ludzi. Trzeba tu nadmienić, że możliwości jest więcej: możemy, używając tego samego zestawu narzędzi, przesyłać informację również inaczej (Event Log, e-mail), lub też automatycznie reagować przy pomocy skryptu (VBS), czy też pełne polecenie – a co za tym idzie – również skrypt PowerShell, uruchamiany podobnie jak w przypadku skryptów uruchamianych z poziomu Task Schedulera. Wszystko zależy od wybranego przez nas „konsumenta” zdarzeń. Pełny ich opis znów wykracza poza ramy jednego artykułu i ponownie polecam lekturę dokumentacji do PowerEvents. Naprawdę, ułatwia zrozumienie idei jak i praktycznie jej zastosowanie.

Więcej

PowerEvents.codeplex.com

Windows PowerShell 2.0 – WMI Event Monitoring

Ravikanth Chaganti WMI Query Language via PowerShell

WMI jako obiektowa baza danych: WQL (4/6)


 


Autor:


Bartosz Bielawski

Bartosz Bielawski

MCTS, MCP


powershellpl.wordpress.com
W pracy "człowiek od wszystkiego".
Specjalizacja to skrypty (cmd/ vbs/ ps), WMI, AD DS.
Zakochany w PowerShell od pierwszego wejrzenia.
Moderator na oficjalnym forum Scripting Guys.
Zwycięzca 2011 Scripting Games organizowanych przez Microsoft w kategorii Advanced.

Komentarze 0 Masz uwagi do tej strony? Napisz

Dodaj komentarz

avatar

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Autor Bartosz Bielawski
avatar s
 

Moja specjalność to skrypty. Moja miłość - PowerShell. ;) Specjalizuję się w WMI i AD DS.

Załóż konto
WSS to serwis, który łączy dziesiątki tysięcy specjalistów IT w Polsce, zajmujących się szeroko pojętymi technologiami Microsoft. Portal działa od 2003 roku, i oprócz setek publikacji technicznych, rozwijającego się forum - portal to ludzie, którzy go tworzą. To właśnie z myślą o nich warto codziennie nas odwiedzać.

Dowiedz się więcej o WSS

vGuru - Zostań Guru Wirtualizacji

 

MetroOne

Idź na górę strony