Windows Management Instrumentation

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 Namespace ROOT verbunden ist, erhält man unter anderem den bekannten Eintrag CIMV2.
    Das Objekt enthält die Eigenschaft Name, 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.