sobota 8. srpna 2009

Získávání informací z WMI

V jednom z předchozích článků jsem slíbil, že se někdy podrobněji podíváme na přístup do WMI pomocí PowerShellu. Ta doba právě nastala :)
O WMI (Windows Management Instrumentation) jste jistě alespoň slyšeli. Pokud ne, určitě vám doporučuji se podívat, k čemu je WMI dobré - můžete začít na Wikipedii nebo na stránkách Microsoftu. Pro potřeby tohoto článku budu předpokládat, že máte alespoň základní představu o tom, k čemu WMI slouží.
Úkol pro všechny následující příklady bude stejný: zjistit všechny běžící procesy s názvem notepad.exe a vypsat jejich ProcessID. Na konci každého příkladu uvedu průměrný čas rychlosti zpracování pro 10 stejných dotazů.
Filtrování pomocí Where-Object
Zrějmě prvním nápadem bude použití standardních příkazů PowerShellu bez nějakého hlubšího zkoumání dalších okolností.
PS C:\> gwmi Win32_Process |? {$_.Name -eq 'notepad.exe'} | select ProcessId
ProcessId
---------
     2072
     5228
Tento postup je přímočarý a pokud potřebujete z WMI "tahat" data pouze příležitostně, bude vám zřejmě stačit. Pokud budete s WMI pracovat častěji (a budete zpracovávat větší množství dat) začne vám za chvíli vadit rychlost (resp. pomalost) zpracování dat. Nevýhodou tohoto přístupu je totiž to, že čtete z WMI všechny procesy a ty pak rourou posíláte cmdletu Where-Object (v mém příkladu zastoupeném jeho aliasem '?' - znak otazník).
Rychlost: 1535 ms
Parametr -Filter
Cmdlet Get-WmiObject má parametr -Filter. Použítím tohoto parametru filtrujete data již na úrovni WMI a dále pracujete pouze s procesy (objekty), které splňují zadané kritérium.
PS C:\> gwmi Win32_Process -filter "name='notepad.exe'" | select ProcessID

ProcessID
---------
     2072
     5228
Rychlost zpracování v tomto případě je 595 ms. Cmdlet Select-Object (resp. jeho alias select) je v tomto případě použit z toho důvodu, že filter nám vrací všechny vlastnosti a my jsme na začátku řekli, že budeme vypisovat pouze ID procesu.
Parametr -Query
Pokud ovládáte jazyk WQL (WMI Query Language) můžete pomocí něj specifikovat dotaz v parametru -Query. Celý příkaz by pak vypadal následovně:
PS C:\> gwmi -Query "SELECT ProcessID FROM Win32_Process WHERE Name='notepad.exe'"

__GENUS : 2
__CLASS : Win32_Process
__SUPERCLASS :
__DYNASTY :
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 2072

__GENUS : 2
__CLASS : Win32_Process
__SUPERCLASS :
__DYNASTY :
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 5228
PowerShell přidal do výpisu ještě několik vlastností, které nás momentálně nezajímají (začínají dvěma podtržítky). Pokud bychom je chtěli odstranit, můžeme opět použít cmdlet Select-Object. Rychlost zpracování byla 573 ms.
Shrnutí
Z předchozích příkladů je vidět, že pokud chcete pracovat s WMI je dobré si rozmyslet, jakým způsobem k němu budete přistupovat. Pokud občas potřebujete okamžitý výsledek z lokálního počítače (a vámi dotazovaná třída nemá tisíce členů), první postup vám možná bude vyhovovat. V případě většího množství dat (případně dotazů na vzdálený počítač) je dobré se naučit používat parametry -Filter nebo -Query.

Žádné komentáře: