Windows PowerShellDie WMI-Verbindung

Don Jones

Eine der Technologien, auf die ich mich im Bereich VBScript bisher überwiegend verlassen habe, ist die Windows-Verwaltungsinstrumentation oder WMI. Interessanterweise hat Windows PowerShell starke Verbindungen zur WMI, und das nicht nur in technischer Hinsicht. Jeffrey Snover, der Entwickler von Windows PowerShell, war auch wesentlich an der Erstellung von

Wmic.exe beteiligt, einem Befehlszeilenprogramm für Windows Server® 2003, das für die Arbeit mit WMI verwendet wurde. In vielerlei Hinsicht war Wmic.exe ein Vorläufer von Windows PowerShell™, da es in der Funktionsweise gewisse Ähnlichkeiten gibt. (Weitere Informationen zu WMIC finden Sie im Artikel von John Kelbley in der Ausgabe des TechNet Magazins vom September 2006, der online unter microsoft.com/technet/technetmag/issues/2006/09/WMIData verfügbar ist.)

Windows PowerShell umfasst Unterstützung für WMI, die in der gleichen konsistenten objektbasierten Weise bereitgestellt wird, wie Sie dies bei allen anderen Funktionen der Shell gewohnt sind. Dadurch ist es besonders in Ad-Hoc-Situationen viel leichter, WMI zu erlernen und zu verwenden als frühere Technologien, wie VBScript.

Eine Einführung in WMI

Wenn Sie Bücher und Artikel zur Skripterstellung lesen, ist es beinahe unmöglich, WMI zu übersehen. Es gehört jedoch nicht viel dazu, sich so sehr in die tatsächliche Anwendung von WMI zu vertiefen, dass Sie vergessen, wie WMI unter der Oberfläche aufgebaut ist. Dabei ist der Aufbau von WMI für die Funktionsweise in Windows PowerShell außerordentlich wichtig.

WMI ist im Grunde ein System organisierter Klassen, die die Verwaltungsinformationen des Windows®-Betriebssystems und anderer Windows-basierter Hardware- und Softwareprodukte darstellt. Eine Klasse ist wirklich nicht mehr als eine abstrakte Beschreibung der Eigenschaften und Funktionen einer bestimmten Software- oder Hardwarekomponente. Zum Beispiel könnte eine logische Datenträgerklasse ein Gerät beschreiben, das eine Seriennummer, einen festen Speicherplatz, eine bestimmte verfügbare Kapazität usw. hat. Demgegenüber könnte eine Klasse, die einen Windows-Dienst beschreibt, angeben, dass der Dienst einen Namen hat, dass er starten und anhalten kann, den aktuellen Status und so weiter.

In WMI stellen Klassen all die Dinge dar, die WMI verwalten kann. Wenn in WMI keine Klasse für eine Komponente vorhanden ist, kann die Komponente nicht verwaltet werden. Microsoft dokumentiert die zentralen Windows-WMI-Klassen unter msdn2.microsoft.com/aa394554.aspx. Andere Produkte, z. B. Internetinformationsdienste und SQL Server™, dokumentieren die WMI-Klassen separat.

Aufgrund der großen Anzahl von Klassen werden sie in WMI in eine Hierarchie von Namespaces eingeteilt. Zum Beispiel lautet der Namespace, der die Windows-Betriebssystemklassen enthält, root\cimv2, während die Klassen in Microsoft IIS 6.0 in root\Microsoft­IISv2 gespeichert werden. Praktischerweise ist der root\cimv2-Namespace der WMI-Standardnamespace. Diese Einstellung ist für Windows PowerShell freigegeben, was das Arbeiten mit diesen zentralen Klassen erleichtert.

Eine „Instanz“ ist ein tatsächliches Vorkommen einer Klasse. Wenn Ihr Computer zum Beispiel über zwei logische Datenträger verfügt, erhalten Sie zwei Instanzen der Win32_LogicalDisk-Klasse. Wenn Sie auf dem Computer 50 Dienste ausführen, werden WMI 50 Instanzen der Win32_Service-Klasse angezeigt. Das Arbeiten mit WMI besteht grundsätzlich in einer Aufforderung an WMI, eine oder mehr Instanzen bereitzustellen, und dem anschließende Untersuchen der Eigenschaften dieser Instanzen, um die benötigten Verwaltungsinformationen zu finden, oder dem Ausführen der Methoden dieser Instanzen, um Verwaltungsänderungen vorzunehmen, wie das Starten oder Beenden eines Diensts.

