Sieci i systemy komputerowe Jama Mastaha
 http://infojama.pl Newsy  ·  Artykuły ·  Forum  ·  Szukaj  ·  O nas  ·  Dodaj Newsa!  
Menu główne
Jama to nie tylko codzienna porcja wiadomości o sieciach i systemach z rodziny Windows XP i Vista oraz Windows Server 2003 i 2008

Publicystyka

Forum

Pomoc

Kontakt

O nas

Sonda
Czy zainstalowałeś już SP3 dla Windows XP?



Pokaż wyniki

Ostatnie artykuły
Windows 2003
Server

Sieci

Windows XP

Pozostałe

Redakcja
Zespół redakcyjny:
Jacek Kolonko
Adam Stępień
Sebastian Sawicki
Tomasz Sadkowski
Mikołaj Kamiński
syndrom windziarza
Marcin Jankowski
Marcin Gondek
Marcin Mierzejewski

Kontakt z redakcją:

Napisz do nas na
adres mailowy lub
na forum bądź wejdź na kanał irc #jama (np. via chat) Zapraszamy!

Szczegółowe informacje dostępne są tutaj.

Kto nas ogląda
Aktualnie przegląda
nas 20039 gości.

Wywołano nas już
1379271 razy.

Na forum znajduje
się obecnie
uczestników.

WMI - czyli zostań sys-developerem

(13421 odsłon) 



WMI, czyli Windows Management Instrumentation, jest mechanizmem pozwalającym na zarządzanie wszelakimi zasobami komputera w jednolity sposób, niezależnie od rodzaju informacji jakiej potrzebujemy: zapytania do Active Directory, informacje o sterownikach, o urządzeniach, zainstalowanym oprogramowaniu, operacje na rejestrach, a nawet badanie wskaźników wydajnościowych, dziennika zdarzeń [event log] czy operacji SNMP [Simple Network Management Protocol]. Dużo?

Osoby, które jeszcze nie zwróciły uwagi, niech zastanowią się jak to możliwe, żeby do informacji tak od siebie odległych tematycznie można było dostawać się w jednolity sposób, i za pomocą jednego tylko interface'u. Interface'm tym jest właśnie WMI. Ideę tego jak to wszystko funkcjonuje najlepiej oddają dwa rysunki:

rys.1 WBEM common model for network management
[rys.1 WBEM common model for network management]
rys.2 WMI architecture
[rys.2 WMI architecture]
Nie trzeba być naddto spostrzegawczym, żeby zauważyć, że na obu rysunkach pojawiło się kilka dziwnych skrótów. Zanim zacznie się pisać skrypty [czy też programy] warto mieć ogólne pojęcie teoretyczne co i jak działa. Postaram się oszczędzić Niecierpliwych i opisać to możliwie zwięźle:
  • WBEM - Web-Based Enterprise Management: jest standardem opracowanym przez kilka firm [Microsoft, Compaq, BMC, Cisco, Intel], definiującym uniwersalny i jednolity sposób dostępu do informacji pomagających zarządzać sprzętem/oprogramowaniem w całej strukturze korporacji, bez względu na to, o jakie urządzenie czy też system chodzi. WMI jest Microsoft'ową implementacją WBEM - czyli mówiąc w skrócie WMI to WBEM by Microsoft.
  • CIM - Common Information Model: ogólnie mówiąc jest to zorientowany obiektowo schemat [repozytorium] zarządzanych obiektów. Czyli po ludzq: żeby się czegoś dowiedzieć, warto najpierw kogoś/czegoś zapytać o co wogóle można się odpytywać. Rolę takiego informatora pełni właśnie CIM. A konkretnie CIMOM [CIM Object Manager].

    Oba rysunki w zasadzie przedstawiają schemat tego samego mechanizmu, z trochę innej perspektywy - rys. 1. pokazuje cały mechanizm na wyższym poziomie abstrakcji - samą ideę działania. Rys. 2. dotyczy konkretnie WMI [czyli konkretnej implementaji WBEM]. Razem tworzą pełny obraz 'co i jak'. Czyli:

    • są sobie jakieś zasoby [rys.2 - Managed System]
    • tymi zasobami mogą być różne części systemu [rys.1 - PC Hardware, Network...]
    • każdy zasób jest reprezentowany w systemie przez jakiś driver [inaczej system nie potrafiłby go obsłużyć] [rys.1 WDM Kernel Object, SNMP Object...] a dostęp do tegoż drivera umożliwia nam konkretny provider za pomocą jakiegoś tam API [rys. 2. - Provider]
    • taraz dla zmyłki od góry - jest sobie klient, konsument, czy też po prostu osoba zainteresowana pewnymi informacjami, reprezentowana przez jakąś aplikację czy też skrypt WMI [tak jak sprzęt jest ogniwem łączącym pomiędzy światem fizycznym a systemem operacyjnym, tak aplikacja jest łącznikiem między użytkownikiem a systemem] [rys. 2 - Management Application]
    • po uruchomieniu aplikacja odwołuje się do CIM żeby dowiedzieć się jakie obiekty są dostępne. Możemy oczywiście odwoływać się od razu do konkretnego obiektu, jeśli wiemy, że taki jest i jak się nazywa.
    • no i tu się wszystko zbiega - CIMOM to repozytorium dostępnych klas obiektów, ich providerzy natomiast są podpięci do CIMOM za pomocą interface'ów COM. Jeśli ktoś nie bardzo wie jak jest zbudowany windows to może się to wydawać trochę namieszne. Nie należy się zrażać - po prostu trzeba przyjąć, że każdy provider udostępnia pośrednika - obiekt COM - za pomocą którego może dogadać się z CIMOM [tak btw. to polecam lekturę artykułu o WSH jeśli jeszcze tego nie zrobił[a]eś. w zasadzie można go potraktować jako poprzedzającą część tego co masz teraz przed oczami].
    Teraz coś, co powinno pomóc tym, którzy się trochę pogubili, czyli kilka standardowych provider'ów w windowsie:
    • Win32 Provider - który jest odpowiedzialny za dostarczanie informacji o systemie operacyjnym [typu: jaki to jest OS, którego ma Service Packa etc], urządzeniach peryferyjnych, systemu plików, informacje o bezpieczeństwie.
    • Registry Provider - pozawalający na wszelkiego rodzaju operacje na rejestrze systemu.
    • Event Log Provider - umożliwiający odczytywanie/backup'owanie informacji w Event Log'u [dzienniku zdarzeń] oraz konfiguracji jego parametrów.
    To oczywiście tylko kilka - żeby jak najszybciej przejść do praktyki, a więcej można sobie zawsze potem doczytać. Teraz kilka przykładów:

    Przykład 1.

    Jak wyświetlić wszystkie service'y w systemie:

    Set ServiceSet = GetObject("winmgmts:").InstancesOf("win32_Service")
    for each Service in ServiceSet
        WScript.echo Service.Description
    next
    
    Skrypcik jest banalny, ale należy się trochę teorii i wyjaśnień:
    1. tworzymy obiekt typu winmgmt [Window Management]. Jeśli zobaczymy na wynik tego skryptu, pojawił się tam m.in. "Windows Management Instrumentation" - jest to service pełniący rolę CIMOM. Dla tego podłączamy się właśnie do niego [rys. 2.]. Pliki odpowiedzialne za WMI znajdują się w katalogu %windir%/system32/wbem.
    2. "winmgmts:" to najprostrzy z możliwych monikerów - informacje o tym jak w pełni zbudowany jest moniker znajdują się dalej. Ale proponuję czytać po kolei.
    3. dalej jest "InstancesOf", które świadczy o obietowej budowie CIM. Jest to żądanie dostępu do instancji obiektów win32_Service. W wyniku otrzymujemy kolekcję [zbiór] obiektów typu win32_Services.
    4. no i pozostaje dla każdego obiektu [for each Service] w kolekcji obiektów jaką zwróciła metoda "InstancesOf" [in ServiceSet] wyświetlić jego opis [WScript.echo Service.Description]

    Przykład 2.

    Trochę o WQL, filtrowaniu i kolejny moniker

    queryString = "select * from Win32_Service where State='Stopped' and StartMode='Auto'"
    Set ServiceSet = GetObject("winmgmts://.").ExecQuery(queryString)
    if ServiceSet.Count <> 0 then
    	for each Service in ServiceSet
    		WScript.echo Service.Description
    	next
    else 
    	WScript.echo "no services stopped, with 'auto' state mode."
    end if
    
    1. najłatwiejszym sposobem tworzenia zapytań i filtrowania jest WQL - WMI Query Languange - stworzony na wzór i podobieństwo swojego ojca - SQL'a. W powyższym przykładzie przedstawiono sposób na wylistowanie tych service'ów, które mają ustawioną właściwość startu na 'Auto' , a z jakiegoś powodu w tym momencie nie działają [where State='Stopped' and StartMode='Auto'].
      Jeśli ktoś zna SQL'a - to 'jest w domu' ponieważ WQL jest jego uproszczoną wersją. Osoby, które z nim do czynienia jeszcze nie miały, nie mają również powodu do zmartwienia - język jest dość intuicyjny i większość podstawowych rzeczy będzie się w stanie zrobić na podstawie przykładów z np. tego artykułu.
    2. pojawił się również nieco wzbogacony moniker - "//" oddziela typ obiektu od reszty zapisu. Ponieważ w poprzednim przykładzie 'resza zapisu' nie wystąpiła, nie było konieczności, żeby to wstawiać. Tutaj reszta zapisu jest reprezentowana przez ".", oznaczającą komputer lokalny. Jeśli zastąpimy ją ciągiem "jakiskompwsieci", to dostaniemy listę service'ów na komputerze "jakiskompwsieci".
    3. wniosek z tego taki, że "." jest defaultowym kontextem i jeśli chodzi nam o komputer lokalny to możemy sobie ją pominąć. Prawidłowy więc będzie również moniker: "winmgmts://"

    Przykład 3.

    wolne miejsce na dyskach czyli bardziej zaawansowane zapytanie WQL, no i oczywiście kolejny moniker

    queryString = "select FreeSpace,Size,Name from Win32_LogicalDisk where DriveType=3"
    strCompName="."
    
    Set diskSet=GetObject("winmgmts:{impersonationLevel=impersonate}//"&strCompName).ExecQuery(queryString)
    for each disk in diskSet
    	tSize = cstr( cint(Disk.Size/1024/1024) )
    	prcFree = "( "+cstr(cint( (Disk.FreeSpace/Disk.size)*100) )+"% )"
        WScript.echo "Drive " + Disk.Name + " total: " + tSize + " Mb free: " + prcFree
    next
    
    1. w tym przykładzie zapytanie zostało zoptymalizowane, poprzez wyselekcjonowanie konkretnych atrybutów, z których będzie korzystał skrypt - FreeSpace, Size i Name - dzięki czemu wyszukiwanie powinno być szybsze a odpowiedzi 'mniejsze' - co ma znaczenie przy zapytaniach do zdalnej maszyny.
    2. pojawiło się również kolejne rozszeżenie monikera - które jak każde do tej pory nic nie wnosi, ponieważ po prostu jawnie wpisywane są ustawienia default'owe. "impersonationLevel" jest atrybutem związanym z kontextem modelu bezpieczeństwa w WMI. Ponieważ zmieniając nazwę komputera z "." na nazwę jakiegoś komputera w sieci możemy zarządać informacji innego systemu, pojawia się problem uprawnień - zupelnie niefajnie by było, gdyby każdy chętny mógł się dowiedzieć wszystkiego o naszym systemie. Standardowo uprawnienia do połączenia się z service'm "Windows Management Instrumentation" mają użytkownicy należący do grupy administratorów. Słowo "impersonate" oznacza, że skrypt będzie wykonywany w kontexcie użytkownika, który go uruchamia.
    3. "DriveType=3" oznacza, iż chodzi nam wyłącznie o dyski stałe [nie CD, nie flopy ani inne wynalazki]

    Przykład 4.

    Pierwsza zmiana... i kolejny moniker

    queryString="select * from win32_computerSystem"
    strCompName="."
    credentials="{impersonationLevel=impersonate}"
    
    set oCollection=GetObject("winmgmts:"&credentials&"//"&strCompName&"/root/CIMv2").ExecQuery(queryString)
    for each o in oCollection
    	o.SystemStartupDelay=3
    	o.put_()
    next
    
    1. Do tej pory przykłady pokazywały wyłącznie sposób na wydobycie jakiejś informacji - czyli pobierały wartość atrybutu [Property]. —eby pokazać, iż WMI daje również możliwość modyfikacji parametrów oto przykład zmieniający czas oczekiwania na wybór systemu podczas startu komputera - do czego wykorzystuje się metodę [Method] "put_()".
    2. pomimo, że na komputerze może działać tylko jeden system operacyjny na raz [tak - ja wiem, że jest np. VMware ale WMI nie wie], to należy wykonać iterację przez wszystkie jeden obiekt - ponieważ przy takim zapytaniu zwracany jest zawsze obiekt typu 'collection'.
    3. staram się pisać skrypty tak, żeby na początek wyrzucać rzeczy, które już były, więc są mniej ciekawe. Poza tym forma skryptów staje się coraz bardziej uniwersalna - ponieważ mam nadzieję poza WMI przybliżyć sposób pisania [IMHO] porządnych skryptów.
    4. moniker rozrósł się o kolejny nieprzydatny fragment - "/root/CIMv2". Tym razem jest to określenie domeny nazewniczej [namespace]

    Przykład 5 i 6.

    Backup EventLoga i reboot zdalnej maszyny czyli jeszcze troche o monikerach

    [topic extremalnie po polsq (;]
    ON ERROR RESUME NEXT
    queryString="select * from win32_NTEventLogFile where LogFileName='Application'"
    strCompName="."
    specRight="(Backup)"
    credentials="{impersonationLevel=impersonate,"&specRight&"}"
    cimContext="/root/CIMv2"
    
    set oCollection=GetObject("winmgmts:"&credentials&"//"&strCompName&cimContext).ExecQuery(queryString)
    for each o in oCollection
    	errHandle( o.BackupEventLog("c:tempApplicationEventLogBackup.evt") )
    	errHandle( o.ClearEventLog() )
    next
    
    Sub errHandle(errLevel)
    	if errLevel = 0 then
    		WScript.echo "DONE."
    	else
    		WScript.echo "error: "&errLevel
    		WScript.quit
    	end if
    End Sub
    
    1. z mniej ważnych [w kontexcie tego artu] doszła prymitywna procedurka do obsługi błedów
    2. wywołane zostają dwie metody dostępne dla obiektu typu 'NTEventLogFile': BackupEverntLog oraz ClearEventLog. Nazwy metod same mówią o swoim przeznaczeniu...
    3. no i oczywiście moniker - tym razem rozwinięty o coś niezbędnego - żądanie specjalnego prawa dostępu "(Backup)" pozwalającego na wykorzystanie w/w metod.
    I przykładzik pokazujący jak wyłączyć komputer - również wymaga uaktywnienia specjalnego prawa systemowego - tym razem "(Shutdown)" [przyczytaj art do końca, zanim przestujesz ten skrypt (;]:
    queryString="select * from win32_OperatingSystem"
    strCompName="."
    specRight="(Shutdown)"
    credentials="{impersonationLevel=impersonate,"&specRight&"}"
    cimContext="/root/CIMv2"
    
    set oCollection=GetObject("winmgmts:"&credentials&"//"&strCompName&cimContext).ExecQuery(queryString)
    for each o in oCollection
    	'o.shutdown()
    	o.reboot()
    next
    
    1. ciekawostką jest to, że w literaturze można również natknąć się na prawo "(RemoteShutdown)". Ale wtedy nie można zrebootować lokalnego systemu. Warto z tego korzystać jesli mamy uniwersalny skrypcik bootujący i chcemy zabezpieczyć się przed tym, żeby przypadkiem nie zbootować lokalnego systemu - to jak z podcinaniem gałezi na której się siedzi.
    2. linijka o.shutdown jest wykomentowana ponieważ shutdown bez parametru doprowadza system do momentu "you can safely..."...

    Przykład 7.

    Troche o zdarzeniach - czyli badanie wydajności

    Option Explicit
    ON ERROR RESUME NEXT
    Dim queryString,strCompName,credentials
    Dim evt
    Dim i, NTevent
    
    queryString="select * from __instanceModificationEvent within 1 where targetInstance isa 'Win32_Processor'"
    strCompName="."
    credentials="{impersonationLevel=impersonate}"
    
    set evt = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecNotificationQuery(queryString)
    errHandle(err)
    i=0
    do while i<10
        set NTevent=evt.nextevent
        errHandle(err)
        performAction(NTevent)
        i=i+1
    loop
    
    Sub errHandle(oErr)
        if oErr<>0 then
            Wscript.echo oErr.Number, oErr.description, oErr.source
            wscript.quit
        end if
    End Sub
    
    Sub performAction(e)
        wscript.echo e.targetInstance.deviceID&": "&e.targetInstance.loadPercentage&"%"
        if e.targetInstance.loadPercentage>80 then performCritical(e)
    end Sub
    
    Sub performCritical(e)
        wscript.echo "CRITICAL!"
    end sub
    
    1. było do tej pory o atrybutach [Properties] oraz metodach [Methods] - nadszedł czas na prezentację kolejnego mechanizmu: obsługi zdarzeń [Event Handling]. Jest to dość potężny mechanizm, jeśli chodzi o możliwość praktycznego zastosowania - ustawia się 'pułapkę na zdarzenie' i w razie, gdy zostanie uruchomiona, wykonywana jest jakaś akcja. W niniejszym przykładzie queryString jest tak sformuowany, iż akceptuje wszystkie zdarzenia. Jest to przydatne do ciągłego monitorowania. Poza tym w obsłudze akcji jest warunek krytyczny i wykonanie akcji krytycznej - moża tam np. wstawić wysyłanie sms'a na komórkę.
    2. z ciekawych rzeczy w queryStringu pojawiło się słówko 'whithin' określające częstość wykonywania akcji w sekundach. Podczas testów nie zdziwcie się, jak różną długość mają sekundy (;
    3. w odróżnieniu od poprzednich przykładów wykonywane jest 'ExecNotificationQuery' czyli żądanie powiadomienia.
    4. pętla jest ustawiona na 10 zdarzeń w celach testowych. Można wyrzucić ten warunek żeby działała w nieskończoność.
    5. jeśli nie interesuje nas ciągły monitoring, a jedynie sprawdzanie wartości krytycznych, można zoptymalizować program modyfikując queryString na "select * from __instanceModificationEvent within 1 where targetInstance isa 'Win32_Processor' and targetinstance.LoadPercentage>80" co spowoduje, że skrypt będzie otrzymywał jedynie zdarzenia krytyczne [czyli niepotrzebna jest również jedna z procedurek].
    6. nie trudno się domyśleć, że w ten sposób można modyfikować wszystko to, co można również robić za pomocą performanceMonitora
    7. jedyną uwagą z praktyki jest to, że czasem dość dziwnie się to zachowuje - czasem się jakby blokuje, sekundy mają różną długość i tym podobne... no ale to juz pozostawiam bez dodatkowych komentarzy. 'wyjdzie w praniu'.

    Skąd brać informacje o obiektach i ich właściwościach

    Jak do tej pory wszystko ładnie - tylko brakuje nadal bardzo ważnego elementu. Teraz warto byłoby napisać coś samemu - i skąd wziąć informacje na temat obiektów, ich nazw i właściwości? Na to jest wiele sposobów.
    Jako pierwszy podam bardzo przydatny obrazek [>700kb!], który warto sobie powiesić nad biurkiem, jeśli będzie się pracowało z WMI. Obrazek ten to część schematu obiektów WMI. Nie jest to oczywiście pełny schemat, ale są na nim najważniejsze rzeczy.

    Bardziej przydatnym zestawem narzędzi jest WMI SDK. SDK czyli Software Developement Kit jest dodawany do większości produktów Microsoftu w celu ułatwienia develeperom wykorzystanie istniejących mechanizmów. Wszelkie niezbędne narzędzia, które ułatwią pracę z WMI można zassać ze stron Microsoftu. Jest to zestaw narzędzi składający się z CIM viewer'a i Object viewer'a - przydatnego do sprawdzenia jakie są obiekty, ich metody etc, Event Viewera i Event Registrator'a - pomocnego przy pracy ze zdarzeniami.

    Bardzo śmiesznym narządkiem, od którego polecam zacząć, jest scriptomatic. Nie mogę go znaleść teraz na stronkach MS więc umieszcam do zassania z niniejszej paginy. Programik służy do automatycznego generowania skryptów WMI. Cały pliczek wraz z komentarzami [ok. 50%] zajmuje 11Kb więc nie należy liczyć na nic rozbudowanego, a zarazem zdumiewa pomysłowością i jest wspaniałym przykładem na to, co i jak można zrobić za pomocą WMI. Pokazuje jak samemu - bez dodatkowych narzędzi - można dowiedzieć się jakie są klasy, obiekty i parmetry. Polecam przejrzeć źródło. Wraz ze skryptem dostarczona jest dokumentacja napisana przez jego twórców.

    Monikery

    Pozostaje skończyć wątek, który wplatał się gdzieś w międzyczasie - czyli jeszcze kilka słów o monikerach. Wszystkie możliwości monikera przedstawia poniższy skrypt:

    auth=",authority=ntlmdomain:mydomain"
    authLv=",authenticationLevel=pktPrivacy"
    specRight=",(Debug,!Shutdown)"
    impLv="{impersonationLevel=impersonate" & authLv & auth & specRight & "}"
    strLocale="[locale=ms_409]"
    strCompName="."
    strNameSpace="ROOTCIMV2"
    strClass="Win32_LogicalDisk=""C:"""
    
    strMoniker= impLv & strLocale & "!" & strCompName & strNameSpace & ":" & strClass
    
    Set monikerTest = GetObject("winmgmts:" & strMoniker )
    wscript.echo monikerTest.size
    
    W powyższym przykładzie widać chyba wszystkie możliwe części monikera - część dotycząca autoryzacji, specjanych uprawnień, ustawienie lokali [strona kodowa], nazwa systemu, kontext nazewniczy oraz klasa do której się dołączamy, wraz z konkretną instancją obiektu.

    Resumeé

    Także na pytanie "co to jest WMI" odpowiedź jest następująca:
    WMI jest implementacją WBEM zatwierdzoną przez DMTF i opartą na CIMOM, który pośredniczy pomiędzy konsumentem WMI a provider'em konkretnego zasobu-obiektu poprzez obiekt COM.

    A bardziej poważnie:
    WMI jest mechanizmem o bardzo prostej idei a dającej potężne możliwości - zwłaszcza osobom zajmującym się na codzień administracją systemów. Czyli nie będących stricte developerami, ale potrzebującymi narzędzi, których brakuje. WMI daje możliwość napisania sobie narzędzi samemu w stosunkowo prosty sposób.

    Linki/referencje

    Będę wdzięczny za wszelkie uwagi lub/oraz informacje - co jeszcze chciał[a]byś się dowiedzieć.
    nExoR

  •   


    [ Indeks sekcji ]

    Komentarze Dodaj komentarz» Nie napisano jeszcze ani jednego komentarza. Twój może być pierwszy...


    Dodaj swój komentarz
    Autor:  
    Komentarz:
    Dodaj komentarz

     

    Grupa CentrumXP.pl

    O Jamie Mastaha  |  O Grupie CentrumXP.pl

    Nasze serwisy: CentrumXP.pl |  Sklep on-line  |  Komputer w firmie  |  Xbox 360  |  Live Blog  |  MS Blog Jama Mastaha |  Developers.pl