Windows Management Instrumentation
« | 16 May 2020 | »Es gibt zahlreiche Infos zu WMI, der Windows Management Instrumentation, im Netz. Die ältesten und reinsten davon entspringen der VBScript Zeit rund um die 2000er. Heute ersetzen oft dotNET und PowerShell Konstrukte all das, was im Hintergrund bis heute mit WMI erledigt wird.
Wenn man aber in C++ “gegen” WMI programmiert, braucht man einige Meta-Informationen, die man nicht sofort findet, wenn man “WMI” in die Suchanfrage tippt.
Im GATE Projekt übernimmt die Bibliothek gate/system/management.h
die Kommunikation mit Verwaltungsroutinen des Betriebssystems.
Unter Windows wird hier WMI implementiert.
Das ganze ist ein Baum von Pfaden und Objekten, die Einstellungen und Methoden bereitstellen, also all das, was WMI selbst auch bietet.
Doch während Scripts für spezifische Aufgaben diverse WMI Pfade “hardcoden”, verlangt der generische Ansatz, dass Infos darüber, was verfügbar ist und was nicht, zur Laufzeit ausgelesen wird.
Besondere WQL Anfragen
Ein paar dieser WMI-Qery-Language (WQL) Suchanfragen möchte ich hier mal zusammenfassen:
-
SELECT * FROM __NAMESPACE
Die Instanzen von__NAMESPACE
sind die Unternamensräume des aktuell verbundenen. Wenn man also zum NamespaceROOT
verbunden ist, erhält man unter anderem den bekannten EintragCIMV2
.
Das Objekt enthält die EigenschaftName
, dessen Inhalt direkt zur Erzeugung des Pfades benutzt werden kann. Beispiel-Ergebnis-Pfad:\\MYPCNAME\ROOT:__NAMESPACE.Name="Hardware"
-
SELECT * FROM META_CLASS
So listet man alle Klassen in einem Namespace auf. Die Objekte haben zwar keine Eigenschaften, aber der Pfad endet eben auf den Klassennamen. Man kann ihn einfach nach dem Doppelpunkt auslesen.
Beispiel-Ergebnis-Pfad:\\MYPCNAME\ROOT\CIMV2:Win32_PrinterShare
Mit diesen Routinen kann man sich bereits einen WMI Namespace aussuchen und # alle seine Objekt auflisten.
Hat man dann eine Auflistung von IWbemClassObject
Instanzen, kann man über
BeginEnumeration
zwei Arten von Eigenschaften auslesen:
- Das Flag
WBEM_FLAG_SYSTEM_ONLY
bewirkt, dass nur die Infrastruktur-Eigenschaften wie__PATH
oder__CLASS
zurückgegeben werden. So findet man den direkten Pfad eines Objektes, den man für spätere Aufrufe brauchen kann. - Mit dem Flag
WBEM_FLAG_NONSYSTEM_ONLY
erhält man alle Eigenschaften, die Daten des Objektes beinhalten, also alles was uns eigentlich interessiert.
Natürlich gibt es noch ein paar andere Flags um z.B. vererbte Eigenschaften auszuschließen usw., doch für meine Zwecke waren diese bisher nie erforderlich.
Anwendungen
Über WMI lässt sich verdammt viel in Windows anstellen. Nicht nur, dass alle möglichen Einstellungen des OS oder von Geräten und Treiber ausgelesen werden können, sondern wir erhalten hier exklusiv Zugriff auf Dienste wie:
- IP Addressen und deren Konfiguration (Routen, etc.)
- Hyper-V Einstellungen und VMs
- Write Filter (in Windows 10 IOT)
- BIOS/EFI Parameter
- Boot Optionen
- Dienste und ihre Konfiguration
- Die Windows Registry
- Event Logs (und zwar bereits mit ausgewerteten Texten)
- Installierte Programme
- Netzwerkfreigaben und das Dateisystem (man kann sogar noch Dateien mit Mustern suchen lassen)
- Zahlreiche Windows (und Windows Server) Dienste
- und vieles mehr
Fazit
Kurz gesagt: Alles was der Admin braucht, findet er in WMI. Und deshalb
basiert auch vieles in der PowerShell, der Remote-Shell und dem dotNET
Namespace System.Management
auf dieser Technologie.
Einen Nachteil möchte ich nicht verschweigen: WMI wurde als synchrone API konzipiert und seine Reaktionszeiten sind … naja, nicht immer schnell.
Frameworks gestatten zwar die asynchrone Nutzung von WMI und erlauben somit auch Abbrüche von Anfragen, doch das beendet in der Regel nicht den Prozess im Hintergrund, der die Daten sammelt.
Wer also viel mit WMI “parallel” machen möchte, wird schnell seine CPU Auslastung hochtreiben.
Wie auch immer … für Administrationsaufgaben ist diese Schnittstelle unabdingbar.