WMI verwendet eine Clientserverarchitektur. WMI wurde in alle Windows-Versionen ab Windows 2000 integriert (in späteren Versionen wurde die Anzahl verfügbarer Klassen erweitert). Ihnen stehen also sowohl der WMI-Client als auch die WMI-Serversoftware sofort zur Verfügung. Wenn Sie WMI verwenden, senden Sie im Grunde eine Anforderung an den WMI-Dienst, der auf einem beliebigen für Sie interessanten Computer ausgeführt wird. Dieser WMI-Dienst ruft die von Ihnen angegebenen WMI-Instanzen ab und gibt sie zurück, sodass Sie mit ihnen arbeiten können. An dieser Stelle kommt Windows PowerShell zum Tragen, denn sie vereinfacht den Vorgang, bei dem Instanzen angefordert, zurückgegeben und bei der Arbeit verwendet werden.

Abrufen eines WMI-Objekts

WMI-Klasseninstanzen werden allgemein als Objekte bezeichnet. Deshalb ist es logisch, dass die Instanzen in Windows PowerShell über das Get-WMIObject-Cmdlet abgerufen werden. Dieses Cmdlet hat ein praktisches Alias, gwmi, das im Folgenden für die meisten Beispiele verwendet wird. Die einfachste Möglichkeit ist, den WMI-Klassennamen anzugeben, der abgerufen werden soll, und anschließend in aller Ruhe die Ergebnisse zu betrachten (siehe Abbildung 1). Als ich gwmi win32_service ausführte, stellte Windows PowerShell eine Verbindung zum WMI-Dienst auf meinem lokalen Computer her, da ich keinen anderen Computer angegeben hatte, sowie eine Verbindung zum root\cimv2-Namespace, da ich keinen anderen Namespace angegeben hatte. Windows PowerShell hat alle Instanzen der angegebenen Klasse abgerufen, und da ich keine andere Anweisung für den Umgang mit diesen Instanzen gegeben hatte, wurden sie in eine Textdarstellung konvertiert. Anders gesagt hat Windows PowerShell anhand dieser Objekte einen Text erstellt, der vom Menschen lesbar ist.

Abbildung 1 Beim Ausführen von gwmi win32_service gibt Windows PowerShell alle Instanzen der angegebenen Klasse in einem lesbaren Textformat zurück.

Abbildung 1** Beim Ausführen von gwmi win32_service gibt Windows PowerShell alle Instanzen der angegebenen Klasse in einem lesbaren Textformat zurück. **

Insbesondere konvertiert Windows PowerShell durch das Lesen und Anzeigen der Namen und Werte ausgewählter Klasseneigenschaften WMI-Objekte in Text. Für die Win32_Service-Klasse wird ein Satz von sechs Eigenschaften ausgewählt.

Auf diese Weise wird in Windows PowerShell jedes beliebige Objekt in Text konvertiert. Die Eigenschaften, die für die Anzeige ausgewählt werden, sind zum größten Teil in einem Satz von .format.ps1xml-Dateien definiert, die sich im Windows PowerShell-Installationsordner befinden. Diese Formatdefinitionsdateien werden digital von Microsoft signiert. Es wird empfohlen, dass Sie diese Dateien nicht ändern. Sie können allerdings eigene Formatierungsdateien bereitstellen. (Dieses Thema wird in einem künftigen Artikel ausführlicher besprochen.)

Das gwmi-Cmdlet kann Sie dabei unterstützen, herauszufinden, welche Klassen auf Ihrem Computer verfügbar sind. Wenn Sie zum Beispiel gwmi –namespace "root\cimv2" –list ausführen, erhalten Sie eine vollständige Liste der Klassen in diesem Namespace. Beachten Sie jedoch, dass die Klassen auf Ihrem Computer nur dann relevant sind, wenn Sie den Computer verwalten. Wenn Sie einen Remotecomputer verwalten, werden Sie vermutlich die Klassen ermitteln wollen, die auf diesem System verfügbar sind. Dafür müssen Sie den Parameter –computer von gwmi verwenden, um eine Verbindung zu einem Remotecomputer herzustellen. Beispielsweise werden durch gwmi –namespace "root\cimv2" –list –computer ServerA alle Klassen im root\cimv2-Namespace auf dem Remotecomputer namens ServerA aufgelistet.

Remote-WMI

In Version 1.0 von Windows PowerShell handelt es sich bei gwmi um das einzige Cmdlet, das die Remoteverwaltung direkt unterstützt. Das liegt hauptsächlich daran, dass die Remotesteuerung in die zugrunde liegende WMI-Architektur integriert ist. Da Windows PowerShell einfach die vorhandene Architektur nutzt, unterliegt sie den Sicherheitsfeatures dieser Architektur. Beispiel:

C:\> gwmi -namespace “root\cimv2” -computer
mediaserver -list
Get-WmiObject : Access is denied. (Exception
from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:1 char:5
+ gwmi <<<< -namespace “root\cimv2” -computer
mediaserver -list
PS C:\>

In dieser Instanz habe ich versucht, eine Verbindung zu einem Remotecomputer mit dem Namen Media-Server herzustellen, für den ich keine Zugriffsberechtigung habe. Als Administrator müsste ich die Berechtigung haben, mit dem WMI-Dienst dieses Computers zu arbeiten, aber wahrscheinlich sind meine Anmeldeinformationen für die lokale Arbeitsstation nicht ausreichend. Ich könnte zum Beispiel in einer anderen, nicht vertrauenswürdigen Domäne angemeldet sein, oder ich könnte mit einem Konto angemeldet sein, das weniger Berechtigungen hat. Erfreulicherweise unterstützt gwmi den Parameter –credential, der es ermöglicht, einen anderen Satz von Benutzeranmeldeinformationen für eine WMI-Verbindung anzugeben. Im Folgenden wird ein sehr einfaches Beispiel angezeigt:

gwmi win32_service –credential mydomain\administrator –computer mediaserver

Meine Anmeldeinformationen – um genauer zu sein, mein Benutzername – werden im Format DOMAIN\Username bereitgestellt.

Es gibt kein Feld, in dem ein Kennwort eingegeben werden kann. Windows PowerShell gibt dazu eine Aufforderung aus. Windows PowerShell stellt vorsätzlich keine Möglichkeit bereit, ein Kennwort in der Befehlszeile einzugeben, da hierdurch Kennwörter in Skriptdateien hartcodiert werden könnten, was ein absolutes Sicherheitsrisiko darstellt. Es gibt jedoch eine andere Möglichkeit, mit dem Parameter „–credential“ zu arbeiten, und zwar durch das vorzeitige Erstellen einer Art von Anmeldeinformationsobjekt namens PSCredential. Wichtig dabei ist das Get-Credential-Cmdlet:

$cred = get-credential mydomain\administrator

Wenn es ausgeführt wird, wird nach wie vor eine Aufforderung zur Angabe des entsprechenden Kennworts angezeigt. Diesmal jedoch wird das erstellte Anmeldeinformationsobjekt in der $cred-Variable gespeichert. Im Inhalt von $cred wird zwar der Name aufgeführt, nicht aber das Kennwort:

PS C:\> $cred

UserName
--------
mydomain\adminstrator

Ich kann dieses Anmeldeinformationsobjekt also beliebig wiederverwenden.

gwmi win32_service –credential $cred –computer mediaserver

Dies vereinfacht wiederholte WMI-Verbindungen zu einem Remotecomputer durch das Vordefinieren eines wiederverwendbaren Anmeldeinformationsobjekts. Es sollte jedoch beachtet werden, dass das WMIObject-Cmdlet derzeit die Angabe der Authentifizierungsebenen (auch Identitätswechsel genannt) nicht auf die gleiche Weise unterstützt, wie VBScript. Weitere Informationen finden Sie unter msdn2.microsoft.com/aa389290.aspx.

Einsichten

An Windows PowerShell gefällt mir insbesondere, dass das Niveau nicht gesenkt wird. Oben wurde aufgezeigt, wie Windows PowerShell nur einen Satz von Eigenschaften für die abgefragte Win32_Service-Klasse auswählte. Die Shell hat jedoch weiterhin Zugriff auf alle Eigenschaften und kann sogar Details zu diesen Eigenschaften angeben. Dafür leiten Sie einfach das Objekt (oder die Objekte) zum Get-Member-Cmdlet (oder seinem Alias gm) weiter, wie in Abbildung 2 dargestellt.

Abbildung 2 Durch das Weiterleiten eines Objekts zum Get-Member-Cmdlet wird offensichtlich, auf welche Methoden und Eigenschaften Sie zugreifen können.

Abbildung 2**  Durch das Weiterleiten eines Objekts zum Get-Member-Cmdlet wird offensichtlich, auf welche Methoden und Eigenschaften Sie zugreifen können. **(Klicken Sie zum Vergrößern auf das Bild)

Abgesehen von den Eigenschaften listet die Shell auch verfügbare Methoden auf. Das bedeutet, dass zum Bestimmen der Leistung einer Klasse nicht unbedingt auf die Dokumentation zurückgegriffen werden muss. Die Klasse selbst stellt die Mittel dafür bereit, die Konfiguration einer Instanz zu ändern, einen Dienst anzuhalten, ihn zu beenden und so weiter.

Um diese Methoden zu verwenden oder andere Eigenschaften anzuzeigen, ist es oft am einfachsten, die Instanzen in einer Variablen bereitzustellen:

$server = gwmi win32_operatingsystem
$server.reboot()

In diesem Beispiel wird die einzige verfügbare Instanz der Klasse Win32_OperatingSystem abgerufen (diese Klasse hat nur eine Instanz pro Computer) und in der $server-Variable gespeichert. Anschließend wird die $server-Variable verwendet, um auf die Reboot-Methode der Instanz zuzugreifen, wodurch der Computer neu gestartet wird. Hierbei ist Vorsicht angesagt!

Umfassende Abfragesprache

Wenn Sie mit WMI unter Verwendung von VBScript oder einer anderen Technologie gearbeitet haben, sind Sie vermutlich mit dem Abrufen von WMI-Klasseninstanzen vertraut, bei der eine Abfrage verwendet wird, die in WQL, der WMI-Abfragesprache, geschrieben ist. Die SQL-ähnliche Syntax dieser Abfragesprache erleichtert es, bestimmte Instanzen abzurufen, z. B. einen bestimmten Dienst, anstatt alle Instanzen einer festgelegten Klasse. Erfreulicherweise ermöglicht gwmi auch die Angabe der Abfrage, etwa so:

gwmi –query “select * from win32_service where name=’alerter’”

Diese Syntax von gwmi (die erst kurz vor der offiziellen Freigabe von Windows PowerShell hinzugefügt wurde) ist unglaublich nützlich und macht es wirklich sehr leicht, komplizierte WMI-Abfragen zu migrieren, die eventuell für andere Zwecke entwickelt wurden. Wie immer gibt Windows PowerShell umfassende Objekte mit ihren eigenen Eigenschaften und Methoden zurück und bietet somit einen vollständigen Zugriff auf die Verwaltungsleistung der WMI.

Künftige Schritte mit WMI

WMI wird für zukünftige Versionen von Windows weiterentwickelt, wobei neue Klassen und Funktionen hinzugefügt werden. WMI wird weiterhin in neuen Microsoft-Produkten enthalten sein. Für die meisten Microsoft-Produkte wurden zwar noch keine Versionen veröffentlicht, die speziell auf Windows PowerShell aufgebaut sind, jedoch ist die Fähigkeit, eine Verbindung zu WMI herzustellen, heute bereits einer der größten Vorteile von Windows PowerShell.

Die Möglichkeiten von WMI wurden hier nur oberflächlich angerissen. Hoffentlich dient dieser Artikel als Anregung, Windows PowerShell näher zu erforschen, um weitere Funktionen zu entdecken.

Don Jones ist Direktor für Projekte und Dienste bei SAPIEN Technologies und Mitautor von Windows PowerShell: TFM (SAPIEN Press). Sie erreichen Don Jones über seine Website unter www.ScriptingAnswers.com.

© 2008 Microsoft Corporation und CMP Media, LLC. Alle Rechte vorbehalten. Die nicht genehmigte teilweise oder vollständige Vervielfältigung ist nicht zulässig.