Microsoft Windows 2000 - Scripting-Handbuch (Teil 1) Scripting-Konzepte und -Technologien zur Systemadministration - Kapitel 6 - WMI-Scripting

Veröffentlicht: 26. Apr 2004

(Engl. Originaltitel: WMI Scripting Primer)

Bei WMI (Windows Management Instrumentation) handelt es sich um die wichtigste Verwaltungstechnologie der Microsoft Windows-Betriebssysteme. Mit WMI ist eine konsistente und einheitliche Verwaltung, Steuerung und Überwachung der einzelnen Systeme im gesamten Unternehmen möglich. WMI basiert auf Industriestandards und ermöglicht es Systemadministratoren, die Konfiguration von Arbeitsstationen, Servern, Anwendungen, Netzwerken und anderen Komponenten abzufragen, zu ändern und zu überwachen. Scripte können die WMI-Script-Bibliothek verwenden.

Zurück zur Übersichtsseite

Auf dieser Seite

Links zu verwandten Themen


Dn151185.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png WMI-Überblick

Dn151185.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Die WMI-Architektur

Dn151185.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Das Common Information Model (CIM)

Dn151185.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Die WMI-Scripting-Bibliothek

Dn151185.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Schreiben von WMI-Scripten

Download

Artikel im Word-Format

Dn151185.8806D110EB18CD71B1CE323B89624167(de-de,TechNet.10).png sas_wmi_overview.doc

Microsoft Word-Datei

Viewer für Office-Dateien downloaden

Artikel im PDF-Format

Dn151185.8B3D04996314173E7583D7C6B55A6BAC(de-de,TechNet.10).png sas_wmi_overview.pdf

PDF-Datei

Adobe Acrobat Reader downloaden

WMI-Überblick

Ein grundlegendes Verständnis von WMI ist zur Systemadministration mindestens genauso wichtig wie das Wissen um Active Directory und ADSI. WMI stellt ein konsistentes Modell einer verwalteten Umgebung zur Verfügung. Für jede verwaltbare Ressource gibt es eine entsprechende WMI-Klasse. Sie können sich eine WMI-Klasse als kurze Beschreibung der Eigenschaften einer verwalteten Ressource und der Aktion, die WMI zur Verwaltung der Ressource durchführen kann, vorstellen.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Was ist eine 'verwaltete Ressource'? Im Zusammenhang mit diesem Kapitel ist eine verwaltete Ressource jedes Objekt, das über WMI verwaltet werden kann (Hardware, Software, Benutzerkonten, usw.).

Überlegen Sie sich, wie Sie Arbeitsstationen und Server bis jetzt verwalten und überwachen. Sie verwenden eine Vielzahl an administrativen Werkzeugen, um diverse unterschiedliche Ressourcen zu verwalten (zum Beispiel Festplatten, Ereignisprotokolle, Dateien, Ordner, Dateisystem, Netzwerkkomponenten, Betriebssystemeinstellungen, Leistungsdaten, Drucker, Prozesse, Registrierungseinstellung, Dienste, Freigaben, Benutzer und Gruppen).

Wenn Sie das WMI-Modell und dessen Anwendung verstanden haben, dann können Sie diese Komponenten alle über die WMI-Scripting-Bibliothek verwalten. Die Scripting-Bibliothek ermöglicht Ihnen die Arbeit mit WMI-Klassen und den entsprechenden verwalteten Ressourcen. Sie können also die unterschiedlichsten Ressourcen über einen gemeinsamen Weg verwalten.

WMI entspricht einem Industriestandard der DMTF (Distributed Management Task Force). Die DMTF ist eine Organisation, die mit Herstellern von Schlüsseltechnologien (inklusive Microsoft) und Standardisierungsgremien zusammenarbeitet, um übergreifende Verwaltungslösungen zu entwickeln. Die Architektur von WMI basiert auf den Ideen der WBEM-Initiative (Web-Based Enterprise Management) der DMTF.

WMI wurde 1998 das erste Mal veröffentlicht und als Komponente über das Service Pack 4 für Microsoft® Windows NT® bereitgestellt. WMI ist inzwischen ein integraler Bestandteil aller Windows-Betriebssysteme - inklusive Microsoft Windows 2000, Microsoft® Windows® XP und Windows Server 2003.

Die Möglichkeiten von WMI

Mit dem WSH und VBScript können Sie WMI-Scripte für die folgenden Bereiche schreiben:

  • Verwaltung von Computern unter Windows Server 2003, Windows XP Professional und Windows 2000
    Mit WMI-Scripten können Sie Ereignisprotokolle, Dateisystem, Drucker, Prozesse, Registrierungseinstellung, geplante Tasks, Sicherheitseinstellung, Dienste, Freigaben und eine Vielzahl anderer Komponenten verwalten.
  • Netzwerke
    Sie können zum Beispiel Dienste wie DNS, clientseitige Einstellungen (zum Beispiel die TCP/IP-Einstellungen) und SNMP-Geräte verwalten.
  • Echtzeitüberwachung
    Sie können zum Beispiel das Auftreten von Ereignissen, die Leistungsanzeige, das Dateisystem oder die Registrierung überwachen.
  • Serveranwendungen
    Sie können zum Beispiel MOM-, SMS-, Exchange- und SQL-Server überwachen.

In einigen Fällen stellt WMI ihnen die gleichen Funktionalitäten wie ein Kommandozeilenwerkzeug oder eine GUI-Anwendung zur Verfügung. In anderen Fällen kann WMI Aufgaben ausführen, die über keinen anderen Weg durchführbar sind. Vor WMI war es zum Beispiel nicht möglich, über ein Script die Menge des installierten RAMs abzufragen - zumindest nicht ohne ein Drittanbieter-Tool. Mit WMI haben Sie die Möglichkeit, das installierte RAM von jedem Computer abzufragen, auf dem Sie über die nötigen administrativen Rechte verfügen. Script 6.1 demonstriert dies.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Das Script sieht zugegebenermaßen auf den ersten Blick nicht ganz einfach aus. Sie werden jedoch feststellen, dass es sich beim größten Teil des Scripts um Bausteine handelt, die Sie in jedem WMI-Script unverändert wieder verwenden können.

Script 6.1: Abfragen und Anzeigen des installierten Hauptspeichers



1

2

3

4

5

6

7

8

9

10

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)

Set colSWbemObjectSet = _

objSWbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")


For Each objSWbemObject In colSWbemObjectSet

Wscript.Echo "Physikalischer Speicher in KB: " & _

objSWbemObject.TotalPhysicalMemory

Next

Wenn Sie das Script unter CScript ausführen, dann zeigt es den installierten Hauptspeicher in KB an. Die Ausgabe sieht zum Beispiel so aus:

Total Physical Memory (kb): 261676

Wie arbeitet das Script nun? Wenn Sie auf die fett geschriebenen Teile des Scripts achten, dann werden Sie feststellen, dass das Script zwei Aufgaben ausführt:

  1. Es verbindet sich mit einer WMI-Klasse mit dem Namen Win32_LogicalMemoryConfiguration.
    WMI-Klassen repräsentieren die verwaltbaren Ressourcen eines Computers. Wie der Name schon andeutet, ermöglicht es Ihnen die Klasse Win32_LogicalMemoryConfiguration Informationen über den Hauptspeicher abzufragen.
  2. Es gibt den Wert einer Eigenschaft mit dem Namen TotalPhysicalMemory aus.
    WMI-Klassen haben Eigenschaften. Die Klasse Win32_LogicalMemoryConfiguration hat zum Beispiel eine Eigenschaft, über die Sie den installierten Hauptspeicher abfragen können. Die Eigenschaften der Klassen entsprechen normalerweise den Eigenschaften der Ressourcen, die durch die Klasse repräsentiert werden. Festplatten haben zum Beispiel Eigenschaften wie Leseköpfe (Heads), Sectoren (Sectors) und Zylinder (Cylinders). Daher verfügt auch die Klasse Win32_DiskDrive über Eigenschaften wie TotalHeads, TotalSectors und TotalCylinders.

Zusätzlich zum physikalischen Speicher gibt es unter Windows-basierten Computern den virtuellen Speicher. Es ist daher nicht wirklich überraschend, dass die Klasse Win32_LogicalMemoryConfiguration eine Eigenschaft mit dem Namen TotalVirtualMemory zur Verfügung stellt. Wie Sie die Größe des virtuellen Speichers abfragen können, sehen Sie in Script 6.2. Der einzige wirkliche Unterschied zu Script 6.1 ist das fett geschriebene Element.

Script 6.2: Abfragen und Anzeigen des virtuellen Speichers



1

2

3

4

5

6

7

8

9

10

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)

Set colSWbemObjectSet = _

objSWbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")


For Each objSWbemObject In colSWbemObjectSet

Wscript.Echo "Virtueller Speicher in KB: " & _

objSWbemObject.TotalVirtualMemory

Next

WMI kann natürlich für mehr als nur zur Rückgabe von Informationen über den Speicher eines Computers verwendet werden. Script 6.3 fragt zum Beispiel die Namen, den Status und den Starttyp aller installierten Dienste ab.

Script 6.3: Abfragen und Anzeigen von Informationen über Dienste



1

2

3

4

5

6

7

8

9

10

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)

Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")


For Each objSWbemObject In colSWbemObjectSet

Wscript.Echo " Name: " & objSWbemObject.DisplayName & vbCrLf & _

" Status: " & objSWbemObject.State & vbCrLf & _

" Starttyp: " & objSWbemObject.StartMode

Next

Wenn Sie das Script unter CScript ausgeführt wird, dann erhalten Sie eine Ausgabe wie die folgende (nur Teile der Ausgabe):

Name: Windows-Zeitgeber
 Status:   Running
 Starttyp: Auto
Name: Webclient
 Status:   Running
 Starttyp: Auto
Name: Windows-Verwaltungsinstrumentation
 Status:   Running
 Starttyp: Auto
Name: Dienst für Seriennummern der tragbaren Medien
 Status:   Stopped
 Starttyp: Manual
Name: Treibererweiterungen für Windows-Verwaltungsinstrumentation
 Status:   Stopped
 Starttyp: Manual
Name: WMI-Leistungsadapter
 Status:   Stopped
 Starttyp: Manual
Name: Automatische Updates
 Status:   Running
 Starttyp: Auto
Name: Konfigurationsfreie drahtlose Verbindung
 Status:   Running
 Starttyp: Auto

Wenn Sie sich Script 6.3 genauer ansehen, dann werden Sie zwei Dinge bemerken:

  • Statt der Klasse Win32_LogicalMemoryConfiguration verwendet das Script eine Klasse mit dem Namen Win32_Service. Warum? Weil das Script Informationen über Dienste zurückgeben soll und nicht über den Hauptspeicher. Wenn das Script zum Beispiel Informationen über einen Monitor zurückgeben würde, dann würde es die Klasse Win32_DesktopMonitor verwenden. Mit der verwalteten Ressource ändert sich also auch die verwendete Klasse.
  • Die abgefragten Eigenschaften unterscheiden sich von den Eigenschaften in den vorherigen Scripten. Warum? Die Klasse Win32_Service stellt natürlich andere Eigenschaften als die Klasse Win32_LogicalMemoryConfiguration zur Verfügung. Eine Klasse stellt immer die Eigenschaften zur Verfügung, die auch die verwaltete Ressource hat, die durch die Klasse repräsentiert wird.

Wenn Sie nun ein Muster erkennen, dann haben Sie bereits einen großen Schritt beim Erlernen von WMI-Scripting hinter sich. WMI-Scripte fragen die Informationen über die verwalteten Ressourcen fast alle gleich ab. Es ändern sich nur die Namen der Klassen und deren Eigenschaften.

Wie Sie in diesem Kapitel sehen werden, arbeiten WMI-Scripts normalerweise in drei Schritten:

  1. Sie verbinden Sich mit dem WMI-Dienst.
  2. Sie fragen Informationen über WMI-Klassen ab.
  3. Sie verarbeiten die Informationen auf irgendeine Weise weiter (zum Beispiel werden diese ausgegeben).

Alle WMI-Scripte folgen diesem Muster. Stellen Sie sich zum Beispiel vor, Sie möchten ein Script schreiben, das die Einträge aus dem Ereignisprotokoll abfragt und anzeigt. Mit dem Scriptcode aus Script 6.1 können Sie ein solches Script ganz schnell erstellen - Script 6.4 demonstriert dies.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Bevor Sie Script 6.4 ausführen, sollten Sie sich bewusst sein, dass es möglicherweise sehr lange zur Ausführung benötigt - abhängig davon, wie viele Einträge im Ereignisprotokoll vorhanden sind.

Script 6.4: Abfragen und Anzeigen von Ereignissen



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)

Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_NTLogEvent")

For Each objSWbemObject In colSWbemObjectSet

Wscript.Echo _

"Protokolldatei: " & objSWbemObject.LogFile & vbCrLf & _

"Nummer: " & objSWbemObject.RecordNumber & vbCrLf & _

"Typ: " & objSWbemObject.Type & vbCrLf & _

"Uhrzeit: " & objSWbemObject.TimeGenerated & vbCrLf & _

"Quelle: " & objSWbemObject.SourceName & vbCrLf & _

"Kategorie: " & objSWbemObject.Category & vbCrLf & _

"Kateogrie-Name: " & objSWbemObject.CategoryString & vbCrLf & _

"Ereignis: " & objSWbemObject.EventCode & vbCrLf & _

"Benutzer: " & objSWbemObject.User & vbCrLf & _

"Computer: " & objSWbemObject.ComputerName & vbCrLf & _

"Nachricht: " & objSWbemObject.Message & vbCrLf

Next

Dn151185.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Die WMI-Architektur

Die ersten Seiten dieses Kapitels sollten einen wichtigen Punkt herausstellen. WMI-Scripting muss nicht schwer sein - es kann sogar sehr einfach sein. Wie Sie gesehen haben, können Sie bereits über eine einzelne Vorlage und geringe Änderungen Hunderte von Scripten zur Abfrage einer riesigen Menge von Informationen erstellen.

Einige wichtige Probleme wurden jedoch bis jetzt verschwiegen. Sie werden uns zum Beispiel zustimmen, wenn wir sagen, dass Sie über die Klasse Win32_NTLogEvent Ereignisse aus dem Ereignisprotokoll abfragen können. Woher wissen Sie aber, dass es eine Klasse mit dem Namen Win32_NTLogEvent gibt? Oder woher wissen Sie, dass es eine Klasse mit dem Namen Win32_Service und den Eigenschaften Name, Description und State gibt? Sie können Hunderte von unterschiedlichen Scripten aus dem ersten Script erstellen - jedoch nur, wenn Sie wissen, welche Klassen und Eigenschaften Sie verwenden können.

Tatsächlich ist das Schreiben des Scripts der einfache Teil von WMI - der schwere Teil ist es, herauszufinden, was über WMI verwaltet werden kann und was nicht. Hierbei helfen Ihnen die aufgabenbasierten Abschnitte dieses Kapitels. Im Abschnitt Dateien und Ordner lesen Sie zum Beispiel mehr über die entsprechenden WMI-Klassen (und deren Methoden und Eigenschaften) - was aber, wenn Sie Grafikkarten, Monitore oder Netzwerkkarten verwalten wollen? Leider gibt es in diesem Buch nicht für alle verwaltbare Ressourcen einen entsprechenden Abschnitt.

Heißt das, Sie können nur die im Buch beschriebenen Ressourcen verwalten? Natürlich nicht - wenn Sie wissen wie WMI funktioniert, dann können Sie alle Bereiche von WMI nutzen. Wenn Ihnen klar ist, wo und wie WMI Informationen speichert, dann können Sie die vorhin gestellten Fragen ganz einfach beantworten. Welche Klassen stehen mir zur Verfügung? Wie sind die Namen dieser Klassen? Welche Eigenschaften und Methoden kann ich über die Klasse verwenden?

Dieser und der folgende Abschnitt beschäftigen sich mit dem Common Information Model (CIM) und beschreiben die WMI-Architektur. Als erstes sehen wir uns die drei grundlegenden WMI-Schichten an (Abbildung 6.1):

  • Konsumenten
  • WMI-Infrastuktur
  • Verwaltete Ressourcen

Dieser Abschnitt schließt mit einer Einführung in die WMI-Sicherheit. Hierbei handelt es sich zwar nicht um eine WMI-Schicht, es ist jedoch trotzdem wichtig zu wissen, wie Sicherheit unter WMI funktioniert - und zwar bevor Sie anfangen, Scripte zu schreiben.

Dn151185.8AC371BA27D47DB2A966F7C6BCC4627A(de-de,TechNet.10).png

Abbildung 6.1: Die WMI-Architektur

Verwaltete Ressourcen

Die grundlegende Schicht der WMI-Architektur bilden die verwalteten Ressourcen. Eine verwaltete Ressource ist jede logische oder physikalische Komponente, die über WMI zugreifbar und verwaltbar ist. Bei diesen Ressourcen handelt es sich unter anderem um: Computer, Festplatten, Peripheriegeräte, Ereignisprotokolle, Dateien, Ordner, Dateisysteme, Netzwerkkomponenten, Betriebssystem-Subsysteme, Leistungsindikatoren, Drucker, Prozesse, Registrierungseinstellungen, Sicherheit, Dienste, Freigaben, SAM-Benutzer und -Gruppen, Active Directory, Windows-Installer, WDM-Gerätetreiber und SNMP.

Eine WMI-Ressource kommuniziert mit WMI über einen Provider. Für das virtuelle Gegenstück einer verwalteten Ressource wird oft der Begriff Instanz verwendet. Entsprechend dem WMI-SDK ist eine Instanz 'ein Repräsentant eines physikalischen Objekts, das zu einer bestimmten Klasse gehört'.

Sehen Sie sich zum Beispiel Script 6.5 an. Es gibt die Laufwerksbuchstaben für alle logischen Laufwerke eines Computers zurück.

Script 6.5: Abfragen und Anzeigen der logischen Laufwerke



1

2

3

4

5

6

7

8

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)

Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_LogicalDisk")


For Each objSWbemObject In colSWbemObjectSet

Wscript.Echo objSWbemObject.DeviceID

Next

Abhängig von den logischen Laufwerken des Computers sieht die Ausgabe des Scripts ungefähr so aus:

A:
C:
D:
E:

Jeder dieser Laufwerksbuchstaben stellt zwei Dinge dar: Erstens ein tatsächliches logisches Laufwerk und zweitens eine Instanz der Klasse Win32_LogicalDiskDrive.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Was ist, wenn es keine Instanzen einer Klasse gibt? Nehmen wir an, dass Sie versuchen Informationen über die Bandlaufwerke eines Computers abzufragen - der Computer hat jedoch keine Bandlaufwerke. Wird dies zu einem Fehler führen? Nein - letztendlich ist Win32_TapeDrive eine gültige WMI-Klasse. Es ist völlig unbedeutend, ob es tatsächlich Bandlaufwerke (oder Instanzen der entsprechenden Klasse) gibt.

Die WMI-Infrastruktur

Die WMI-Infrastruktur ist die Vermittlungsschicht im WMI-Architekturmodell. WMI setzt sich aus drei primären Komponenten zusammen: dem CIMOM (Common Information Model Object Manager, auch WMI-Dienste genannt), dem CIM-Repository (Common Information Model, auch WMI-Repository genannt) und WMI-Providern. Zusammen bilden diese drei Komponenten die WMI-Infrastruktur.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Eine weitere Komponente - die WMI-Scriptbibliothek - wird weiter unten in diesem Kapitel besprochen.

WMI-Provider

WMI-Provider arbeiten als Vermittler zwischen dem CIMOM und der verwalteten Ressource. Provider fordern Informationen von den verwalteten Ressourcen an und geben Informationen an diese weiter. Script 6.1 und Script 6.3 verwenden zum Beispiel den Provider Win32, um Informationen über den Hauptspeicher und die Dienste abzufragen. Script 6.4 verwendet hingegen den Provider Event Log.

Provider verbergen die Implementierungsdetails für die einzelnen verwalteten Ressourcen über ein standardbasiertes und einheitliches Zugriffsmodell. WMI-Provider kommunizieren mit ihren jeweiligen verwalteten Ressourcen über die nativen APIs (Application Programming Interfaces) der verwalteten Ressource. Mit CIMOM kommunizieren die WMI-Provider über die WMI-Programmierschnittstelle. Der Provider Event Log ruft zum Zugriff auf die Ereignisprotokolle zum Beispiel die Win32-EventLog-APIs auf.

Warum müssen Sie das wissen? Um eine Anwendung zu erstellen, die Windows-Subsysteme verwaltet, werden normalerweise die Win32-APIs verwendet. Ohne WMI müssten Sie diese APIs selbst aufrufen. Hierbei gäbe es zwei Probleme: Erstens können Win32-APIs nicht über ein Script aufgerufen werden - daher müssen Sie eine Programmiersprache wie C++ oder Visual Basic verwenden. So gehen Ihnen jedoch alle Vorteile von Scripten verloren (schnelle Entwicklung, keine Entwicklungsumgebung notwendig).

Und zweitens funktionieren nicht alle Win32-APIs auf die gleich Art und Weise. Wenn Sie die EventLog-APIs beherrschen, dann heißt das noch lange nicht, dass Sie die Service-APIs genauso verwenden können. Dies ist eine der grundlegenden Schwierigkeiten bei der Programmierung mit Windows-APIs.

WMI-Provider lösen diese Probleme. Sie müssen sich nicht um den Aufruf der Win32-APIs kümmern - dies erledigt WMI für Sie - und Sie müssen auch nicht die Unterschiede zwischen den einzelnen APIs kennen. Stattdessen verwenden Sie die konsistenten WMI-Befehle, und WMI übersetzt diese für Sie in API-Aufrufe.

WMI wendet sich natürlich nicht nur an Systemadministratoren. Auch Softwareentwickler können die WMI-Architektur verwenden. Ein Beispiel hierfür ist der Exchange Server 2000-Provider. Er überwacht den Status des Exchange-Connectors. Auch viele andere Serverprodukte stellen WMI-Provider zur Verfügung (zum Beispiel MOM-, SMS-, IIS- und SQL-Server).

Providers werden generell als DLLs (Dynamic-Link Libraries) implementiert. Diese DLLs befinden sich im Verzeichnis systemroot\System32\Wbem. WMI stellt unter Windows 2000, Windows XP und Windows Server 2003 bereits eine Menge Provider zur Verfügung - diese Provider werden auch Standardprovider genannt. Einige dieser Standardprovider sehen Sie in Tabelle 6.1.

Tabelle 6.1: Einige WMI-Standardprovider

Provider

DLL

Namespace

Beschreibung

Active Directory

dsprov.dll

root\directory\ldap

Stellt Active Directory-Objekte über WMI zur Verfügung

Event Log

ntevt.dll

root\cimv2

Verwaltet das Windows-Ereignisprotokoll

Performance Counter

wbemperf.dll

root\cimv2

Stellt einen Zugriff auf Leistungsdaten zur Verfügung

Registry

stdprov.dll

root\default

Liest, schreibt, überwacht und erstellt Registrierungseinträge

SNMP

snmpincl.dll

root\snmp

Stellt einen Zugriff auf SNMP-MIB-Daten und Trap-Meldungen zur Verfügung

WDM

wmiprov.dll

root\wmi

Stellt einen Zugriff auf WDM-Treiber zur Verfügung

Win32

cimwin32.dll

root\cimv2

Stellt Informationen über Computer, Festplatten, Peripheriegeräte, Dateien, Ordner, Dateisysteme, Netzwerkkomponenten, Betriebssystem, Drucker, Prozesse, Sicherheit, Dienste, Freigaben, SAM-Benutzer und -Gruppen und vieles weitere zur Verfügung

Windows Installer

msiprov.dll

root\cimv2

Stellt einen Zugriff auf Informationen über installierte Software zur Verfügung

Windows Server 2003 und Windows XP bieten noch viele weitere Standardprovider. Eine vollständige Liste finden Sie im WMI Software Developers Kit (SDK). Informationen zum WMI-SDK finden Sie unter dem Link Microsoft Windows Management Instrumentation (WMI) SDK unter https://www.microsoft.com/windows/reskits/webresources (englischsprachig).

CIMOM

Das CIMOM handhabt die Interaktion zwischen Konsumenten und Providern. Alle WMI-Anfragen und der gesamte Datenfluss werden über den CIMOM durchgeführt. Wenn Sie ein WMI-Script starten, dann wird das Script an CIMOM umgeleitet. Der CIMOM verarbeitet die Anfrage des Scripts jedoch nicht direkt. Nehmen wir zum Beispiel an, das Script fragt eine Liste der installierten Dienste ab. Der CIMOM ruft die Liste der Dienste in diesem Fall nicht für Sie ab - er ruft stattdessen den entsprechenden WMI-Provider auf, und dieser ruft dann die Liste ab. Wenn die Liste abgefragt ist, dann wird Sie an den CIMOM übergeben. Dieser leitet sie dann an das Script weiter.

Der CIMOM wird unter Windows XP und Windows Server 2003 über den WMI-Dienst (winmgmt.exe) bereitgestellt. Der WMI-Dienst wird unter dem Prozess svchost.exe ausgeführt.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Unter Windows 2000 und Windows NT 4.0 SP4 wird der WMI-Dienst als separater Prozess ausgeführt. Unter Windows ME, Windows® 98 und Windows® 95 OSR 2.5 wird WMI als Standardprozess ausgeführt.

Der WMI-Dienst entspricht den meisten Betriebssystemdiensten. Er kann zum Beispiel angehalten und gestartet werden:

net stop winmgmt
net start winmgmt

Wenn der Dienst angehalten ist und ein Script oder eine Anwendung aufgeführt wird, die den Dienst benötigt, dann wird der Dienst automatisch neu gestartet.

Der CIMOM stellt die folgenden Dienste für die WMI-Infrastruktur zur Verfügung:

  • Registrierung von Providern - Der CIMOM speichert die Informationen zu den Providern im CIM-Repository.
  • Routing von Anfragen - Der CIMOM verwendet die gespeicherten Provider-Informationen, um Konsumentenanfragen an den entsprechenden Provider weiterzuleiten.
  • Remotezugriff - Anfragen von Remote-Konsumenten werden vom CIMOM verarbeitet.
  • Sicherheit - Der CIMOM kontrolliert den Zugriff auf die verwalteten Ressourcen, indem er das Zugrifftoken des Benutzers überprüft.
  • Abfrageverarbeitung - Erlaubt es einem Konsumenten Abfragen gegen verwaltete Ressourcen über die WMI Query Language (WQL - WMI-Abfragesprache) durchzuführen.
  • Ereignisverarbeitung - Erlaubt es einem Konsumenten auf Ereignisse einer verwalteten Ressource zu reagieren.

Das CIM-Repository

Die Grundidee von WMI ist, dass die Konfiguration und die Verwaltung von unterschiedlichen Ressourcen über ein einheitliches Schema erfolgt. Das CIM-Repository speichert dieses Schema - es wird auch Objekt-Repository oder Klassenspeicher genannt. Das Schema definiert alle über WMI zur Verfügung stehenden Daten und basiert auf dem Common-Information-Model-Standard der DMTF.

Genau wie das Active Directory-Schema ist das CIM auf Klassen aufgebaut. Eine Klasse ist eine Blaupause einer über WMI verwaltbaren Ressource. Im Gegensatz zu Active Directory-Klassen, die statische Objekte vorgeben, stellen CIM-Klassen normalerweise dynamische Ressourcen dar. Die Instanzen der Ressourcen werden nicht im CIM-Repository gespeichert, sondern auf Anfrage eines Konsumenten dynamisch abgefragt. Das bedeutet, dass der Begriff Repository (Speicher) im Bezug auf das CIM nicht ganz richtig ist. Auch wenn das CIM ein Repository ist und auch statische Daten speichert, so ist sein primärer Zweck doch die Speicherung von Blaupausen für die verwalteten Ressourcen.

Der Grund hierfür ist einfach: Der Status der meisten über WMI verwalteten Ressourcen ändert sich regelmäßig. WMI-Klassen können zum Beispiel dazu verwendet werden, Ereignisse des Ereignisprotokolls abzufragen.

Genau wie Active Directory-Klassen sind auch CIM-Klassen hierarchisch organisiert. Untergeordnete Klassen erben Eigenschaften der übergeordneten Klassen. Der DMTF pflegt eine Gruppe von allgemeinen Basisklassen, von denen System- und Anwendungsentwickler (zum Beispiel Microsoft) system- oder anwendungsspezifische Klassen ableiten können. Die Klasse Win32_Process ist zum Beispiel von der Klasse CIM_Process abgeleitet (diese ist wiederum von den Klassen CIM_LogicalElement und CIM_ManagedSystemElement abgeleitet).

Klassen sind in Namespaces gruppiert - logische Gruppen für bestimmte Bereiche. Der Namespace root\cimv2 enthält zum Beispiel Klassen, die allgemeine Ressourcen eines Computers oder eines Betriebssystems repräsentieren. Die Klassen, die in den bisherigen Scripten verwendet wurden (Win32_LogicalMemoryConfiguration, Win32_Service und Win32_NTLogEvent) befinden sich im Namespace root\cimv2 - sie sind jedoch nur drei von Hunderten von Klassen in den unterschiedlichen CIM-Namespaces.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Auch für die WMI-Sicherheit sind Namespaces wichtig. Dieses Thema wird weiter unten in diesem Kapitel besprochen.

CIM-Klassen enthalten Eigenschaften und Methoden. Eigenschaften beschreiben die Konfiguration und den Status einer über WMI verwalteten Ressource. Methoden sind ausführbare Funktionen, die bestimmte Aktionen für die über WMI verwalteten Ressourcen ausführen.

Unter Windows 2000 und Windows NT 4.0 SP4 ist das CIM unter systemroot\System32\Wbem\Respository\cim.rep gespeichert. Unter Windows Me, Windows 98 und Windows 95 OSR 2. ist das CIM unter %windir%\System\Wbem\Repository\cim.rep gespeichert.

Unter Windows XP und Windows Server 2003 ist das CIM im Ordner systemroot\System32\Wbem\Repository\FS gespeichert und setzt sich aus den folgenden Dateien zusammen:

  • Index.btr - Binary-tree (btree) Index
  • Index.map - Transaktionskontrolldatei
  • Objects.data - CIM-Repository
  • Objects.map - Transaktionskontrolldatei

Auch wenn das CIM auf objektorientierten Prinzipien basiert, müssen Sie trotzdem kein Experte im Schema-Design werden. Es ist jedoch wichtig, dass Sie die grundlegenden Strukturen und die Organisation des CIM-Repository verstanden haben.

WMI-Konsumenten

Bei den WMI-Konsumenten handelt es sich um die letzte Schicht der WMI-Infrastruktur. Ein Konsument kann ein Script, eine Anwendung, eine Webanwendung oder ein anderes Tool sein, das auf WMI zugreift.

Ein solches Script muss nicht kompliziert sein. Das folgende dreizeilige Script ist ein Beispiel für einen WMI-Konsumenten. Es fragt den verfügbaren Speicherplatz auf Laufwert C ab:

Set objSWbemServices = GetObject("winmgmts:")
Set objDisk = objSWbemServices.Get("Win32_LogicalDisk.DeviceID='C:'")
Wscript.Echo objDisk.FreeSpace

WMI-Sicherheit

WMI ist eine Technologie, die für die Systemadministration extrem nützlich ist. Scripte können genauso einfach gegen Remotecomputer wie gegen den lokalen Computer ausgeführt werden. Außerdem benötigen Sie zum Entwickeln von WMI-Scripten nicht mehr als einen Texteditor. WMI wird zwar so zur perfekten Technologie zur Systemadministration, doch leider gibt es noch eine weitere Gruppe, die WMI nutzen kann - Hacker. Wie schwer wäre es zum Beispiel, ein Script zu schreiben, das alle Computer in Ihrer Organisation einen nach dem anderen herunterfährt?

Wenn wir ganz ehrlich sind, dann wäre es ganz einfach, ein solches Script zu schreiben. Dieses Script jedoch auszuführen wird deutlich schwerer. Das liegt daran, dass die Sicherheit ein wichtiger Teil der WMI-Infrastruktur ist. WMI wurde so entworfen, dass solche Aktivitäten, wie die oben beschriebenen, verhindert werden.

Stellen Sie sich zum Beispiel vor, ein Hacker versucht über WMI einen Ihrer Computer herunterzufahren. Dieser Versuch wird fehlschlagen. Warum? Weil nur Administratoren ein Script gegen einen Remotecomputer ausführen können. Solange der Hacker kein Administrator ist, ist er nicht in der Lage, einen Computer über WMI herunterzufahren (wenn der Hacker Administrator ist, dann kann er auch ohne ein Script eine Menge Probleme verursachen).

Was ist, wenn ein Hacker das Script per E-Mail an einen Benutzer schickt und diesen dazu bringt, das Script auszuführen? Auch das wird nicht funktionieren. Ein WMI-Script, das etwas tut, benötigt immer administrative Rechte. In den meisten Organisationen verfügen die Benutzer jedoch nicht über solche Rechte. WMI wird immer unter den Rechten der Person ausgeführt, die das Script gestartet hat.

WMI-Sicherheit ist eine Erweiterung der anderen Windows-Sicherheits-Subsysteme und setzt sich aus den folgenden Komponenten zusammen:

  • WMI-Namespace-Sicherheit
  • DCOM-Sicherheit (Distributed COM)
  • Standard Windows-Betriebssystem-Sicherheit

WMI-Namespace-Sicherheit

Bevor ein Benutzer sich mit WMI verbinden kann - egal ob auf einem lokalen Computer oder einem Remotecomputer, - wird das Zugriffstoken des Benutzers auf die entsprechenden Rechte überprüft. Die benötigten Rechte sind im CIM-Repository gespeichert.

Standardmäßig hat die Gruppe Administratoren einen Vollzugriff auf WMI und das gesamte CIM-Repository - sowohl auf dem lokalen Computer als auch auf Remotecomputern. Alle anderen Benutzer haben über die Gruppe Jeder die Rechte Konto aktivieren, Methoden ausführen und Anbieterschreibzugriff auf dem lokalen Computer. In Tabelle 6.2 sehen Sie die verfügbaren WMI-Berechtigungen - diese können Sie über die Registerkarte Sicherheit des Snap-Ins Windows-Verwaltungsinfrastruktur (WMI) (systemroot\System32\Wmimgmt.msc) konfigurieren.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Unter Windows NT 4.0 SP4, Windows 98 und Windows 95 OSR 2.5 müssen Sie die Anwendung Wbemcntl.exe verwenden. Sie finden diese unter Windows NT 4.0 SP4 im Ordner systemroot\System32\Wbem.

Tabelle 6.2: WMI-Namespace-Berechtigungen

Berechtigung

Beschreibung

Administratoren

Jeder

Methoden
ausführen

Ermöglicht das Ausführen
von Methoden, die von den
WMI-Klassen oder -Instanzen
exportiert wurden.

x

x

Vollständiger
Schreibzugriff

Ermöglicht umfassenden
Lese-/Schreib-/Löschzugriff
auf alle WMI-Objekte,
-Klassen und -Instanzen.

x


Eingeschränkter
Schreibzugriff

Ermöglicht den Schreib-
zugriff auf statische
WMI-Objekte.

x


Anbieter-
schreibzugriff

Ermöglicht den Schreib-
zugriff auf von Anbietern
bereitgestellte Objekte.

x

x

Konto
aktivieren

Ermöglicht den Lesezugriff
auf WMI-Objekte.

x

x

Remote-
aktivierung

Ermöglicht den Remote-
zugriff auf den Namespace.

x


Sicherheit
lesen

Ermöglicht den schreib-
geschützten Zugriff auf WMI-Sicherheitsinformationen.

x


Sicherheit
bearbeiten

Ermöglicht den Lese- und
Schreibzugriff auf WMI-
Sicherheitsinformationen

x


WMI-Berechtigungen werden auf Namespace-Ebene auf alle Klassen im entsprechenden Namespace zugewiesen - sie gelten damit auch für alle untergeordneten Namespaces die Einstellungen von dem entsprechenden Namespace erben. Standardmäßig werden Berechtigungen nur dem Namespace root zugewiesen und an alle untergeordneten Namespaces vererbt.

Eine Sicherheitsprüfung wird dann durchgeführt, wenn sich ein Benutzer mit dem CIMOM verbindet. Daher werden Berechtigungsänderungen nur dann aktiv, wenn der Benutzer eine neue Verbindung aufbaut.

DCOM-Sicherheit

DCOM ist die Architektur, über die die WMI-Scripting-Bibliothek mit dem WMI-Dienst zusammenarbeitet. Sie stellt einen Mechanismus zur Verfügung, der Impersonation genannt wird (Personifizierung - auch mit dem Begriff 'Ausführen als' bezeichnet - zur Vereinfachung wird in diesem Text der Begriff Personifizierung verwendet). Die Personifizierung legt fest, unter welchen Benutzerrechten der WMI-Dienst ein Script ausführt.

Standardmäßig führt der WMI-Dienst Script unter den Anmeldeinformationen des angemeldeten Benutzers aus - dies ist auch die empfohlene Einstellung. Sie können dem WMI-Dienst das Recht geben, über Ihre Anmeldeinformationen auf andere DCOM-basierte Dienste zuzugreifen. Dieser Vorgang wird Delegierung genannt - mit ihm sind jedoch einige Risiken verbunden.

Was für Risiken sind das? Standardmäßig unterstützt DCOM nur eine 'Einzelschritt-Personifizierung'. Stellen Sie sich zum Beispiel vor, Sie führen ein Script auf Computer A aus, das Informationen von Computer B abfragen soll. Das Script kann für den 'einzelnen Schritt' von Computer A zu Computer B eine Personifizierung durchführen. Was passiert jedoch, wenn Computer B Informationen von einem dritten Computer abfragen muss? Standardmäßig kann das Script für diesen 'Doppelschritt' keine Personifizierung mehr durchführen. Es schlägt daher fehl.

Es ist natürlich möglich, Computer B ebenfalls zu erlauben, Ihre Anmeldeinformationen zu verwenden - auch den Computer D, E und G können Sie dies erlauben. Hier tritt jedoch das Sicherheitsrisiko zu tage. Bei zwei Computern können Sicherheitsprobleme auf die beiden Computer beschränkt werden. Bei vielen Computern sind diese auch alle von Sicherheitsproblemen betroffen.

Die unterschiedlichen DCOM-Sicherheitsebenen werden weiter unten in diesem Kapitel im Abschnitt WMI-Scripte erstellen besprochen. Dort erfahren Sie auch mehr zu entsprechenden Sicherheitsmaßnahmen.

Windows-Betriebssystem-Standardsicherheit

Zusätzlich zu den WMI- und DCOM-spezifischen Sicherheitseinstellung verwendet WMI auch die Standardsicherheitseinstellung des Betriebssystems. Nehmen wird zum Beispiel einmal an, jemand wird durch die Sicherheitseinstellungen eines Ordners daran gehindert, in den Ordner zu schreiben. Wenn diese Person diesen Vorgang über ein WMI-Script auszuführen versucht, dann gelten die Sicherheitseinstellungen des Ordners auch für das Script.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Was passiert, wenn das Script trotzdem Schreiboperationen in diesem Ordner durchführen muss? In diesem Fall müssen Sie entweder die NTFS-Berechtigungen des Ordners ändern, oder das Script unter einem Benutzerkonto ausführen, das die entsprechenden Rechte besitzt.

Dn151185.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Das Common Information Model (CIM)

Wenn Sie ein Haus bauen möchten, dann benötigen Sie jemanden, der die Baupläne lesen und interpretieren kann. Wenn Sie ein elektronisches Gerät bauen möchten, dann benötigen Sie jemanden, der sich mit Schaltplänen auskennt. Wenn Sie WMI-Scripte schreiben möchten, dann müssen Sie wissen, wie Sie mit dem WMI-Blaupausen arbeiten: dem CIM-Repository.

Das CIM-Repository ist das WMI-Schema - in ihm sind alle Klassendefinitionen für alle Ressourcen gespeichert, die über WMI verwaltet werden können.

Um die Wichtigkeit von CIM und den CIM-Klasse zu unterstreichen, sehen Sie sich Script 6.6 und Script 6.7 an. Script 6.6 ist eine erweiterte Version von Script 6.3 - es gibt Informationen über die installierten Dienste zurück.

Script 6.6: Abfragen von Informationen über die installierten Dienste



1

2

3

4

5

6

7

8

9

10

11

12

13

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)

Set colServices = objSWbemServices.InstancesOf("Win32_Service")


For Each objService In colServices

Wscript.Echo "Name: " & objService.Name & vbCrLf & _

"Angez. Name: " & objService.DisplayName & vbCrLf & _

"Beschreibung: " & objService.Description & vbCrLf & _

"Pfadname: " & objService.PathName & vbCrLf & _

"Starttyp: " & objService.StartMode & vbCrLf & _

"Status: " & objService.State & vbCrLf

Next

Script 6.7 ist eine weitere Variante des Scripts. Es verwendet dieses Mal jedoch die Klasse Win32_OperatingSystem. Wie Sie vielleicht erkennen, gibt es Informationen über das installierte Betriebssystem zurück.

Script 6.7: Abfragen von Informationen über das installierte Betriebssystem



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer)

Set colOperatingSystems = _

objSWbemServices.InstancesOf("Win32_OperatingSystem")


For Each objOperatingSystem In colOperatingSystems

Wscript.Echo "Name: " & objOperatingSystem.Name & vbCrLf & _

"Caption: " & objOperatingSystem.Caption & vbCrLf & _

"CurrentTimeZone:" & objOperatingSystem.CurrentTimeZone & vbCrLf & _

"LastBootUpTime: " & objOperatingSystem.LastBootUpTime & vbCrLf & _

"LocalDateTime: " & objOperatingSystem.LocalDateTime & vbCrLf & _

"Locale: " & objOperatingSystem.Locale & vbCrLf & _

"Manufacturer: " & objOperatingSystem.Manufacturer & vbCrLf & _

"OSType: " & objOperatingSystem. OSType & vbCrLf & _

"Version: " & objOperatingSystem.Version & vbCrLf & _

"ServicePack: " & objOperatingSystem.ServicePackMajorVersion & _

"." & objOperatingSystem.ServicePackMinorVersion & vbCrLf & _

"Windows Dir: " & objOperatingSystem.WindowsDirectory

Next

Es gibt zwischen diesen beiden Scripten zwei Unterschiede: der verwendete Klassenname und die Eigenschaften der Klassen. Das erste Script verwendet zum Beispiel die Eigenschaften DisplayName, StartMode und State - das zweite Script fragt die Eigenschaften LastBootUpTime, Version und ServicePackMajorVersion ab.

Dass Sie das gleiche Script verwenden können, um so unterschiedliche Informationen abzufragen, verdeutlicht die wichtige Rolle von CIM-Klassen. Wenn Sie ein Script erstellt haben, können Sie über dieses Scripte viele verschiedene Informationen abfragen.

Zu wissen, wie die Klassen und deren Eigenschaften heißen, ist jedoch nur ein Teil der Arbeit. Bevor Sie WMI voll ausnutzen können, müssen Sie etwas mehr über die Struktur des CIM-Repository und der WMI-Klassen wissen. Und zwar aus zwei Gründen.

  • Wenn Sie das CIM-Repository kennen, wird es Ihnen leichter fallen, die Ressourcen eines Computers oder einer Software zu identifizieren.
  • Wenn Sie die Klassen kenn, werden Sie leichter feststellen können, welche Aufgaben Sie über WMI ausführen können.

Beide Gründe sind unabhängig vom verwendeten WMI-Werkzeug. Egal ob Sie ein WMI-Script oder eine andere Anwendung nutzen - Sie müssen wissen wie das CIM-Repository aufgebaut ist und wie die WMI-Klassen anzuwenden sind.

Ein genauso wichtiger Grund ist, dass das CIM-Repository eine hervorragende Dokumentation der verfügbaren verwalteten Ressourcen ist. Wenn Sie Informationen über eine WMI-Klasse benötigen, können Sie natürlich das WMI-SDK verwenden. Was machen Sie aber, wenn Sie zum Beispiel wissen möchten, ob eine bestimmte Klasse, Methode oder Eigenschaft unter einer bestimmten Windows-Version unterstützt wird? In einem solchen Fall können Sie das CIM-Repository abfragen.

Nehmen wird einmal an, Sie haben sich das folgende Script aus dem Script Center im Microsoft TechNet besorgt:

Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set objComputerSystem = GetObject _
    ("winmgmts:{impersonationLevel=Impersonate}!\\" & strComputer & _
        "\root\cimv2:Win32_ComputerSystem.Name='" & strComputer & "'")
ReturnValue = objComputerSystem.JoinDomainOrWorkGroup _
    ("FABRIKAM", "password", "FABRIKAM\shenalan", NULL, JOIN_DOMAIN+ACCT_CREATE)

Sie möchten wissen, ob das Script unter Windows 2000 ausgeführt werden kann. Wie sich herausstellt kann es nicht ausgeführt werden - und zwar, da die Klasse Win32_ComputerSystem unter Windows 2000 keine Methode JoinDomainOrWorkGroup zur Verfügung stellt. Die Methode wurde erst unter Windows XP hinzugefügt.

Aber wie finden Sie das heraus - außer über das Ausprobieren des Scripts? Ein Weg wäre die Verwendung der WMI-Tools, die weiter unten in diesem Kapitel im Abschnitt Das CIM-Repository erkunden beschrieben werden. Ein deutlich flexiblerer Ansatz ist jedoch die Verwendung der WMI-Scripting-Bibliothek. Eine nützliche Eigenschaft von WMI ist die Tatsache, dass Sie mit der Scripting-Bibliothek Informationen über WMI selbst abfragen können. Sie können zum Beispiel WMI-Scripte schreiben, die alle Namespaces und Klassen im CIM-Repository ausgeben. Sie können auch ein Script schreiben, das alle installierten Provider ausgibt.

Blaupausen

WMI vereinheitlicht die Konfiguration und Verwaltung von Ressourcen über das CIM-Repository - dem Schema von WMI. Stellen Sie sich das Schema als Blaupause oder Modell vor, das für ein echtes Objekt steht.

In Abbildung 6.2 sehen Sie eine konzeptuelle Ansicht der internen Struktur und Organisation des CIM-Repository. Wie Sie sehen verwendet CIM für das Datenmodell Klassen. Es enthält jedoch weit mehr Klassen als im Diagramm zu sehen.

In Abbildung 6.2 werden drei wichtige CIM-Konzepte gezeigt:

  1. Das CIM-Repository ist in mehrere Namespaces aufgeteilt.
  2. Jeder Namespace kann eine oder mehrere der folgenden Klassengruppen enthalten:
    • Systemklassen
    • Kernklassen oder allgemeine Klassen
    • Erweiterungsklassen
  3. Es gibt vier primäre Klassentypen: abstrakt, statisch und dynamisch.
    • Eine abstrakte Klasse ist eine Vorlage von der neue abstrakte oder nicht-abstrakte Klassen abgeleitet werden. Sie kann nicht zur Erstellung von Instanzen verwalteter Objekte verwendet werden.
    • Eine statische Klasse definiert im CIM-Repository gespeicherte Daten. Normalerweise handelt es sich hierbei um die WMI-Konfiguration und operative Daten.
    • Eine dynamische Klasse ist eine Klasse, die zur Erstellung neuer Instanzen verwalteter Ressourcen verwendet wird.
    • Eine assoziative Klasse ist eine abstrakte, statische oder dynamische Klasse, die eine Beziehung zwischen zwei Klassen oder verwalteten Ressourcen beschreibt.

Dn151185.5F38E4F8A830D7F7EF40E86AB335CC1A(de-de,TechNet.10).png

Abbildung 6.2: Strukturelle Ansicht des CIM-Repository (WMI-Schema)

Namespaces

CIM-Klassen sind in Namespaces organisiert. Namespaces sind Partitionierungsmechanismen, mit denen das CIM den Bereich und die Sichtbarkeit von Klassendefinitionen steuert. Jeder Namespace im CIM enthält eine logische Gruppe mit den Klassen zu einer bestimmten Technologie oder zu einem bestimmten Bereich der Verwaltung.

Namespaces sind das gleiche wie Ordner in einem Laufwerk. Wie Ordner bieten auch Namespaces einen Platz, um zusammengehörige Informationen zu speichern. Ein Ordner mit dem Namen Scripts enthält wahrscheinlich Scripte - ein Namespace mit dem Namen MicrosoftActiveDirectory enthält wahrscheinlich Informationen über Active Directory. So wie Sie nur eine Datei mit dem Namen C:\Scripts\WMI_Script.vbs haben können, so können Sie auch nur eine Klasse mit dem Namen root\cimv2:Win32_Process haben.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Ein Unterschied zwischen Ordner und den WMI-Namespaces ist, dass Ordner oft tief verschachtelt sind. Namespaces sind hingegen sind selten mehr als drei Ebenen tief. Die meisten Klassen zur Systemadministration befinden sich zum Beispiel unter root\cimv2 - also schon in der zweiten Ebene.

Alle Klassen in einem Namespace müssen einen eindeutigen Klassennamen haben. Klassen in einem Namespace können nicht von Klassen in einem anderen Namespace abgeleitet werden. Daher finden Sie in unterschiedlichen Namespaces identische Systemklassen, Kernklassen und allgemeine Klassen.

Die meisten Klassen zur Verwaltung von Ressourcen befinden sich im Namespace root\cimv2. root\cimv2 ist jedoch nicht der einzige Namespace, auf den Sie achten müssen. Der Provider Registry speichert seine Klassendefinitionen zum Beispiel im Namespace root\default.

Einen Namespace angeben

Jedes WMI-Script verbindet sich im ersten Schritt mit einem Namespace. Die folgende Codezeile verbindet das Script zum Beispiel mit dem Namespace root\cimv2 auf dem lokalen Computer (die Verbindung wird deshalb mit dem lokalen Computer aufgebaut, weil kein Computername angegeben ist):

Set objSWbemServices = GetObject("winmgmts:root\cimv2")

Eine Verbindung wird auch dann hergestellt, wenn kein Namespace im Verbindungs-String angegeben wird:

Set objSWbemServices = GetObject("winmgmts:")

Wenn keine Namespace definiert wurde, dann verbindet sich das Script mit dem Standard-Namespace. Dieser Standard-Namespace wird im folgenden Registrierungschlüssel definiert:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\Scripting\Default Namespace

Wenn Sie bei der Abfrage von verwalteten Ressourcen keinen Namespace angeben, sucht WMI die Klassendefinition nur im Standard-Namespace. Wenn dieser dort nicht zu finden ist, kommt es zum Fehler WBEM_E_INVALID_CLASS (0x80041010).

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Verwechseln Sie nicht den Standard-Namespace mit dem Namespace root\DEFAULT. Solange Sie den Standard-Namespace nicht auf root\DEFAULT setzen, haben die beiden nichts mit einander zu tun.

Normalerweise ist der Namespace root\cimv2 der Standard-Namespace. Er kann jedoch auch ganz einfach geändert werden. Um sicherzustellen, dass Ihr Script korrekt ausgeführt wird, sollten Sie daher immer einen Namespace angeben. Das folgende Codestück zeigt, wie Sie einen Namespace angeben. Es verwendet außerdem die Variable strComputer, um den Computernamen anzugeben, gegen den das Script ausgeführt wird:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Warum wurde der Wert von strComputer auf "." gesetzt? Bei WMI-Scripting ist der erste Teil eines Objektpfads immer der Name des Computers. Wenn kein Computername oder nur ein Punkt angegeben wird, dann wird das Script gegen den lokalen Computer ausgeführt. Durch die Variable, die auf den Wert "." gesetzt wird, erreichen Sie zwei Dinge: Das Script wird gegen den lokalen Computer ausgeführt und Sie haben die Möglichkeit, einen anderen Computer einzutragen und das Script so ganz einfach gegen einen Remotecomputer auszuführen.

Konfigurieren des Standard-Namespace

Sie können die WMI-Scripting-Bibliothek zusammen mit der Klasse Win32_WMISetting verwenden, um den Standard-Namespace auszulesen und zu ändern. Script 6.8 und Script 6.9 demonstrieren dies. Bei Win32_WMISetting handelt es sich um eine dynamische Klasse mit operativen Parametern des WMI-Dienstes. Über die Eigenschaft ASPScriptDefaultNamespace können Sie auf den Standard-Namespace zugreifen.

Script 6.8 verwendet die bereits bekannten drei Schritte: verbinden, abfragen und anzeigen. Wie oben empfohlen, wird beim Verbinden ein Namespace für die Klasse Win32_WMISetting angegeben.

Script 6.8: Abfragen des Standard-Namespace



1

2

3

4

5

6

7

8

9

10

strComputer = "."


Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colWMISettings = objSWbemServices.InstancesOf("Win32_WMISetting")


For Each objWMISetting in colWMISettings

Wscript.Echo "Der Standard-Namespace ist: " & _

objWMISetting.ASPScriptDefaultNamespace

Next

Wenn Sie das Script unter CScript ausführen, erhalten Sie die folgende Ausgabe:

Der Standard-Namespace ist: root\cimv2

Um den Standard-Namespace zu ändern, können Sie Script 6.8 erneut verwenden - mit einer wichtigen Änderung: Statt die Eigenschaft zu lesen, gehen Sie folgendermaßen vor:

  1. Sie schreiben einen neuen Wert in die Eigenschaft.
  2. Sie rufen die Methode SWbemObject.Put_ auf, um die Änderung an die WMI-Ressource zu übermitteln.
    Diese Aufgabe wird in einer For-Each-Schleife durchgeführt. Und zwar darum, weil die Methode InstancesOf immer eine Collection zurückgibt. Dies passiert auch dann, wenn es nur eine Instanz der Ressource gibt (so wie bei der Klasse Win32_WMISetting).

Script 6.9: Konfigurieren des Standard-Namespace



1

2

3

4

5

6

7

8

9

10

strComputer = "."


Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colWMISettings = objSWbemServices.InstancesOf("Win32_WMISetting")


For Each objWMISetting in colWMISettings

objWMISetting.ASPScriptDefaultNamespace = "root\cimv2"

objWMISetting.Put_

Next

Abrufen von Namespaces

Über WMI-Scripting können Sie nicht nur Informationen über Ressourcen abrufen, sondern auch Informationen über das CIM. Die einzige Änderung zu den vorherigen Scripten ist in diesem Fall der verwendete Klassenname.

Namespace-Informationen werden im CIM als statische Instanzen der Klasse __NAMESPACE gespeichert. Im Gegensatz zu verwalteten Ressourcen, bei denen die Informationen über einen Provider abgerufen werden, werden die Informationen von Instanzen statischer Klassen direkt im CIM gespeichert und von dort auch ohne einen WMI-Provider abgerufen. Script 6.10 verwendet die Klasse __NAMESPACE, um alle Namespaces direkt unter dem Namespace root abzurufen.

Script 6.10: Abrufen der Namespaces direkt unter root



1

2

3

4

5

6

7

8

strComputer = "."


Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root")

Set colNameSpaces = objSwbemServices.InstancesOf("__NAMESPACE")


For Each objNameSpace In colNameSpaces

Wscript.Echo objNameSpace.Name

Next

Wenn Sie das Script unter Windows 2000 ausführen, erhalten Sie die folgende Ausgabe:

DEFAULT
SECURITY
CIMV2
WMI
directory

Die Liste der Namespaces variiert je nach der verwendeten Windows-Version und der installierten WMI-Version. Auch WMI-Anwendungen beeinflussen die Liste. Unter Windows XP mit installiertem Microsoft® Office XP und dem .NET Framework erhalten Sie zum Beispiel die folgende Liste:

SECURITY
RSOP
Cli
WMI
CIMV2
MSAPPS10
Policy
Microsoft
DEFAULT
directory
subscription
NetFrameworkv1

Script 6.10 gibt nicht alle Namespaces auf dem Computer aus. Es zeigt nur die Namespaces an, die sich direkt unter dem Namespace root befinden. Um alle Namespaces anzuzeigen, müssen Sie das Script verändern. Wie Script 6.11 zeigt, ist dies jedoch nicht so schwer, wie Sie vielleicht denken.

Script 6.10 wird einfach in ein rekursives Script umgewandelt. Hierzu wird der Hauptteil des Scripts in eine Subroutine verschoben. Das Script geht folgendermaßen vor:

  1. Es initialisiert die Variable strComputer mit dem Namen des Zielcomputers.
  2. Es ruft die Subroutine EnumNameSpaces auf und übergibt ihr den Start-Namespace root. Der Inhalte der Subroutine EnumNameSpaces ist mit Script 6.10 identisch - mit einer wichtigen Ausnahme:
    1. Die Subroutine gibt als erstes das Argument aus, mit dem sie aufgerufen wurde: strNameSpace.
      Die Variable strNameSpace definiert den Namespace, der bei jedem Aufruf der Subroutine im Verbindungs-String verwendet wird. Beim ersten Aufruf der Subroutine enthält strNameSpace den Wert "root".
    2. Sie verwendet die VBScript-Funktion GetObject, um eine Verbindung mit dem Namespace aufzubauen, der in der Variable strNameSpace angegeben ist.
    3. Nach dem Verbindungsaufbau fragt die Subroutine alle Namespaces direkt unter dem Namespace ab, mit dem die Verbindung aufgebaut wurde.
    4. Die Subroutine verwendet eine For-Each-Schleife, um die Liste der direkten Unter-Namespaces aufzulisten. Statt die Namen der Namespaces jedoch auszugeben, ruft sich die Subroutine selbst mit dem jeweiligen Namen des Unter-Namespaces auf.
  3. Die Schritte a bis d werden so lange durchgeführt, bis alle Namespaces aufgelistet sind.

Script 6.11: Abfragen aller CIM-Namespaces



1

2

3

4

5

6

7

8

9

10

11

12

strComputer = "."

Call EnumNameSpaces("root")


Sub EnumNameSpaces(strNameSpace)

Wscript.Echo strNameSpace

Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\" & strNameSpace)

Set colNameSpaces = objSWbemServices.InstancesOf("__NAMESPACE")

For Each objNameSpace In colNameSpaces

Call EnumNameSpaces(strNameSpace & "\" & objNameSpace.Name)

Next

End Sub

Unter Windows 2000 Advanced Server erhalten Sie die folgende Ausgabe:

root
root\DEFAULT
root\SECURITY
root\CIMV2
root\CIMV2\Applications
root\CIMV2\Applications\MicrosoftIE
root\CIMV2\ms_409
root\WMI
root\directory
root\directory\LDAP
root\directory\LDAP\ms_409
root\MicrosoftNLB
root\MicrosoftNLB\ms_409

Klassenkategorien

Wie Sie in Abbildung 6.2 gesehen haben, gibt es drei generelle Kategorien von Klassen: system, Kern und allgemein und erweitert.

Systemklassen

Systemklassen sind Klassen, die die interne WMI-Konfigurationen zur Verfügung stellen - zum Beispiel die Namespace-Konfiguration, die Namespace-Sicherheit, die Registrierung von Providern und die Ereignisbenachrichtigung. Wenn Sie sich das CIM anschauen, dann können Sie die Systemklassen leicht an den beiden Unterstrichen erkennen.

Systemklassen sind entweder von Typ abstrakt oder statisch. Abstrakte Systemklassen sind Vorlagen zum Ableiten (oder Definieren) anderer abstrakter oder statischer Systemklassen. Statische Systemklassen definieren die WMI-Konfiguration im CIM -Repository. Die Systemklasse __Win32Provider stellt zum Beispiel Informationen zur Providerregistrierung zur Verfügung.

Wie bereits mit der Systemklasse __NAMESPACE demonstriert, können Sie WMI nutzen, um die statischen Instanzen der Systemklassen abzufragen. Script 6.12 fragt zum Beispiel alle Instanzen der Klasse __Win32Provider im Namespace root\cimv2 ab.

Script 6.12: Abfragen der im Namespace root\comv2 registrierten Win32-Provider



1

2

3

4

5

6

7

8

strComputer = "."

Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colWin32Providers = objSWbemServices.InstancesOf("__Win32Provider")


For Each objWin32Provider In colWin32Providers

Wscript.Echo objWin32Provider.Name

Next

Wenn Sie das Script unter Windows 2000 ausführen, erhalten Sie die folgende Ausgabe:

CIMWin32
WBEMCORE
MS_Power_Management_Event_Provider
MS_NT_EVENTLOG_PROVIDER
MS_NT_EVENTLOG_EVENT_PROVIDER
SECRCW32
MSIProv
NT5_GenericPerfProvider_V1

Wahrscheinlich werden Sie Systemklassen eher selten verwenden - mit einer Ausnahme: WMI-Überwachungsscripts abbonieren bestimmte WMI-Ereignisse, um bei deren Auftreten benachrichtigt zu werden. Dieses Thema wird jedoch später in diesem Kapitel besprochen.

Kernklassen und allgemeine Klassen

Diese Klassen haben zwei Aufgaben. Erstens sind sie die abstrakten Klassen, von denen System- und Softwareentwickler technologiespezifische Erweiterungsklassen ableiten können. Zweitens definieren Sie Ressourcen im Bezug auf bestimmte Bereiche der Verwaltung, die nicht von einer bestimmen Technologie oder Implementierung abhängen. Theoretisch sind dies Ressourcen, die jedes Betriebssystem unterstützt. Die DMTF definiert einen Satz an Kernklassen und allgemeinen Klassen. Diesen können Sie über den Prefix CIM_ prefix erkennen.

Von den 275 Kernklassen und allgemeinen Klassen im Namespace root\cimv2 sind fast alle abstrakte Klassen. Da Sie keine Instanzen von abstrakten Klassen erstellen können, werden Sie diese eher selten verwenden. Sie werden normalerweise nur von System- und Softwareentwicklern genutzt.

Vier der 275 Klassen sind dynamische Klassen. Diese vier Klassen sind CIM_DataFile, CIM_DirectoryContainsFile, CIM_ProcessExecutable und CIM_VideoControllerResolution. Sie können zum Abrufen von Informationen über Ressourcen verwendet werden. Das folgende Script gibt zum Beispiel Informationen über alle möglichen Auflösungen der Grafikkarte zurück:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colVideoControllers = _
    objSWbemServices.InstancesOf("CIM_VideoControllerResolution")
For Each objVideoController In colVideoControllers
    Wscript.Echo objVideoController.HorizontalResolution
    Wscript.Echo objVideoController.VerticalResolution
    Wscript.Echo objVideoController.NumberOfColors
    Wscript.Echo objVideoController.RefreshRate
Next

Erweiterungsklassen

Erweiterungsklassen sind technologiespezifische Klassen, die von System- und Softwareentwicklern verwendet werden. Erweiterungsklassen von Microsoft sind zum Beispiel Win32_BaseService, Win32_Service, Win32_SystemServices und Win32_ComputerSystem. Die Erweiterungsklassen von Microsoft im Namespace root\cimv2 erkennen Sie am Prefix Win32_.

Gehen Sie jedoch nicht davon aus, dass alle Microsoft-Erweiterungsklassen mit Win32_ beginnen - dies ist nicht der Fall. Die Klasse StdRegProv in root\DEFAULT hält sich zum Beispiel nicht an diese Regel.

In der aktuellsten Version von WMI gibt es im Namespace root\cimv2 463 Erweiterungsklassen. Von den 463 Win32-Klassensind 68 abstrakte Klassen und 395 dynamische. Die meisten Klassen, die Sie in Ihren Scripten verwenden werden, sind Erweiterungsklassen.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Die tatsächliche Anzahl der Klassen kann von vielen verschiedenen Faktoren abhängen - zum Beispiel von der Windows-Version und der installierten WMI-Version.

Auflisten der Klassen in einem Namespace

Sie können ein Script schreiben, dass alle Klassen in einem bestimmen Namespace auflistet. Script 6.13 demonstriert dies, indem es alle Klassen im Namespace root\cimv2 auflistet. Im Gegensatz zu den vorherigen Scripten, die die Methode SWbemServices.InstancesOf verwendet haben, verwendet das Script jedoch die Methode SubclassesOf.

Wie der Name schon sagt, gibt die Methode SubclassesOf alle untergeordneten Klassen einer bestimmten Klasse oder eines bestimmten Namespaces zurück. Wie InstancesOf gibt auch SubclassesOf die Unterklassen als Collection zurück. Jedes Element in der Collection ist eine Klasse.

Ein neues Element in Script 6.13 ist die Eigenschaft objClass.Path_.Path. Sie wird in der For-Each-Schleife verwendet. Wie in den anderen Scripten dieses Kapitels, geht die Schleife alle Elemente der von der Methode SubclassesOf zurückgegebenen Collection durch.

Im Gegensatz zu den vorherigen Scripten ist Path_ jedoch eine Eigenschaft von SWbemObject. Um dies zu verstehen, müssen Sie sich überlegen, in welchem Kontext das Script SWbemObject verwendet. In diesem Fall greift es nicht auf eine Instanz einer verwalteten Ressource zu (zum Beispiel ein Dienst, ein Prozess, etc.), sondern auf die Klassendefinition der verwalteten Ressource.

Wenn Sie mit SWbemObject auf eine Instanz einer verwalten Ressourcen zugreifen, dann greifen Sie auf die Eigenschaften und Methoden zu, die über die Klassendefinition für die verwaltete Ressource definiert werden. Wenn Sie SWbemObject jedoch verwenden, um Informationen über die Klasse selbst abzurufen, dann verwenden Sie die Eigenschaften und Methoden von SWbemObject selbst - Path_ ist eine solche Eigenschaft.

Path_ ist eine Referenz auf eine andere WMI-Scripting-Bibliothek mit dem Namen SWbemObjectPath. Diese stellt die Eigenschaft Path zur Verfügung. Die Eigenschaft SWbemObjectPath.Path enthält den vollqualifizierten Pfad zur Klasse, die von SWbemObject referenziert wird (objClass in Script 6.13).

Script 6.13: Abrufen aller Klassen im Namespace root\cimv2



1

2

3

4

5

6

7

8

9

strComputer = "."


Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colClasses = objSWbemServices.SubclassesOf()


For Each objClass In colClasses

Wscript.Echo objClass.Path_.Path

Next

Wenn Sie das Script unter Windows 2000 ausführen, erhalten Sie eine Liste mit 636 Einträgen. Ein Teil der Ausgabe sieht so aus:

\\ATL-WIN2K-01\ROOT\CIMV2:Win32_NTEventlogFile
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_NTLogEvent
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_NTLogEventLog
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_NTLogEventUser
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_NTLogEventComputer
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SID
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_AccountSID
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SecuritySetting
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SecuritySettingOfObject
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SecuritySettingOwner
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SecuritySettingGroup
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SecuritySettingAccess
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SecuritySettingAuditing
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_Trustee
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_ACE
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_SecurityDescriptor
\\ATL-WIN2K-01\ROOT\CIMV2:Win32_LogicalFileSecuritySetting

Sie können Script 6.13 zur Auflistung der Klassen anderer Namespaces anpassen, indem Sie einfach den Ziel-Namespace im Script ändern. Um nach Klassen zu suchen, können Sie das Script zusammen mit dem Befehl findstr.exe verwenden. Findstr.exe ist ein Kommandozeilentool, mit dem Sie in Dateien nach Text suchen können.

Nehmen wir beispielsweise einmal an, Sie möchten wissen, ob Ihre Windows-Version die neue Windows XP-Klasse Win32_TSSessionSetting unterstützt. Mit dem folgenden Befehl können Sie feststellen, ob die Klasse im Namespace root\cimv2 vorhanden ist. Das Script schickt seine Ausgabe an Findstr.exe. Findstr.exe sucht dann in der Ausgabe nach dem Text "Win32_TSSessionSetting".

cscript GetClasses.vbs |findstr /I "win32_tssessionsetting"

Wenn Sie den Befehl unter Windows XP ausführen, erhalten Sie die folgende Ausgabe:

\\ATL-WINXP-01\ROOT\cimv2:Win32_TSSessionSettingError
\\ATL-WINXP-01\ROOT\cimv2:Win32_TSSessionSetting

Wenn sie den Befehl unter Windows 2000 ausführen, erhalten Sie keine Ausgabe. Das bedeutet, dass die Klasse Win32_TSSessionSetting unter Windows 2000 nicht unterstützt wird.

Einige weitere Befehle, die Sie probieren können, sind:

  1. Eine Liste aller Systemklassen im Namespace root\cimv2:
    cscript GetClasses.vbs |findstr /I "__"
  2. Eine Liste aller Kernklassen und allgemeinen Klassen im Namespace root\cimv2:
    cscript GetClasses.vbs |findstr /I "CIM_"
  3. Eine Liste aller Win32-Erweiterungsklassen im Namespace root\cimv2:
    cscript GetClasses.vbs |findstr /I "Win32_"
  4. Eine Liste alle Klassen im Namespace root\cimv2, die den Text "process" enthalten:
    cscript GetClasses.vbs |findstr /I "process"

CIM-Klassentypen

Zu diesem Zeitpunkt sollte klar sein, dass es sich bei den grundlegenden Einheiten im CIM-Repository um die Klassen handelt. Genau wie im Active Directory-Schema werden WMI-Konfiguratinsinformationen und verwaltete Ressourcen durch eine oder mehrere Klassen definiert. CIM-Klassen sind hierarchisch organisiert. Untergeordnete Klassen erben Eigenschaften und Methoden von den übergeordneten Klassen.

Die dynamische Klasse Win32_Service erbt zum Beispiel von der abstrakten Klasse Win32_BaseService. Diese erbt von der abstrakten Klasse CIM_Service, die von der abstrakten Klasse CIM_LogicalElement und diese erbt wiederum von der abstrakten Klasse CIM_ManagedSystemElement. Diese Klassenhierarchie können Sie in Abbildung 6.2 erkennen.

Tabelle 6.3 vergleicht die Eigenschaften dieser Klassen. Wie Sie sehen können, erben Unterklassen alle Eigenschaften von ihrer übergeordneten Klasse. Außerdem definieren Sie meist noch weitere, eigene Eigenschaften. Dies ist auch der Grund, aus dem ein Entwickler eine neue Unterklasse statt einer ganz neuen Klasse definiert. Die übergeordnete Klasse bringt meist bereits viele der benötigten Eigenschaften mit.

CIM_ManagedSystemElementundCIM_LogicalElement

CIM_Service

Win32_BaseService

Win32_Service

Caption

Caption

Caption

Caption

Description

Description

Description

Description

InstallDate

InstallDate

InstallDate

InstallDate

Name

Name

Name

Name

Status

Status

Status

Status


CreationClass
Name

CreationClass
Name

CreationClass
Name


Description

Description

Description


Name

Name

Name


Started

Started

Started


StartMode

StartMode

StartMode


Status

Status

Status


SystemCreation
ClassName

SystemCreation
ClassName

SystemCreation
ClassName


SystemName

SystemName

SystemName



AcceptPause

AcceptPause



AcceptStop

AcceptStop



DesktopInteract

DesktopInteract



DisplayName

DisplayName



ErrorControl

ErrorControl



ExitCode

ExitCode



PathName

PathName



ServiceSpecific
ExitCode

ServiceSpecific
ExitCode



ServiceType

ServiceType



StartName

StartName



State

State



TagID

TagID




Checkpoint




ProcessID




WaitHint

Tabelle 6.3: Vergleich der Eigenschaften von über- und untergeordneten Klassen

Heißt das, dass Sie die Klasse Win32_BaseService verwenden können, um Informationen über Dienste zurückzugeben? Nein - Win32_BaseService ist eine abstrakte Klasse. Das bedeutet, dass sie nur als Vorlage für andere Klassen dient - nicht zum Abfragen von Daten.

Komponenten einer Klasse

Jede Hard- und Softwareressource, die über WMI verwaltet werden kann, wird über eine Klasse definiert. Eine Klasse ist eine Blaupause (oder Vorlage) für eine über WMI verwaltete Ressource. Alle Instanzen einer Ressource verwenden die Blaupause (oder Klassendefinition). Das bedeutet, dass alle Dienste (die auch Instanzen der Klasse Win32_Service sind) die gleichen Eigenschaften haben. Es bedeutet nicht, dass die Eigenschaften alle die gleichen Werte haben.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Wenn eine Eigenschaft nicht mit einem Wert konfiguriert ist, gibt WMI den Wert NULL zurück.

Die Klassendefinitionen (Blaupausen) setzten sich aus Eigenschaften, Methoden und Kennzeichnern zusammen. Bevor wir uns diese Komponenten anschauen, sollten Sie wissen, wo die Klassendefinitionen eigentlich herkommen.

Nehmen wir einmal an, Microsoft entscheidet sich dazu, einen neuen WMI-Provider zu erstellen, den Administratoren zu Verwaltung und Überwachung von DNS-Servern verwenden können. Das entsprechende Team bei Microsoft würde in diesem Fall mindestens zwei Dateien erstellen: Einen Provider und eine MOF-Datei (Managed Object Format).

Der Provider ist die DLL, die als Vermittlungsstelle zwischen der WMI-Infrastruktur und der verwalteten Ressource arbeitet (in diesem Fall der DNS-Server). Der Provider verarbeitet WMI-Anfragen, indem er die nativen APIs der Ressource aufruft.

Die MOF-Datei enthält Klassendefinitionen, die die Features des DNS-Providers beschreiben. DNS-Server verwenden zum Beispiel Zonen und Ressourceneinträge. Daher wird die MOF-Datei wahrscheinlich Klassen wie MicrosoftDNS_Zone und MicrosoftDNS_ResourceRecord definieren.

Wenn der DNS-Provider installiert wird, dann wird dessen DLL beim Betriebssystem und bei WMI registriert. Die MOF-Datei wird kompiliert. Danach ist die DNS-Providerklasse im CIM-Repository vorhanden und kann nun verwendet werden.

MOF-Dateien sind Textdateien, die auf der MOF-Sprache basieren. Die MOF-Sprache wurde vom DMTF entwickelt. Wie Sie in Abbildung 6.3 sehen, folgt eine Klassendefinition einer wohl definierten Struktur und Syntax.

Dn151185.E304D235BE5947DB45AE85A8A73A4680(de-de,TechNet.10).png

Abbildung 6.3: Struktur einer Klassendefinition

Eigenschaften

Eigenschaften beschreiben die verwaltete Ressource. Klassen verwenden Eigenschaften, um Dinge wie Konfigurationen, Status und Namen von verwalteten Ressourcen zu beschreiben. Dienste haben zum Beispiel die Eigenschaften Name, angezeigter Name, Beschreibung, Starttyp und Status. Daher hat die Klasse Win32_Service die gleichen Eigenschaften.

Jede Eigenschaft hat einen Namen, einen Typ und optional einen Kennzeichner. Über den Namen greifen Sie auf die Eigenschaft zu:

Wscript.Echo objService.Name
Wscript.Echo objService.Description

In der MOF-Datei sieht die Eigenschaftsdefinition so aus (Name, Datentyp und Kennzeichner sind fett formatiert):

[read : ToSubclass,MappingStrings{"Win32API|Service Structures|SERVICE_STATUS|dwControlsAccepted|
SERVICE_ACCEPT_PAUSE_CONTINUE"} : ToSubclass] boolean AcceptPause;

Methoden

Methoden führen Aktionen mit einer verwalteten Ressource aus. Mit den Methoden der Klasse Win32_Service können Sie zum Beispiel einen Dienst anhalten und starten.

Jede Methode hat einen Namen, einen Rückgabewert, optionale Parameter und optionale Methoden-Kennzeichner. Das folgende Scriptstück hält zum Beispiel einen Dienst an. Wenn der Rückgabewert der Methode ungleich 0 ist, dann ist der Vorgang fehlgeschlagen (normalerweise bedeutet der Rückgabewert 0 immer, dass eine Methode erfolgreich ausgeführt wurde):

errReturn = obService.StopService()
Wscript.Echo errReturn

Nicht alle Klassen stellen Methoden zur Verfügung. Unter Windows 2000 stellen zum Beispiel die Klassen Win32_Service, Win32_NTEventLogFile und Win32_Process Methoden zur Verfügung. Unter Windows XP gibt es noch bei einigen weiteren Klassen Methoden (zum Beispiel Win32_DiskQuota und Win32_Printer).

Kennzeichner

Kennzeichner sind zusätzliche Informationen über eine Klasse, eine Eigenschaft oder eine Methode. Wenn Sie Scripte schreiben, die etwas mehr machen als nur Informationen abzufragen (zum Beispiel Eigenschaften ändern oder Methoden aufrufen), werden Kennzeichner schnell sehr wichtig. Dies liegt daran, dass die Charakteristika einer Eigenschaft oder Methode beschreiben.

Welche Informationen stellen Ihnen Kennzeichner nun zur Verfügung? Erstmal sollten Sie wissen, dass es drei Arten von Kennzeichnern gibt - somit gibt es auch drei unterschiedliche Informationstypen.

Klassenkennzeichner

Klassenkennzeichner stellen Ihnen zusätzliche Informationen über eine Klasse zur Verfügung:

  • Die Kennzeichner Abstract (Abstrakt), Dynamic(Dynamisch) und Association (Assoziativ) zeigen den Klassentyp an.
  • Der Kennzeichner Provider gibt an, welcher Provider für die Klasse zuständig ist.
  • Der Kennzeichner EnumPrivileges gibt die erforderlichen Rechte zu Verwendung der Klasse an. Der Kennzeichner EnumPrivileges der Klasse Win32_NTLogEvent teilt Ihnen zum Beispiel mit, dass das Recht SeSecurityPrivilege zur Verwendung der Klasse notwendig ist.

Eigenschaftskennzeichner

Eigenschaftskennzeichner stellen Informationen über eine Eigenschaft zu Verfügung:

  • Der Kennzeichner CIMType gibt den Datentyp der Eigenschaft an. WMI unterstützt einige unterschiedliche Datentypen (zum Beispiel String, Integer, Date, Array und Boolean).
    Ist es wirklich wichtig, welchen Datentyp eine Eigenschaft hat? Für die bisherigen einfachen Beispiele nicht. Stellen Sie sich jedoch vor, Sie verwenden die Klasse Win32_Printer und fragen die Eigenschaft Capabilities ab. Diese Eigenschaft gibt ein Array zurück. Konsequenterweise können Sie die Eigenschaft nicht einfach ausgeben:
    Wscript.Echo objPrinter.Capabilities Stattdessen müssen Sie die einzelnen Elemente des Arrays durchgehen:
    For Each intCapability in objPrinter.Capabilities
    Wscript.Echo intCapability
    Next
  • Der Kennzeichner Read zeigt, ob die Eigenschaft gelesen werden kann.
  • Der Kennzeichner Write zeigt, ob Sie die Eigenschaft verändern können. Die Eigenschaft ASPScriptDefaultNamespace der Klasse Win32_WMISetting, die in Script 6.9 verändert wird, ist zum Beispiel schreibbar. Die anderen in den bisherigen Scripten verwendeten Eigenschaften sind hingegen nur lesbar. Ausnahmen sind Eigenschaften, die Sie über eine Methode ändern.
  • Der Kennzeichner Key zeigt an, ob die Eigenschaft ein Klassenschlüssel ist und zur eindeutigen Identifizierung einer Instanz einer verwalteten Ressource verwendet wird.
    DeviceID ist zum Beispiel eine Schlüsseleigenschaft von Win32_LogicalDisk.

Methodenkennzeichner

Methodenkennzeichner stellen Informationen über Methoden zur Verfügung:

  • Der Kennzeichner Implemented zeigt an, dass eine Methode über einen Provider implementiert ist. Dies ist wichtig, da WMI-Klassen oftmals Methoden enthalten, die noch nicht funktionieren (da sie noch nicht implementiert wurden).
  • Der Kennzeichner ValueMap definiert die Werte, die als Parameter verwendet werden können und den Rückgabewert.
  • Der Kennzeichner Privileges definiert die zum Aufrufen der Methode erforderlichen Rechte.
Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Es gibt noch deutlich mehr Kennzeichner. Eine komplette Liste der WMI-Kennzeichner finden Sie im WMI SDK. Das SDK finden Sie unter dem Link Microsoft Windows Management Instrumentation (WMI) SDK unter https://www.microsoft.com/windows/reskits/webresources (englischsprachig).

Vergleich zwischen Klassen und verwalteten Ressourcen

Klassen legen fest, was Sie mit WMI machen können und was nicht. Wenn Sie eine Klasse für Dienste haben, können Sie diese verwalten - wenn nicht, dann nicht. Konsequenterweise ist es also wichtig zu wissen, welche Klassen auf einem Computer vorhanden sind.

Der Umfang von WMI unterscheidet sich unter verschiedenen Betriebssystemen. Die Klasse Win32_ComputerSystem stellt unter Windows XP viele neue Eigenschaften und Methoden zur Verfügung, die unter Windows 2000 nicht vorhanden sind. Damit Ihr Script funktioniert, müssen Sie wissen, welche Eigenschaften und Methoden vorhanden sind.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Mit WMI können Sie keine Informationen von einem Remotecomputer abfragen, wenn WMI auf diesem nicht installiert ist. Auch die verwendeten Methoden und Eigenschaften müssen vorhanden sein. Ein WMI-Script, das lokal auf einem Computer unter Windows XP korrekt ausgeführt wird, kann daher auf einem Remotecomputer unter Windows 2000 durchaus fehlschlagen.

Wie stellen Sie fest, ob eine Methode oder Eigenschaft auf einem bestimmten Computer zur Verfügung steht? Sie fragen die Klassendefinition ab.

Abfragen von Klassendefinitionen

Sie können die WMI-Scripting-Bibliothek verwenden, um die Klassendefinitionen von verwalteten Ressourcen abzufragen. Hierzu gibt es zwei Wege:

  • Sie verwenden die Eigenschaften SWbemObject.Qualifiers_, SWbemObject.Properties_ und SWbemObject.Methods_.
  • Sie verwenden die Methode SWbemObject.GetObjectText_, um eine Klassendefinition in der MOF-Syntax zu erhalten.

Verwenden der Eigenschaften Properties_, Methods_ and Qualifiers_

Script 6.14, Script 6.15 und Script 6.16 zeigen, wie Sie die Eigenschaften Properties_, Methods_ und Qualifiers_ zur Abfrage von Informationen über die Klasse Win32_Service verwenden können. Alle drei Scripte gehen nach dem gleichen Ansatz vor - es gibt allerdings auch einige Unterschiede.

Script 6.14 beginnt mit der Initialisierung von drei Variablen: strComputer, strNameSpace und strClass. strComputer werden als Wert der Namen des Zielcomputers zugewiesen. strNameSpace wird der Name des Namespace zugewiesen, mit dem eine Verbindung aufgebaut werden soll, und strClass erhält als Wert den Namen der Klasse, dessen Eigenschaften abgefragt und angezeigt werden soll.

Wenn diese drei Werte in einzelnen Variablen gespeichert werden, wird es einfach, das Script für andere Computer, Namespaces und Klassen zu verwenden. Mit der Collection WSH Arguments können Sie das Script sogar ganz einfach in einem Kommandozeilentool verwenden. Weitere Informationen hierzu finden Sie im Kapitel Der WSH in diesem Buch.

Als Nächstes verwendet das Script die VBScript-Funktion GetObject, um eine Verbindung mit dem WMI-Dienst auf dem Zielcomputer zu erstellen. Vielleicht ist Ihnen etwas bei dem Verbindungsstring aufgefallen, der an GetObject übergeben wird. Zusätzlich zum Namespace wird auch noch der Klassenname angegeben. Dies hat weit reichende Auswirkungen auf das, was die Methode GetObject zurückgibt. Statt eine Referenz auf ein SWbemServices-Objekt zurückzugeben (wie in den bisherigen Scripten), gibt GetObject nun eine Referenz auf ein SWbemObject zurück, das die Zielklasse darstellt. Wie das? Die Antwort liegt im Objektpfad. Auch wenn Objektpfade später in diesem Kapitel noch genauer besprochen werden, wollen wir hier eine kurze Einführung geben. Sie wird Ihnen beim Verständnis des Scripts helfen.

Jede WMI-Klasse und jede Instanz einer verwalteten Ressource hat einen Objektpfad. Ein Objektpfad ist so ähnlich wie ein Dateipfad. Eine Datei hat einen voll qualifizierten Pfad - dieser setzt sich aus einem Gerätenamen, einem oder mehreren Ordnernamen und dem Dateinamen zusammen. Klassen und verwaltete Ressourcen haben ebenfalls solche Pfade - sie setzen sich aus dem Computernamen, dem Namespace, dem Klassenamen, der Schlüsseleigenschaft der Klasse und dem Wert der Schlüsseleigenschaft zusammen. Ein solcher Objektpfad sieht zum Beispiel so aus (die eckigen Klammern trennen nur die einzelnen Teile des Objektpfads - sie werden normalerweise weggelassen):

[\\ComputerName][\Namespace][:Klassenname][.Schlüsseleigenschaft='Wert']

Wenn Sie den gesamten Objektpfad oder einen Teil des Objektpfads im Verbindungsstring von GetObject verwenden, dann legt dieser den zurückgegebenen Referenztyp fest. Wenn Sie zum Beispiel nur den Computernamen-Teil des Objektpfads angeben, dann erhalten Sie eine SWbemServices-Objektreferenz zurück, die mit dem Standard-Namespace verbunden ist. Wenn Sie den Computernamen oder den Namenspace oder beides angeben, erhalten Sie ebenfalls eine Referenz auf ein SWbemServices-Objekt. Wenn Sie den Computernamen, den Namespace und den Klassennamen angeben erhalten, Sie eine Referenz auf ein SWbemObject zurück, das eine Klasse darstellt. Wenn Sie alle vier Teile des Objektpfads angeben, erhalten Sie ein SWbemObject zurück, das eine Instanz eines verwalteten Objekts darstellt - und zwar die Instanz, die durch den Wert der Schlüsseleigenschaft definiert wird.

Die Elemente des Objektpfads und die zurückgegebenen Objekte sind in Tabelle 6.4 zusammengefasst.

Tabelle 6.4: Elemente des Objektpfads und die zurückgegebenen Objekte

Teile des Objektpfads

Zurückgegebenes Objekt

Computername:
Set objSWbemServices = _
GetObject("winmgmts:\\WebServer")

SWbemServices
(verbunden mit dem
Standard-Namespace)

Computername und/
oder Namespace:
Set objSWbemServices = _
GetObject
("winmgmts:\\WebServer\root\cimv2")

SWbemServices
(verbunden mit den
angegebenen Namespace -
in diesem Fall root\cimv2)

Computername, Namespace,
Klassenname:
Set objSWbemObject = GetObject _
("winmgmts:\\WebServer\root\
cimv2:Win32_Service")

SWbemObject (stellt die
Klasse Win32_Service dar)

Computername, Namespace,
Klassenname, Schlüsseleigenschaft:
Set objSWbemObject = GetObject _
"winmgmts:\\WebServer\root\cimv2:" & _
Win32_Service.Name='Alerter'")

SWbemObject (stellt die
Instanz des Dienstes
mit dem Namen Alerter dar)

Der Rest des Scripts ist ganz einfach. Es verwendet die SWbemObject-Referenz (objClass), um auf die Eigenschaften (objClass.Properties_) zuzugreifen. Properties_.property referenziert eine Collection mit den Eigenschaften der Klasse (SWbemPropertySet). Jede Eigenschaft in der Collection ist ein SWbemProperty-Objekt (objClassProperty) dessen Eigenschaftsname gelesen und ausgegeben wird.

Script 6.14: Abfragen der Eigenschaften von Win32_Service über SWbemObject.Properties_



1

2

3

4

5

6

7

8

9

10

11

12

13

strComputer = "."

strNameSpace = "root\cimv2"

strClass = "Win32_Service"


Set objClass = GetObject("winmgmts:\\" & strComputer & _

"\" & strNameSpace & ":" & strClass)


Wscript.Echo strClass & " Eigenschaften "

Wscript.Echo " — — — — — — — — — — — — — — — "


For Each objClassProperty In objClass.Properties_

Wscript.Echo objClassProperty.Name

Next

Wenn Sie das Script ausführen, werden die 25 Eigenschaften der Klasse Win32_Service angezeigt.

Win32_Service Eigenschaften
- - - - - - - - - - - - - - -
AcceptPause
AcceptStop
Caption
CheckPoint
CreationClassName
Description
DesktopInteract
DisplayName
ErrorControl
ExitCode
InstallDate
Name
PathName
ProcessId
ServiceSpecificExitCode
ServiceType
Started
StartMode
StartName
State
Status
SystemCreationClassName
SystemName
TagId
WaitHint

Script 6.15 ist mit Script 6.14 bis auf eine Ausnahme identisch: Eine For-Each-Schleife geht die Collection SWbemMethodSet durch und zeigt die Eigenschaft Name jeder Methode (objClassMethod) in der Collection SWbemMethodSet an.

Script 6.15: Verwenden von SWbemObject.Methods_, um die Methoden von Win32_Service abzufragen



1

2

3

4

5

6

7

8

9

10

11

12

13

strComputer = "."

strNameSpace = "root\cimv2"

strClass = "Win32_Service"


Set objClass = GetObject("winmgmts:\\" & strComputer & _

"\" & strNameSpace & ":" & strClass)


Wscript.Echo strClass & " Methoden"

Wscript.Echo " — — — — — — — — — — — — — -"


For Each objClassMethod In objClass.Methods_

Wscript.Echo objClassMethod.Name

Next

Wenn Sie das Script ausführen, zeigt es die 10 Methoden der Klasse Win32_Service an:

Win32_Service Methoden
- - - - - - - - - - - - - -
StartService
StopService
PauseService
ResumeService
InterrogateService
UserControlService
Create
Change
ChangeStartMode
Delete

Script 6.16 entspricht zum größten Teil den Scripten 6.14 und 6.15 - mit drei Ausnahmen:

  • In der For-Each-Schleife werden die Elemente der Collection SWbemQualifierSet durchlaufen. Die Eigenschaft Name jedes Elementes in der Collection wird ausgegeben.
  • Da die Klassenkennzeichner Teil der Klassendefinition sind und Kennzeichner Werte haben, fragt Script 6.16 auch diese ab.
  • Da Kennzeichner mehrere Werte in einem Array bereitstellen können, muss dies im Script berücksichtigt werden. Über die VBScript-Funktion VarType wird daher der Typ der Variable überprüft.

Script 6.16: Abfragen der Klassenkennzeichner von Win32_Service über SWbemObject.Qualifiers_



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

strComputer = "."

strNameSpace = "root\cimv2"

strClass = "Win32_Service"


Set objClass = GetObject("winmgmts:\\" & strComputer & _

"\" & strNameSpace & ":" & strClass)


Wscript.Echo strClass & " Klassenkennzeichner"

Wscript.Echo " — — — — — — — — — — — — — — — "


For Each objClassQualifier In objClass.Qualifiers_

If VarType(objClassQualifier.Value) = (vbVariant + vbArray) Then

strQualifier = objClassQualifier.Name & " = " & _

Join(objClassQualifier.Value, ",")

Else

strQualifier = objClassQualifier.Name & " = " & _

objClassQualifier.Value

End If

Wscript.Echo strQualifier

strQualifier = ""

Next

Wenn Sie das Script ausführen, werden die Namen und Werte der fünf Klassenkennzeichner der Klasse Win32_Service ausgegeben:

Win32_Service Klassenkennzeichner
- - - - - - - - - - - - - - -
dynamic = True
Locale = 1033
provider = CIMWin32
SupportsUpdate = True
UUID = {8502C4D9-5FBB-11D2-AAC1-006008C78BC7}

Script 6.14 und Script 6.15 zeigen keine Methoden- und Eigenschaftskennzeichner an - die Scripte bleiben so überschaubar.

Verwenden der Methode SWbemObject.GetObjectText_

Es wurde bereits darauf hingewiesen, dass Sie die Klassendefinitionen von verwalten Ressourcen über eine MOF-Datei abfragen können. Wenn Sie zum Beispiel die Klasse Win32_Service abfragen möchten, schlagen Sie in der Datei systemroot\System32\Wbem\Cimwin32.mof nach. Die direkte Verwendung von MOF-Dateien hat jedoch ihren Preis - Sie müssen jede Klasse in der Klassenhierarchie überprüfen, um die komplette Klassendefinition zu erhalten.

Wenn Sie zum Beispiel die Klasse Win32_Service abfragen, dann müssen Sie auch alle fünf Klassen überprüfen, die sich in der Hierarchie über der Klasse Win32_Service befinden. Dies ist sehr mühsam - ein einfacherer Ansatz ist es, die Methode SWbemObject.GetObjectText_ zu verwenden. Script 6.17 demonstriert dies.

Im Gegensatz zu Script 6.14 und Script 6.16 verwendet Script 6.17 die Methode SWbemServices.Get statt die Klasse über GetObject abzufragen. Die Methode Get muss verwendet werden, damit das Flag (der Schalter) wbemFlagUseAmendedQuailifiers aktiviert werden kann. Mit diesem Flag teilen Sie WMI mit, dass es die gesamte Klassendefinition der verwalteten Ressource zurückgeben soll und nicht nur deren lokale Definition. Mit anderen Worte: Die zurückgegebenen Informationen umfassen nicht nur drei Eigenschaften, die direkt in der Klasse definiert werden, sondern auch alle von übergeordneten Klassen gerbten Eigenschaften.

Die Methode Get gibt eine Referenz auf ein SWbemObject-Objekt (objClass) zurück, dass die Zielklasse darstellt, mit der die Methode GetObjectText_ aufgerufen wird. Die Methode GetObjectText_ gibt die MOF-Beschreibung der Klasse zurück. Wenn Sie GetObjectText_ verwenden, ohne das Flag wbemFlagUseAmendedQuailifiers zu aktivieren, erhalten Sie nur die Methoden, Eigenschaften und Kennzeichner, die direkt in der Klasse Win32_Service definiert werden. Die geerbten Eigenschaften und Methoden werden nicht ermittelt.

Script 6.17: Abfragen der MOF-Beschreibung der Klasse Win32_Service über SWbemObject.GetObjectText_



1

2

3

4

5

6

7

8

9

10

11

12

strComputer = "."

strNameSpace = "root\cimv2"

strClass = "Win32_Service"


Const wbemFlagUseAmendedQualifiers = &h20000


Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\" & strNameSpace)

Set objClass = objSWbemServices.Get(strClass, wbemFlagUseAmendedQualifiers)

strMOF = objClass.GetObjectText_


Wscript.Echo strMOF

Die Ausgabe des Scripts sieht so aus:

[dynamic: ToInstance, provider("CIMWin32"): ToInstance, 
Locale(1033): Amended, UUID("{8502C4D9-5FBB-11D2-AAC1-006008C78BC7}"): 
ToInstance, Description("The Win32_Service class represents a 
service on a Win32 computer system. A service application conforms 
to the interface rules of the Service Control Manager (SCM) and 
can be started by a user automatically at system boot through 
the Services control panel utility, or by an application that 
uses the service functions included in the Win32 API. Services 
can execute even when no user is logged on to the system."): 
ToSubClass Amended]
class Win32_Service : Win32_BaseService
{
[Description("The Caption property is a short textual 
description (one-line string) of the object."): ToSubClass 
Amended] string Caption;

Es gibt allerdings einen Vorbehalt gegenüber der Methode GetObjectText**_** : Sie gibt keine Informationen über die geerbten Kennzeichner zurück.

Erkunden des CIM-Repository

Die Erkundung des CIM-Repository ist wahrscheinlich der beste Weg, um mehr über die verfügbaren Klassen und deren Methoden und Eigenschaften zu lernen. Sie haben bereits ein Script kennen gelernt, mit dem Sie das CIM-Repository anzeigen lassen können. Sie sind jedoch nicht auf dieses Script beschränkt. Es gibt einige unterschiedliche Tools, mit denen Sie WMI-Klassen anzeigen lassen können.

WMI-Tester

Der WMI-Tester (Wbemtest.exe) ist ein grafisches Tool das Sie zu Interaktion mit der WMI-Infrastruktur verwenden können. Sie können das CIM-Schema anzeigen lassen und Klassendefinitionen verwalten. Über den WMI-Tester können Sie dieselben Aktionen wie über ein Script ausführen. Da der WMI-Tester ein Teil der WMI-Standardinstallation ist, steht er immer zur Verfügung.

CIM-Studio

CIM-Studio ist Teil des WMI-SDKs. Es stellt eine webbasierte Benutzerschnittstelle zur Interaktion mit der WMI-Infrastruktur zur Verfügung. Mit CIM-Studio haben Sie die gleichen Möglichkeiten wie mit dem WMI-Tester.

Scripte aus dem Resource Kit

Das Microsoft Windows 2000 Server Resource Kit enthält Dutzende von Scripten zur Verwendung von WMI. Mit drei dieser Scripts (EnumClasses.vbs, EnumInstances.vbs und EnumNamespaces.vbs) können Sie ebenfalls das CIM-Schema anzeigen.

Dn151185.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Die WMI-Scripting-Bibliothek

Die WMI-Scripting-Bibliothek stellt einen Satz von Automatisationsobjekten zur Verfügung, über die Scriptsprachen wie VBScript, JScript und ActiveState ActivePerl auf die WMI-Infrastruktur zugreifen können. Die WMI-Scripting-Bibliothek ist über eine einzelne Automatisationskomponente (wbemdisp.dll) implementiert - diese befindet sich im Ordner systemroot\System32\Wbem.

Das Objektmodell der WMI-Scripting-Bibliothek

Die WMI-Scripting-Bibliothek setzt sich aus 19 Automatisationsobjekten zusammen. 16 von diesen Objekten sehen Sie in Abbildung 6.4. Die WMI-Scripting-Bibliothek stellt ein konsistentes und einheitliches Scriptmodell für verwaltete Ressourcen zur Verfügung.

Es ist wichtig, dass Sie die Beziehungen zwischen den Automatisationsobjekten der WMI-Scripting-Bibliothek und den Klassendefintionen der verwalteten Ressourcen im CIM-Repository verstehen.

Über die WMI-Scripting-Bibliothek können Scripte eine Authentifizierung durchführen und eine Verbindung mit WMI aufbauen. So erhalten die Scripte einen Zugriff auf die Instanzen der verwalteten Ressourcen. Das Script kann dann auf die Methoden und Eigenschaften der Ressource zugreifen.

Dn151185.A2337A80C7E7B3AF2989BDBE160B1899(de-de,TechNet.10).png

Abbildung 6.4: Das Objektmodell der WMI-Scripting-Bibliothek

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Die Linien in Abbildung 6.4 zeigen an, dass das entsprechende Objekt über eine Methode oder eine Eigenschaft erstellt oder aufgerufen wird. Wenn Sie zum Beispiel die Methode SWbemLocator.ConnectServer aufrufen, dann gibt diese eine SWbemObjectSet-Collection zurück.

Das Diagramm gibt Ihnen einen guten Überblick über die Arbeitsweise von WMI-Scripten. Die bisherigen Scripte führten zum Beispiel aller drei grundlegenden Aufgaben aus:

  • Jedes Script hat sich zuerst mit dem WMI-Dienst auf dem Zielcomputer verbunden. Hierzu wird die Funktion GetObject mit einem entsprechenden WMI-Verbindungsstring verwendet. Dieser besteht aus dem WMI-Moniker ("winmgmts:") und einem WMI-Objektpfad zum Zielcomputer und den entsprechenden Namespace:
    strComputer = "."
    Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & _
    "\root\cimv2")
    Auf diese Art erhält das Script das in Abbildung 6.4 gezeigt SWbemServices-Objekt zurück. Es kann dann die Methoden des Objekts aufrufen.
  • Jedes Script ruft über die Methode InstancesOf Instanzen von verwalteten Ressourcen ab.
    Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")
    InstancesOf gibt immer eine SWbemObjectSet-Collection zurück. Wie Sie an der Linie zwischen den Objekten SWbemServices und SWbemObjectSet sehen, handelt es sich um eine der drei Objektarten, die SWbemServices zurückgeben kann (die anderen beiden sind SWbemObject und SWbemEventSource).
  • Jedes Script greift auf die Eigenschaften der verwalteten Ressourcen zu, indem es die Instanzen im Objekt SWbemObjectSet durchgeht.
    For Each objSWbemObject In colSWbemObjectSet
    Wscript.Echo "Name: " & objSWbemObject.Name
    Next
    Wie Sie in Abbildung 6.4 sehen, wird jede Instanz einer verwalteten Ressource in einer SWbemObjectSet-Collection durch ein SWbemObject-Objekt repräsentiert. Wenn das SWbemObjectSet-Objekt zum Beispiel aus einer Collection mit allen installierten Diensten besteht, bedeutet das:
  • Jedes Element der Collection ist ein SWbemObject-Objekt (dies gilt für jedes SWbemObjectSet-Objekt).
  • Jedes Objekt in der Collection ist eine Instanz eines installierten Dienstes.

Interpretieren des WMI-Scripting-Bibliothek-Objektmodells

Was können Sie noch vom WMI-Scripting-Bibliothek-Objektmodell lernen? Sie sehen, dass die Objekte SWbemLocator, SWbemSink, SWbemObjectPath, SWbemNamedValueSet und SWbemLastError über die Funktion CreateObject erstellt werden. Andererseits können SWbemServices und SWbemObject über die Funktion GetObject zusammen mit einem WMI-Moniker und einem WMI-Objektpfad erstellt werden.

Das Objektmodell zeigt Ihnen außerdem über den Kreis mit dem S, dass sieben Objekte der WMI-Scripting-Bibliothek ein SWbemSecurity-Objekt zur Verfügung stellen.

Von den 19 Automatisationsobjekten der WMI-Scripting-Bibliothek sind die beiden wichtigsten Objekte SWbemServices und SWbemObject. SWbemServices repräsentiert die authentifizierte Verbindung zu einem WMI-Namespace auf einem Computer und spielt eine wichtige Rolle bei Abfragen und der Verarbeitung von Ereignissen.

Über SWbemObject rufen Sie die Methoden und Eigenschaften der verwalteten Ressource auf.

Die folgende Diskussion betrachtet die Rolle die die primären WMI-Scripting-Bibliothek-Automatisationsobjekte beim WMI-Scripting spielen. Wenn Sie Informationen über die einzelnen Objekte erhalten, nehmen Sie sich einen Moment Zeit und betrachten Sie die Beziehungen des Objekts zu den anderen Objekten im Objektmodell-Diagramm.

Namenskonventionen für Variablen

Die Variablen in den folgenden Beispielscripten, die eine Referenz auf WMI-Automatisationsobjekte speichern, folgen einer Namenskonvention. Die Variable wird nach dem Automatisationsobjekt benannt, auf das sie eine Referenz speichert - außerdem wird ihr der Prefix "obj" vorangestellt (zum zu zeigen, dass es sich um eine Objektreferenz handelt). Eine Variable, die eine Referenz auf ein SWbemServices-Objekt speichert, wird zum Beispiel objSWbemServices genannt. Eine Variable, die eine Referenz auf ein SWbemObject-Objekt speichert, wird objSWbemObject genannt. Eine Variable, die eine Referenz auf eine SWbemObjectSet-Collection speichert, wird colSWbemObjectSet genannt.

Mit dieser Namenskonvention fällt es Ihnen leichter, mit WMI-Objekten zu arbeiten. Ihr Scriptcode wird leichter lesbar und einfacher zu pflegen. Natürlich können Sie auch beliebige Variablennamen verwenden - wenn Ihre Variablen x und y heißen, dann ist das auch in Ordnung. Die beiden folgenden Codestücke arbeiten zum Beispiel vollkommen gleich - sie verwenden nur unterschiedliche Variablennamen:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
strComputer = "."
Set x = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Dn151185.note(de-de,TechNet.10).gifAnmerkung:

In den folgenden Abschnitten werden nicht alle Methoden und Eigenschaften jedes Automatisationsobjekts besprochen. Eine vollständige Übersicht können Sie im WMI-SDK finden. Weitere Informationen hierzu finden Sie unter dem Link Microsoft Windows Management Instrumentation (WMI) SDK unter https://www.microsoft.com/windows/reskits/webresources (englischsprachig).

SWbemLocator

An der Spitze des WMI-Scripting-Bibliothek-Objektmodells steht das Objekt SWbemLocator. Es wird verwendet, um eine authentifizierte Verbindung mit einem WMI-Namespace aufzubauen - so ähnlich, wie die VBScript-Funktion GetObject und der WMI-Moniker "winmgmts:" zum Aufbau einer authentifizierten Verbindung zu WMI dienen. SWbemLocator wurde für zwei bestimmte Scripting-Szenarien entwickelt, die nicht über GetObject und den WMI-Moniker durchgeführt werden können. SWbemLocator wird in den folgenden Fällen benötigt:

  • Wenn Sie sich mit einem anderen Benutzernamen und Passwort mit WMI auf einem Remotecomputer verbinden möchten. Der WMI-Moniker der Funktion GetObject stellt keine Mechanismen zur Angabe von Anmeldeinformationen zur Verfügung. Die meisten WMI-Aktivitäten (inklusive der auf Remotecomputern) erfordern jedoch administrative Rechte.
  • Wenn Sie sich mit WMI verbinden möchten und das WMI-Script in einer Webseite ausführen[NA?]. Wenn Sie Scripte ausführen, die in eine HTML-Seite eingebettet sind, können Sie die Funktion GetObject aus Sicherheitsgründen nicht verwenden.

Außerdem können Sie SWbemLocator verwenden, um eine Verbindung mit WMI aufzubauen, wenn Sie den WMI-Verbindungsstring von GetObject zu kompliziert finden.

Eine Referenz auf SWbemLocator erstellen Sie mit CreateObject statt mit GetObject. Sie müssen der Funktion CreateObject die ProgID von SWbemLocator übergeben ("WbemScripting.SWbemLocator" - wie in Zeile 2 des folgenden Scripts). Nachdem Sie eine Referenz auf das SWbemLocator-Objekt erhalten haben, rufen Sie die Methode ConnectServer auf um sich mit WMI zu verbinden und eine Referenz auf ein SWbemServices-Objekt zu erhalten (Zeile 3 im folgenden Beispielscript):

strComputer = "."
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")
Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")
For Each objSWbemObject In colSWbemObjectSet
    Wscript.Echo "Name: " & objSWbemObject.Name
Next

Die Zeilen 2 und 3 sind identisch mit allen Beispielen zu GetObject, die Sie bereits gesehen haben. ConnectServer ist die einzige Methode, die von SWbemLocator zur Verfügung gestellt wird.

Um ein Script mit alternativen Anmeldeinformationen auszuführen, übergeben Sie ConnectServer den Namen und das Passwort als optionale Parameter. Das folgende Script wird zum Beispiel unter den Anmeldeinformationen des Benutzers kenmyer ausgeführt - sein Passwort ist homerjs.

strComputer = "atl-dc-01"
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer _
    (strComputer, "root\cimv2", "kenmyer", "homerjs")
Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")
For Each objSWbemObject In colSWbemObjectSet
    Wscript.Echo "Name: " & objSWbemObject.Name
Next

Sie können für den Benutzernamen alternativ auch das Format Domäne\Benutzer verwenden:

" fabrikam\kenmyer"

WMI-Scripte, die sich mit dem WMI-Dienst auf dem lokalen Computer verbinden, verwenden immer den Sicherheitskontext des angemeldeten Benutzers. Für diese Scripte können Sie über die Methode SWbemLocator.ConnectServer keinen abweichenden Benutzernamen und ein Passwort angeben.

Sie sollten es vermeiden, Passwörter direkt in ein Script einzutragen. Stattdessen können Sie zum Beispiel die Methoden WScript.StdOut und .StdIn verwenden, um den Scriptbenutzer zur Eingabe des Passworts aufzufordern. Wenn das Script unter Windows XP Professional ausgeführt wird, können Sie die Scripteingabe sogar über das Objekt ScriptPW unkenntlich machen.

Das folgende Script demonstriert die Eingabe eines Passworts. Es verwendet die Methode .StdIn, um das Passwort einzulesen und weist dieses dann der Variable strPassword zu. Da das Script die Methoden StdIn und StdOut verwendet, muss es unter CScript ausgeführt werden:

strComputer = "atl-dc-01"
Wscript.StdOut.Write "Geben Sie das Administrator-Passwort ein: "
strPassword = Wscript.StdIn.ReadLine
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer _
    (strComputer, "root\cimv2", "administrator", strPassword)
Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")
For Each objSWbemObject In colSWbemObjectSet
    Wscript.Echo "Name: " & objSWbemObject.Name
Next

SWbemServices

SWbemServices hat zwei primäre Aufgaben. Erstens stellt das Objekt eine authentifizierte Verbindung zu einem WMI-Namespace auf dem Zielcomputer dar, und zweitens verwenden Sie SWbemServices zur Abfrage von verwalteten Ressourcen. Eine Referenz auf ein SWbemServices-Objekt erhalten Sie über zwei Wege:

  • Wie Sie in den meisten bis jetzt gezeigten Scripten gesehen haben, können Sie die VBScript-Funktion GetObject zusammen mit dem WMI-Moniker "winmgmts:" verwenden. Das folgende Beispiel zeigt die einfachste Form einer WMI-Verbindung. Es verbindet sich mit dem Standard-Namespace (normalerweise root\cimv2) des lokalen Computers:
    Set objSWbemServices = GetObject("winmgmts:")
  • Sie können die Methode ConnectServer eines SWbemLocator-Objekts verwenden. Weitere Informationen hierzu haben Sie im vorhergehenden Abschnitt SWbemLocator erhalten.

Nachdem Sie eine Referenz auf ein SWbemServices-Objekt haben, können Sie einer der 18 Methoden von SWbemServices aufrufen. SWbemServices kann drei unterschiedliche Objekte zurückgeben (SWbemObjectSet, SWbemObject und SWbemEventSource). Sie sollten wissen, welche Methode welches Objekt zurückgibt. Wenn sie zum Beispiel ein Objekt vom Typ SWbemObjectSet zurückerhalten, müssen Sie eine Collection durchgehen, um an die einzelnen SWbemObject-Objekte zu gelangen. Wenn Sie direkt ein SWbemObject-Objekt zurück erhalten, können Sie sofort auf die Methoden und Eigenschaften des Objekts zugreifen.

Die Methoden und die Rückgaben von SWbemServices sehen Sie in Tabelle 6.5.

Tabelle 6.5: Methoden von SWbemServices

Name der Methode

Standardmodus

Rückgabewert

Beschreibung

AssociatorsOf

Semisynchron

SWbemObjectSet

Ruft die Instanzen von den
verwalteten Ressourcen einer
bestimmten Klasse ab. Sie
geben einen Objektpfad an,
und die Methode gibt eine
verwaltete Ressource zurück.

Delete

Synchron (kann nicht geändert werden)

keiner

Löscht eine Instanz einer
verwalteten Ressource
(oder eine Klassendefinition
im CIM-Repository).

ExecMethod

Synchron (kann nicht geändert werden)

SWbemObject

Bietet einen alternativen Weg,
um eine Methode auszuführen,
die über die Klassendefinition
einer verwalteten Ressource
definiert ist. Wird primär in
Situationen verwendet, in
denen eine Scriptsprache
keinen Parameter unterstützt
(zum Beispiel JScript).

ExecNotificationQuery

Semisynchron

SWbemEventSource

Führt eine Ereignisabonnement-
abfrage durch, um Ereignisse
entgegenzunehmen. Eine
Ereignisabonnementabfrage
ist eine Abfrage, die das
Ereignis definiert, das Sie
überwachen möchten.
Wenn das Ereignis auftritt,
übergibt die WMI-Infrastruktur
ein entsprechendes Ereignis
an das Script.

ExecQuery

Semisynchron

SWbemObjectSet

Führt eine Abfrage aus,
die eine Collection mit den
Instanzen einer verwalteten
Ressource zurückgibt
(oder mit Klassendefinitionen).
Kann verwendet werden, um
eine gefilterte Collection mit
Instanzen zu erhalten.

Get

Synchron (kann nicht geändert werden)

SWbemObject

Ruft eine einzelne Instanz
einer verwalteten Ressource
(oder Klassendefinition)
über einen Objektpfad ab.

InstancesOf

Semisynchron

SWbemObjectSet

Ruft alle Instanzen einer
verwalteten Ressource auf
Basis eines Klassennamens
ab. Standardmäßig führt
InstancesOf eine "Tiefenabfrage"
durch - das bedeutet, dass
alle Instanzen der übergebenen
Klasse und alle Instanzen
der Unterklassen der
übergebenen Klasse
zurückgeliefert werden.

ReferencesTo

Semisynchron

SWbemObjectSet

Gibt alle Zuordnungen
zurück, die eine bestimmte
Ressource referenzieren.
Im Gegensatz zu
AssociatorsOf (die
dynamische Ressourcen
zurückgibt), gibt ReferencesTo
die entsprechende Zuordnung
zurück.

SubclassesOf

Semisynchron

SWbemObjectSet

Fragt alle Unterklassen
einer bestimmten Klasse
im CIM-Repository ab.

In Tabelle 6.5 finden Sie nur 9 der 18 Methoden von SWbemServices. Bei den restlichen 9 Methoden handelt es sich um die asynchronen Gegenstücke zu den gezeigten Methoden. Die Namen der Methoden entsprechen den in der Tabelle gezeigten Namen mit einem angehängten Suffix Async. Die asynchrone Version von ExecNotificationQuery heißt also zum Beispiel ExecNotificationQueryAsync.

SWbemServices Betriebsmodi

SWbemServices unterstützt drei Betriebsmodi: synchron, asynchron und semisynchron.

  • Synchron - Im synchronen Modus steht das Script so lange still, bis die Methode SWbemServices ausgeführt wurde. Auch das Script ist betroffen - wenn das WMI Instanzen von verwalteten Ressourcen abfragt, wird die gesamte SWbemObjectSet-Collection im Speicher aufgebaut. Erst dann werden diese Daten an das Script zurückgegeben. Dies kann Auswirkungen auf die Leistung des Scripts und auf den Computer, auf dem das Script ausgeführt wird, haben. Die synchrone Abfrage von Tausenden von Ereignissen kann unter Windows 2000 zum Beispiel sehr lange dauern und eine große Menge an Speicher verbrauchen. Aus diesen Gründen sollten synchrone Methoden nicht ausgeführt werden - eine Ausnahme sind die drei Methoden Delete, ExecMethod und Get. Diese geben keinen großen Datensätze zurück.
  • Asynchron - Im asynchronen Modus wird das Script sofort weiter ausgeführt. Um eine asynchrone Methode zu verwenden, muss Ihr Script erst ein SWbemSink-Objekt und eine spezielle Subroutine (den Event-Handler) erstellen. WMI führt die asynchrone Methode aus und benachrichtigt das Script über die Event-Handler-Subroutine, wenn die Methode beendet ist.
  • Semisynchron - Der semisynchrone Modus ist ein Kompromiss zwischen synchron und asynchron. Er bietet oft eine bessere Leistung als der synchrone Modus, und es sind keine zusätzlichen Schritte notwendig. Daher ist dies der Standardmodus für die meisten WMI-Abfragen.

Im semisynchronen Modus ruft das Script die Methode auf und wird sofort weiter ausgeführt. WMI ruft die verwalteten Ressourcen währenddessen im Hintergrund ab. Nachdem die Ressourcen vollständig abgerufen sind, werden diese über eine SWbemObjectSet-Collection an das Script zurückgegeben. Sie können auf die Ressourcen zugreifen ohne darauf zu warten, dass die gesamte Collection zusammengestellt ist.

Wenn Sie mit verwalteten Ressourcen arbeiten, die viele Instanzen haben (viel heißt in diesem Fall mehr als 1.000), dann gibt es gewisse Vorbehalte gegenüber semisynchronen Methoden. WMI erstellt und speichert für jede Instanz einer Ressource ein SWbemObject-Objekt. Bei vielen Instanzen kann die Leistung des Scripts und des Computers zurückgehen.

Um dieses Problem zu umgehen, können Sie die Aufrufe von semisynchronen Methoden optimieren, indem Sie das Flag wbemFlagForwardOnly verwenden. Mit dem wbemFlagForwardOnly-Flag in Kombination mit dem Flag wbemFlagReturnImmediately teilen Sie WMI mit, dass es eine forward-onlySWbemObjectSet-Collection zurückgeben soll. Dieser Weg hat jedoch seinen Preis. Eine forward-onlySWbemObjectSet-Collection kann nur einmal abgefragt werden. Nachdem auf ein Element der Collection zugegriffen wurde, wird dieses aus dem Speicher entfernt.

Mit Ausnahme der Methoden Delete, ExecMethod, Get und den neun asynchronen Methoden sollten Sie standardmäßig die semisychronen Methoden verwenden.

Verwenden der Methoden von SWbemServices

Zu den häufig verwendeten Methoden zählen InstancesOf, ExecQuery, Get und ExecNotificationQuery. Auch wenn Sie oft verwendet wird, ist InstancesOf nicht der empfohlene Weg, um Informationen abzurufen (auch wenn es wohl der einfachste Weg ist). Warum dies so ist, wird im nächsten Abschnitt besprochen.

InstancesOf

Sie haben die Verwendung der Methode InstancesOf bereits mehrmals in diesem Kapitel gesehen. Weiter oben in diesem Kapitel wurde gesagt, dass es nicht möglich ist, Instanzen von abstrakten Klassen (zum Beispiel CIM_Service) abzufragen. Dies stimmt zwar - das Standardverhalten der Methode InstancesOf könnte jedoch dafür sorgen, dass Sie dies nicht glauben.

Standardmäßig führt InstancesOf eine "Tiefenabfrage" durch. Das bedeutet, dass InstancesOf alle Instanzen einer verwalteten Ressource abfragt deren Klasse Sie angegeben haben und zusätzlich auch alle Instanzen der Unterklassen unter der angegebenen Klasse. Das folgende Script fragt zum Beispiel alle Ressourcen ab, die über die die dynamische Klasse CIM_Service und alle Klasse unter dieser Klasse repräsentiert werden:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.InstancesOf("CIM_Service")
For Each objSWbemObject In colSWbemObjectSet
    Wscript.Echo "Objektpfad: " & objSWbemObject.Path_.Path
Next

Wenn Sie das Script ausführen, erhalten Sie nicht nur die Dienste des Computers zurück, sondern auch alle Unterklassen unter CIM_Service - inklusive Win32_SystemDriver und Win32_ApplicationService.

ExecQuery

Sie die Methode InstancesOf gibt auch ExecQuery immer eine SWbemObjectSet-Collection zurück[???]. Daher muss Ihr Script die von ExecQuery zurückgegebene Collection durchgehen, um auf die einzelnen Instanzen zuzugreifen:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.ExecQuery _
   ("SELECT * FROM Win32_Service")
For Each objSWbemObject In colSWbemObjectSet
    Wscript.Echo "Name: " & objSWbemObject.Name
Next

Die anderen Methoden von SWbemServices, die eine SWbemObjectSet-Collection zurückgeben, sind AssociatorsOf, ReferencesTo und SubclassesOf.

Get

Im Gegensatz zu ExecQuery und InstancesOf gibt Get immer ein SWbemObject-Objekt zurück (dieses stellt eine spezifische Instanz einer verwalteten Ressource oder eine einzelne Klassendefinition dar). Um eine spezifische Instanz über die Get zu erhalten, müssen Sie Get den Objektpfad der Instanz übergeben:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set objSWbemObject = objSWbemServices.Get("Win32_Service.Name='Messenger'")

Wscript.Echo "Name:             " & objSWbemObject.Name        & vbCrLf & _
             "Angezeigter Name: " & objSWbemObject.DisplayName & vbCrLf & _
             "Starttyp:         " & objSWbemObject.StartMode   & vbCrLf & _
             "Status:           " & objSWbemObject.State

SWbemObjectSet

Ein SWbemObjectSet-Objekt ist eine Collection mit SWbemObject-Objekten. Jedes SWbemObject-Objekt in der SWbemObjectSet-Collection kann eine der beiden folgenden Instanzen sein:

  • Eine Instanz einer verwalteten Ressource.
  • Eine Instanz einer Klassendefinition.

Meistens ist das Einzige, was Sie mit einer SWbemObjectSet-Collection machen, das Auflisten der einzelnen Elemente der Collection. SWbemObjectSet jedoch stellt auch eine sehr nützliche Eigenschaft zur Verfügung (Count). Wie der Name schon sagt, gibt Count die Anzahl der Elemente der Collection zurück. Das folgende Script ruft zum Beispiel eine Collection mit allen installierten Diensten ab und gibt dann die Anzahl der gefundenen Dienste aus:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")
Wscript.Echo "Anzahl der installierten Dienste: " & colSWbemObjectSet.Count

Count ist deshalb so nützlich, weil Sie mit dieser Eigenschaft feststellen können, ob eine bestimmte Instanz auf einem Computer vorhanden ist. Das folgende Script ruft zum Beispiel eine Collection mit allen Diensten eines Computers auf, die den Namen W3SVC haben. Wenn Count den Wert 0 zurückgibt, dann heißt das, dass der Dienst auf diesem Computer nicht installiert ist.

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE Name='w3svc'")
If colSWbemObjectSet.Count = 0 Then
    Wscript.Echo "Der Dienst W3SVC ist nicht installiert."
Else
    For Each objSWbemObject In colSWbemObjectSet
        ' Das Script die gewünschten Aktionen durchführen
        ' lassen
    Next
End If

Eine Sache, die Sie bei der Verwendung von Count berücksichtigen sollen, ist das WMI keine 'Strichliste' über die Anzahl der Elemente einer Collection führt. Wenn Sie die Methode Count ausführen, kann WMI nicht sofort mit einer Zahl antworten. Stattdessen muss WMI die Elemente der Collection erst zählen. Bei einer Collection mit eine paar Elementen ist dies Verhalten sicher irrelevant - bei einer Collection mit 1.000 Elementen kann die Zählung jedoch eine ganz Weile dauern.

Dn151185.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Schreiben von WMI-Scripten

Ein Punkt, der bereits mehrmals erwähnt wurde ist, dass die meisten WMI-Scripte nach einem einfachen Muster mit drei Schritten vorgehen:

  1. Sie verbinden sich mit dem WMI-Dienst.
  2. Sie rufen ein WMI-Objekt oder eine Collection von WMI-Objekten ab.
  3. Sie verarbeiten diese Objekte auf irgendeine Art und Weise. Bis jetzt wurden meist Eigenschaften der Objekte ausgegeben. Sie können jedoch auch Eigenschaften ändern, Methoden ausführen und Instanzen erstellen oder löschen.

Damit Sie gute WMI-Scripte schreiben können, müssen Sie die Einzelheiten der drei Schritte verstehen. Der vorherige Abschnitt dieses Kapitels war sehr theoretisch - Sie haben Hintergrundinformationen dazu erhalten, was WMI ist und was man damit machen kann. In diesem Teil des Kapitels wollen wir uns einem mehr praktischen Ansatz zuwenden. Sie erhalten eine detaillierte Übersicht über die drei Schritte.

  1. Die Verwendung des WMI-Monikers wird erklärt - eine vielseitige Methode, um eine Verbindung zum WMI-Dienst aufzubauen.
  2. Die Verwendung von ExecQuery, einer Methode von SWbemServices, die eine Alternative Methode zur Abfrage von WMI-Daten zur Verfügung stellt, wird erklärt.
  3. Sie erhalten Vorlagen, die Sie als Basis für eigene Scripte verwenden können.

Außerdem werden zwei weitere wichtige Elemente von WMI-Scripten besprochen: Die Arbeit mit Daten- und Zeitwerten unter WMI und die Überwachung von Ereignissen.

Eine Verbindung zu WMI über den WMI-Moniker aufbauen

Die WMI-Scripting-Bibliothek stellt zwei Mechanismen zur Verfügung, über die Sie eine Verbindung mit WMI aufbauen können: Das Objekt SWbemLocator und den WMI-Moniker 'winmgmts:'. Diese beiden Mechanismen unterscheiden sich außer durch ihre Syntax dadurch, dass Sie bei SWbemLocator einen Benutzernamen und ein Passwort angeben können und beim WMI-Moniker nicht. Das Objekt SWbemLocator wird im Abschnitt WMI Scripting Library dieses Kapitels genauer besprochen.

Das Prefix 'WinMgmts:'

WMI-Moniker können aus drei Teilen bestehen: Einem verpflichtenden und zwei optionalen Teilen. Die verpflichtende Komponente ist das Prefix 'winmgmts:', mit dem alle WMI-Moniker anfangen müssen:

Set objSWbemServices = GetObject("winmgmts:")

Beim WMI-Moniker wird im Gegensatz zum ADSI-Provider übrigens nicht zwischen Groß- und Kleinschreibung unterschieden.

Ein Moniker, der nur aus dem Prefix 'winmgmts:' besteht, ist die einfachste Form, die Sie verwenden können. Als Ergebnis erhalten Sie eine Referenz auf ein SWbemServices-Objekt, das eine Verbindung zum WMI-Dienst des lokalen Computers darstellt:

  1. Es wird die WMI CLSID aus dem Registrierungsschlüssel HKCR\WINMGMTS\CLSID abgefragt. Die CLSID ({172BDDF8-CEEA-11D1-8B05-00600806D9B6}) ist eine ID, die vom Betriebssystem verwendet wird, um WMI dem entsprechenden COM-Objekt zuzuordnen.
  2. Es wird ein zweiter Wert aus dem Registrierungsschlüssel HKCR\CLSID\{172BDDF8-CEEA-11D1-8B05-00600806D9B6}\InProcServer32 abgefragt. Dieser Wert (normalerweise C:\Windows\System32\wbem\wbemdisp.dll) zeigt den Pfad zu dem COM-Objekt an, dass das Objekt SWbemServices zur Verfügung stellt.
  3. Die DLL Wbemdisp.dll wird geladen. Sie enthält die WMI-Scripting-Bibliothek und stellt das Objekt SWbemServices endgültig zur Verfügung.

Nachdem eine Referenz auf ein SWbemServices-Objekt zur Verfügung steht, können Sie [folgende?]Methoden ausführen:

Set objSWbemServices = GetObject("winmgmts:")
Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_LogicalDisk")

In diesem Beispiel wird eine Referenz-Variable mit dem Namen objSWbemServices mit dem Moniker 'winmgmts:' initialisiert. Diese Variable wird dann zum Aufrufen der Methode InstancesOf des SWbemServices-Objekts verwendet.

Auch wenn das Beispiel nicht sehr lang ist, kann es durchaus noch kürzer werden. Sie können die gleiche Funktionalität zum Beispiel auch über eine Scriptzeile implementieren:

Set colSWbemObjectSet = GetObject("winmgmts:").InstancesOf("Win32_LogicalDisk")

In diesem Beispiel wird keine Variable verwendet (objSWbemServices im vorherigen Beispiel), um die Referenz aufzunehmen. Stattdessen wird die vom Moniker erstellte Referenz auf das SWbemServices-Objekt sofort zum Aufrufen der Methode InstancesOf verwendet.

Beide Beispiele produzieren das gleiche Ergebnis - eine SWbemObjectSet-Collection mit allen Instanzen der Klasse Win32_LogicalDisk des lokalen Computers.

WMI-Sicherheitseinstellungen

Beim zweiten, optionalen Teil des WMI-Monikers handelt es sich um die Sicherheitseinstellungen. Die Sicherheitseinstellungen haben schon zu viel Verwirrung geführt. Dies liegt vor allem an der Einstellung Personifizierung (ImpersonationLevel) - diese verhält sich unter den unterschiedlichen Versionen von WMI verschieden.

Über den Sicherheitsteil können Sie verschiedene Einstellungen angeben:

  • Personifizierungsebene - "winmgmts:{impersonationLevel=Wert}".
  • Authentifizierungsebene - "winmgmts:{authenticationLevel=Wert}".
  • Authentifizierungsautorität - "winmgmts:{authority=NTLMDomäne:Domänenname}" oder "winmgmts:{authority=kerberos:Domänenname\Servername}".
  • Gewährte oder verweigerte Rechte - zum Beispiel "winmgmts:{(Security, !RemoteShutdown)}".

Personifizierungsebene (ImpersonationLevel)

Die ersten beiden Einstellungen (impersonationLevel und authenticationLevel) sind nicht WMI-spezifisch - sie werden von DCOM abgeleitet. WMI verwendet DCOM, um auf die WMI-Infrastruktur von Remotecomputern zuzugreifen. Im Kontext von WMI regelt die Personifizierung, wie weit der WMI-Dienst eines Remotecomputers Aktionen unter Ihrem Benutzerkontext ausführen darf. DCOM unterstützt vier Personifizierungsebenen: Anonymous, Identify, Impersonate und Delegate. Diese vier Ebenen sind in Tabelle 6.6 definiert.

Tabelle 6.6: DCOM-Personifizierungsebenen

Wert

Beschreibung

Anonymous

Verbirgt die Anmeldeinformationen des Aufrufers.
Diese Ebene wird von WMI im Moment nicht
unterstützt. Wenn ein Script die Einstellung
impersonationLevel=Anonymous verwendet,
setzt WMI die Einstellung ohne Hinweis auf Identify.

Identify

Ermöglicht Objekten die Anmeldeinformationen
des Aufrufers abzufragen. Scripte, die diese
Personifizierungsebene verwenden, werden
wahrscheinlich fehlschlagen. Mit der Einstellung
Identify können Sie normalerweise nicht mehr
machen, als ACLs (Zugriffskontrolllisten - Access
Control Lists) zu überprüfen. Sie sind mit Identify
nicht in der Lage, ein Script gegen einen
Remotecomputer auszuführen.

Impersonate

Ermöglicht es Objekten die Anmeldeinformationen
des Aufrufers auszulesen. In WMI-Scripten
sollten Sie diese Personifizierungsebene
verwenden. Mit ihr kann das Script Ihre
Anmeldeinformationen verwenden.

Delegate

Ermöglicht es Objekten, anderen Objekten das
Auslesen der Anmeldeinformationen des
Aufrufers zu gestatten. Mit der Einstellung Delegate
kann ein Script Ihre Anmeldeinformationen auf
einem Remotecomputer verwenden, und der
Remotecomputer kann Ihre Anmeldeinformationen
auf einem weiteren Remotecomputer verwenden.
Diese Einstellung kann ein potentielles
Sicherheitsrisiko darstellen. Wenn die in den Vorgang einbezogenen
Benutzer- und Computerkonten in Active
Directory nicht mit der Einstellung Für
Delegierungszwecke vertrauen konfiguriert sind,
können Sie die Konten nicht verwenden.
Der Vorgang wird in diesem Fall fehlschlagen.

Die Einstellung Anonymous verhindert, wie gesagt, dass Ihre Anmeldeinformationen an ein Remoteobjekt weitergegeben werden. Die Einstellung Identify erlaubt es Remoteobjekten, die Anmeldeinformationen abzufragen. Das Remoteobjekt ist jedoch trotzdem nicht in der Lage, diese Informationen zu verwenden. Scripte, die eine dieser beiden Einstellungen verwenden, schlagen prinzipiell fehl - dies gilt sogar für die meisten Scripte, die auf einem lokalen Computer ausgeführt werden.

Die Einstellung Delegate erlaubt es einem Remote-WMI-Dienst Ihre Anmeldeinformationen an Objekte weiterzugeben - dies ist ein generelles Sicherheitsrisiko.

Das Standardverhalten der Einstellung Personifizierungsebene unterscheidet sich leider zwischen den unterschiedlichen WMI-Versionen. Die Versionen vor 1.5 verwenden als Standardeinstellung Identify. Seit Version 1.5 (mit Windows 2000 veröffentlicht) wurde die Standardeinstellung auf Impersonate geändert. Die Standardeinstellung wird über den folgenden Registrierungsschlüssel definiert:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\Scripting\Default Impersonation Level

Wenn Ihre WMI-Scripte nur mit Computern mit WMI-Version 1.5 oder höher arbeiten, brauchen Sie sich um die Einstellung ImpersonationLevel nicht kümmern. Um auch ältere Versionen zu unterstützen und um Fehler zu vermeiden, sollten Sie jedoch trotzdem in jedem Script die Einstellung impersonationLevel explizit angeben.

Authentifizierungsebene (AuthenticationLevel)

Diese Einstellung ermöglicht es Ihnen, die DCOM-Authentifizierung und -Sicherheit für eine bestimmte Verbindung anzugeben. Die Einstellungen reichen von keiner Authentifizierung bis zu einer verschlüsselten Authentifizierung pro Paket. Die sieben möglichen Einstellungen (Default, None, Connect, Call, Pkt, PktIntegrity und PktPrivacy) werden in Tabelle 6.7 beschrieben. Die Angabe der Einstellung Authentifizierungsebene sollten Sie mehr als Anfrage statt als Anweisung betrachten. Es gibt keine Garantie dafür, dass die angeforderte Authentifizierung auch tatsächlich verwendet wird.

Tabelle 6.7: DCOM-Authentifizierungsebene

Wert

Beschreibung

None

Keine Authentifizierung.

Default

Verwendet eine Standardsicherheitsaushandlung,
um die Authentifizierungsebene festzulegen.
Dies ist die empfohlene Einstellung.

Connect

Führt eine Authentifizierung nur dann durch,
wenn der Client versucht sich mit einem
Server zu verbinden. Nachdem die Verbindung
aufgebaut wurde, wird keine weitere Authentifizierung
mehr durchgeführt.

Call

Authentifiziert den Client nur bei Beginn eines
jeden Aufrufs. Die Paketheader werden signiert.
Die Datenpakete sind jedoch weder signiert
noch verschlüsselt.

Pkt

Authentifiziert alle Datenpakete. Wie bei Call
werden alle Header signiert, jedoch nicht verschlüsselt.
Die Pakete selbst werden weder signiert noch
verschlüsselt.

PktIntegrity

Authentifiziert alle Datenpakete.
Jedes Datenpaket ist signiert.
Kein Paket wird verschlüsselt.

PktPrivacy

Führt alle Authentifizierungen der anderen
Stufen durch und verschlüsselt alle Datenpakete.

Autorität (Authority)

Diese Einstellung erlaubt es Ihnen, das Sicherheitsverfahren zur Authentifizierung der WMI-Verbindung anzugeben. Sie können die NTLM- oder die Kerberos-Authentifizierung verwenden. Für NTLM verwenden Sie die Einstellung authority=NTLMDomäne:Domänenname, wobei Domänenname ein gültiger NTLM-Domänenname sein muss. Um Kerberos zu verwenden, geben Sie die Einstellung authority=kerberos:Domänenname\Servername an.

Berechtigungen

Als letzte Einstellung können Sie Berechtigungen angeben. Diese Einstellung ermöglicht es Ihnen, Recht zu gewähren oder zu verweigern. Zum Beispiel könnten Sie sich selbst das Recht Security zuweisen, um unter Windows NT/2000 das Sicherheitsprotokoll abzufragen. Einige der möglichen Rechte sehen Sie in Tabelle 6.8.

Tabelle 6.8: Berechtigungen

Recht

Beschreibung

MachineAccount

Erforderlich, um ein Computerkonto zu erstellen.

Security

Erforderlich, um einige sicherheitsbezogene
Funktionen auszuführen (zum Beispiel das
Anzeigen von Überwachungsnachrichten).

TakeOwnership

Erforderlich, um den Besitz an einem
Objekt zu übernehmen.

LoadDriver

Erforderlich, um Gerätetreiber zu laden
und zu entladen.

SystemProfile

Erforderlich, um das Systemprofil
abzufragen.

SystemTime

Erforderlich, um die Systemzeit zu ändern.

ProfileSingleProcess

Erforderlich, um Informationen über
einen Prozess abzufragen.

IncreaseBasePriority

Erforderlich, um die Basispriorität
eines Prozesses zu erhöhen.

CreatePagefile

Erforderlich, um eine Auslagerungsdatei
zu erstellen.

Backup

Erforderlich, um Sicherungsoperationen
durchzuführen.

Restore

Erforderlich, um Wiederherstellungen
durchzuführen.

Shutdown

Erforderlich, um den lokalen
Computer herunterzufahren.

Audit

Erforderlich, um Einträge im
Überwachungsprotokoll zu generieren.

RemoteShutdown

Erforderlich, um einen Computer
über das Netzwerk herunterzufahren.

Undock

Erforderlich, um aus der
Dockingstation zu entfernen.

SyncAgent

Erforderlich, zur Synchronisierung
von Verzeichnisdienstdaten.

Wenn Sie ein Recht verweigern möchten, können Sie dies tun, indem Sie dem Recht ein Ausrufezeichen (!) voranstellen.

Der folgende Moniker gewährt zum Beispiel das Recht LockMemory und verweigert das Recht IncreaseQuota:

Set objSWbemServices = GetObject _
("winmgmts:{impersonationLevel=impersonate,(LockMemory, !IncreaseQuota)}")

Wenn Sie in einem Script Rechte gewähren, werden diese nicht auf den Benutzer übertragen. Nehmen wir zum Beispiel an, Sie führen ein Script aus, das das Recht Shutdown gewährt. Wenn Sie nicht bereits über das Recht verfügen, können Sie auch über ein Script dieses Recht nicht wahrnehmen. Um ein Recht wahrnehmen zu können, müssen zwei Bedingungen erfüllt sein:

  • Das Script muss das Recht im Verbindungsstring gewähren.
  • Sie müssen bereits über das Recht verfügen.

Moniker mit Sicherheitseinstellungen

Das Format für Moniker mit Sicherheitseinstellungen sieht folgendermaßen aus:

Set objSWbemServices = GetObject("winmgmts:"                  & _
                                 "{SecuritySetting1=Wert,"    & _
                                 "SecuritySetting2=Wert,"     & _
                                 "(Recht1,!Recht2)}")

Verwenden von WMI-Objektpfaden

Bei der dritten Komponente des WMI-Monikers handelt es sich um den WMI-Objektpfad. Für die Sicherheitseinstellungen ist diese Komponente optional. Mit WMI-Objektpfaden können Sie eine oder mehrere der folgenden Zielressourcen eindeutig identifizieren:

  • Remotecomputer - Wenn der Computer im Objektpfad nicht angegeben wird, dann wird das Script gegen den lokalen Computer ausgeführt:
    Set objSWbemServices = GetObject("winmgmts:")

    Der folgenden Moniker verbindet sich mit dem WMI-Dienst des Remotecomputers atl-dc-01:
    Set objSWbemServices = GetObject("winmgmts:\\atl-dc-01")

    Computernamen werden normalerweise über den NetBIOS-Namen des Computers angegeben. DNS-Namen und IP-Adressen sind jedoch ebenfalls möglich (zum Beispiel atl-dc-01.fabrikam.com oder 192.168.1.1).

  • WMI-Namespace - Wenn der Namespace nicht angegeben wird, dann wird der Standard-Namespace verwendet. Der folgende Moniker verbindet sich mit dem Standard-Namespace auf dem Remotecomputer atl-dc-01:
    Set objSWbemServices = GetObject("winmgmts:\\atl-dc-01")

    Dieser Moniker verbindet sich mit dem Namespace root\default auf dem Computer atl-dc-01:
    Set objSWbemServices = GetObject("winmgmts:\\atl-dc-01\root\default")

  • Eine WMI-Klasse in einem Namespace - Wenn in einem Moniker eine Klasse angegeben wird, muss dieser von Computername und Namespace durch einen Doppelpunkt getrennt werden. Der folgende Moniker verbindet sich zum Beispiel mit der Klasse Win32_OperatingSystem:
    Set objSWbemObject = GetObject _
    ("winmgmts:\\atl-dc-01\root\cimv2:Win32_OperatingSystem")

  • Eine Spezifische Instanz oder Instanzen einer WMI-Klasse in einem Namespace - Der folgende Moniker verbindet sich direkt mit der WMI-Instanz von Laufwerk C:
    Set objSWbemObject = GetObject _
    ("winmgmts:\\atl-dc-01\root\cimv2:Win32_LogicalDisk.DeviceID='C:'")

Format von Objektpfaden

In einem Objektpfad werden Computername und WMI-Namespace durch die Zeichen Slash oder Backslash getrennt. Gültige Objektpfade sind zum Beispiel:

\\WebServer\root\cimv2
//WebServer/root/cimv2
Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Sie können die beiden Formen sogar mischen. Dies wird jedoch nicht empfohlen, da Ihr Scriptcode so schwerer lesbar wird. Trotzdem wäre der folgende Objektpfad gültig: \\Webserver/root/cimv2.

Wenn im Objektpfad eine WMI-Klasse angegeben wird, dann muss die Klasse vom Namespace durch einen Doppelpunkt getrennt werden:

\\WebServer\root\cimv2:Win32_Printer

Um eine direkte Instanz einer Klasse (zum Beispiel einen bestimmten Dienst) anzugeben, müssen Sie den Klassennamen und durch einen Punkt (.) getrennt die Schlüsseleigenschaft angeben. Dann folgt der Wert dieser Eigenschaft der gesuchten Instanz:

\\WebServer\root\cimv2:Win32_Service.Name="Alerter"

Schlüsseleigenschaften

Die Schlüsseleigenschaft ist eine Eigenschaft, die zur eindeutigen Identifizierung einer Instanz verwendet werden kann. Die Schlüsseleigenschaft der Klasse Win32_Service ist zum Beispiel die Eigenschaft Name - und zwar darum, weil jeder Dienst einen eindeutigen Namen hat. Die Eigenschaft StartMode ist hingegen keine Schlüsseleigenschaft - der Starttyp kann bei vielen Diensten gleich sein. Der folgende Verbindungsstring schlägt daher fehl:

Set colServices = GetObject _
("winmgmts:\\.\root\cimv2\Win32_Service.StartMode='Auto'")

Wenn Sie versuchen dieses Script auszuführen, erhalten Sie die Fehlermeldung 'Ungültiger Syntax':

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Was ist, wenn Sie eine Liste der Dienste mit dem Starttyp Automatisch benötigen? Dies können Sie über die Methode ExecQuery durchführen. Die Methode wird weiter unten in diesem Kapitel im Abschnitt Abfragen von verwalteten Ressourcen über die WMI-Abfragesprache besprochen.

Klassen haben normalerweise nur eine Schlüsseleigenschaft - auch wenn es ein paar Ausnahmen gibt. Die Klasse Win32_NTLogEvent hat zum Beispiel zwei Schlüsseleigenschaften: Logfile und RecordNumber. Dies liegt daran, dass RecordNumber einen Eintrag in einem Ereignisprotokoll nicht eindeutig identifiziert. Es kann in den unterschiedlichen Protokollen Einträge mit den gleichen Nummern geben. Wenn Sie einen solchen Eintrag aufrufen wollen, müssen Sie daher beide Schlüsseleigenschaften angeben:

\\WebServer\root\cimv2:Win32_NTLogEvent.Logfile='Application',RecordNumber=555

Abfragen von verwalteten Ressourcen über die WMI-Abfragesprache

Über WMI-Abfragen können Sie Daten oder Ereignisse nach vordefinierten Kriterien abrufen. Eine WMI-Abfrage kann zum Beispiel alle Dienste mit dem Starttyp Automatisch, die im Moment angehalten sind, zurückgeben. Eine WMI-Ereignisabfrage können Sie verwenden, um zum Beispiel beim Anhalten und Starten von Diensten benachrichtigt zu werden. Da der WMI-Abfrageprozessor ein Teil des WMI-Dienstes ist, können Sie WMI auf alle Daten des CIM abfragen.

WMI-Abfragen sind ein effizienterer Mechanismus zum Abfragen von Objektinstanzen als die Methode InstancesOf. WMI-Abfragen geben nur die Instanzen und Daten zurück, die der Abfrage entsprechen. InstancesOf gibt hingegen alle Objektinstanzen einer Klasse zurück. Abfragen werden außerdem auf dem Zielcomputer im Objektpfad ausgeführt statt auf dem Computer, auf dem das Script gestartet wurde. Daher verringern WMI-Abfragen den Netzwerkverkehr.

Um WMI-Abfragen durchzuführen, erstellt der Administrator einen Abfragestring mit der WMI-Abfragesprache (WMI Query Language - WQL). Der Abfragestring definiert die Kriterien der zurückzugebenden Instanzen und Daten. Der Abfragestring wird dann über eine von mehreren Methoden des SWbemServices-Objekts an WMI übergeben. Das Script erhält die Ergebnisse der Abfrage über eine SWbemObjectSet-Collection zurück.

WQL ist eine Untermenge von ANSI-SQL (Structured Query Language). SQL wird normalerweise in Datenbanken verwendet. Der Hauptzweck von WQL ist das Abfragen von Informationen. SQL-Funktionen wie UPDATE und DELETE werden von WQL nicht unterstützt. Außerdem können Sie mit WQL keine Sortierreihenfolge angeben.

Mit WQL und der Methode ExecQuery können Sie viel flexiblere Scripte als mit InstancesOf schreiben. Sie erhalten nur die Elemente, die für Sie interessant sind. Sie können zum Beispiel eine grundlegende WQL-Abfrage verwenden, um allen Eigenschaften aller Instanzen einer bestimmten Klasse abzufragen - diese Informationen würden Sie jedoch auch über die Methode InstancesOf erhalten. Mit WQL können Sie jedoch deutlich mehr machen. Zum Beispiel:

  • Abfragen von ausgewählten Eigenschaften für alle Instanzen einer Klasse.
  • Abfragen von allen Eigenschaften für ausgewählte Instanzen einer Klasse.
  • Abfragen von ausgewählten Eigenschaften für ausgewählte Instanzen einer Klasse.

Solche zielgerichteten Abfragen beschleunigen die Geschwindigkeit von Abfragen in einigen Situationen deutlich - auch die Arbeit mit den zurückgegebenen Daten wird einfacher. Zielgerichtete Anfragen können außerdem die zurückgegebenen Daten deutlich einschränken. Bei Scripten, die über das Netzwerk ausgeführt werden, ist dies unter umständen sehr wichtig.

In Tabelle 6.9 sehen Sie einige Werte für unterschiedliche Abfragetypen. Wie Sie sehen, ist die zurückgegebene Datenmenge teilweise sehr unterschiedlich.

Tabelle 6.9: Vergleich von WMI-Abfragen

Abfrage

Bytes zurückgegeben

objSWbemServices.Instances
Of("Win32_Service")

157.398

objSWbemServices.ExecQuery
("SELECT * FROM Win32_Service")

156.222

objSWbemServices.ExecQuery
("SELECT Name FROM Win32_Service")

86.294

objSWbemServices.ExecQuery
("SELECT StartMode FROM Win32_Service")

88.116

objSWbemServices.ExecQuery _
("SELECT StartMode FROM Win32_
Service WHERE State='Running'")

52.546

objSWbemServices.ExecQuery _
("SELECT StartMode, State FROM Win32_
Service WHERE State='Running'")

56.314

objSWbemServices.ExecQuery _
("SELECT * FROM Win32_Service
WHERE Name='WinMgmt'")

27.852

objSWbemServices.Get("Win32_
Service.Name='WinMgmt'")

14.860

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Das bedeutet nicht notwendigerweise, dass die Abfragen mit den wenigsten Daten die beste Lösung darstellen. Sie geben einfach nicht alle Eigenschaften zurück. Wenn Sie alle Eigenschaften benötigen, bleibt Ihnen nichts anderes übrig, als eine andere Abfrage zu verwenden.

Abfragen aller Eigenschaften aller Instanzen einer Klasse

Die einfachste WQL-Abfrage ist die, die alle Eigenschaften einer Instanz einer Klasse abfragt. Hierzu gehen Sie folgendermaßen vor:

  • Sie verwenden einen Stern (*), um anzuzeigen, dass Sie alle Eigenschaften abfragen wollen.
  • Sie geben den Namen der Klasse an.

Diese Abfrage gibt zum Beispiel alle Eigenschaften aller installierten Dienste zurück:

"SELECT * FROM Win32_Service"

Der Vorteil einer SELECT * Abfrage ist, dass dieses Verfahren schnell und einfach ist. Der Nachteil ist, dass Sie möglicherweise viel mehr Informationen zurückerhalten, als Sie benötigen. Eine Abfrage, die zum Beispiel alle Eigenschaften aller installierten Laufwerke zurückgibt, produziert ca. 808 Byte an Daten. Eine Abfrage, die nur die Eigenschaft Name zurückgibt, produziert nur 145 Byte an Daten. Die Abfrage SELECT * wird in weniger als zwei Sekunden ausgeführt. Die Abfrage SELECT Name benötigt jedoch nur weniger als eine Sekunde. Möglicherweise finden Sie den Unterschied zwischen den beiden Scripten unbedeutend.

In anderen Fällen kann der Unterschied jedoch dramatisch sein. Ein Script, das alle Eigenschaften aller auf einem Computer ausgeführten Threads anzeigt, benötigt hierzu ca. 7 Sekunden und gibt 105 KB Daten zurück. Ein Script, das nur das Thread-Handle zurückgibt, benötigt nur eine Sekunde und gibt nur 6 KB Daten zurück.

Script 6.18 verwendet eine Standard-WQL-Abfrage, die alle Eigenschaften aller installierten Dienste zurückgibt.

Script 6.18: Abfragen aller Eigenschaften aller Instanzen einer Klasse



1

2

3

4

5

6

7

8

9

10

strComputer = "."

Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\root\cimv2")


Set colServices = _

objSWbemServices.ExecQuery("SELECT * FROM Win32_Service")


For Each objService In colServices

Wscript.Echo objService.Name

Next

Abfragen ausgewählter Eigenschaften aller Instanzen einer Klasse

Wie Sie bereits wissen, wird ein Script schneller ausgeführt und gibt weniger überflüssige Daten zurück, wenn Sie nur bestimmte Eigenschaften einer Klasse abfragen. Hierzu ersetzen Sie in der Abfrage den Stern durch die Namen der zurückgegebenen Eigenschaften. Die folgende Abfrage gibt nur die Eigenschaft Name aller Instanzen der Klasse Win32_Service zurück:

"SELECT Name FROM Win32_Service"

Wenn Sie mehrere Eigenschaften zurückgeben möchten, dann trennen Sie die Eigenschaftsnamen durch Kommata. Die folgende Abfrage gibt zum Beispiel die Eigenschaften Name und State der Klasse Win32_Service zurück:

"SELECT Name, State FROM Win32_Service"

Was bedeutete es, nur ausgewählte Eigenschaften zurückzugeben? Sehen Sie sich das folgende Script an. Es ruft nur die Eigenschaft Name der Klasse Win32_Service ab, versucht jedoch auch die State auszugeben:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
("SELECT Name FROM Win32_Service")

For Each objService In colServices
    Wscript.Echo objService.Name, objService.State
Next

Wenn Sie das Script unter CScript ausführen, erhalten sie die folgende Fehlermeldung:

Laufzeitfehler in Microsoft VBScript: Das Objekt unterstützt diese Eigenschaft oder Methode nicht:
'objService.State'

Warum diese Fehlermeldung? State ist zwar eine gültige Eigenschaft der Klasse Win32_Service, Sie haben Sie jedoch nicht abgefragt. Daher ist die Eigenschaft State in der Collection nicht vorhanden. Da das Script die zurückgegebene Collection und nicht die Klasse selbst abfragt, kommt es zu dem Fehler.

Es gibt eine Ausnahme: Die Schlüsseleigenschaft wird immer zurückgegeben - auch dann, wenn Sie in der WQL-Abfrage nicht angegeben wurde. Name ist zum Beispiel die Schlüsseleigenschaft der Klasse Win32_Service. Das folgende Script fragt nur die Eigenschaft State ab. Bei der Ausgabe kann es jedoch auch die Eigenschaft Name verwenden:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
("SELECT State FROM Win32_Service")

For Each objService In colServices
    Wscript.Echo objService.Name, objService.State
Next

Wenn Sie das Script unter Cscript ausführen, schlägt es nicht fehl. Stattdessen erhalten Sie die folgende Ausgabe:

Alerter Stopped
ALG Stopped
AppMgmt Stopped
Ati HotKey Poller Stopped
AudioSrv Running
BITS Running

Abfragen aller Eigenschaften für ausgewählten Instanzen einer Klasse

Die beiden bisherigen WQL-Abfragen haben Informationen für jede Instanz einer bestimmten Klasse zurückgegeben. Oft benötigen Sie jedoch nur eine Untermenge der Instanzen - zum Beispiel, wenn Sie nur Informationen über die Dienste erhalten möchten, die angehalten wurden oder nur über Festplatten (nicht über Diskettenlaufwerke oder CD-Rom-Laufwerke). In solchen Situationen ist eine Rückgabeliste mit allen Instanzen kontraproduktiv. Sie müssen die Liste erst nach den gewünschten Instanzen durchsuchen.

In anderen Fällen kann die Beschränkung auf einzelne Instanzen einer Klasse einen deutlichen Zeitunterschied ausmachen. Stellen Sie sich vor, Sie möchten ein Ereignisprotokoll mit ca. 48.000 Einträgen abfragen. Ein Script, das nur 4.000 Einträge abfragt, würde schon ca. 18 Sekunden benötigen. Und wie lange braucht das Script für die gesamten 48.000 Einträge? Das weiß leider keiner - nach 41.592 Einträgen ist das Script wegen Speichermangel abgestürzt.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Auch wenn es schon schlimm genug ist, dass das Script abstürzt - es kommt noch schlimmer. Auch wenn das Script abgestürzt ist, führt WMI die Abfrage weiter aus. Somit kommt das ganze System zum Stillstand. Der einzige Weg, dies zu beenden, wäre ein Neustart des WMI-Dienstes.

Sie sehen also: In diesem Fall ist der Unterschied tatsächlich dramatisch. Ein Script, das nur die Instanzen mit dem Ereigniscode 532 zurückgibt, ist in wenigen Sekunden beendet.

Um eine solche Abfrage zu erstellen, benötigen Sie eine WHERE-Bedingung:

"SELECT * FROM Klassename WHERE Eigenschaftsname = Eigenschaftswert"
Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Dieser Beschreibung ist nicht vollkommen richtig. Außer dem Gleichzeichen (=) können Sie auch noch andere Operatoren verwenden - zum Beispiel kleiner (), größer () und ungleich ().

Die folgende Abfrage gibt zum Beispiel nur die Einträge zurück, die im Systemprotokoll aufgezeichnet wurden:

"SELECT * FROM Win32_NTLogEvent WHERE Logfile = 'System'"

Die Abfrage setzt sich folgendermaßen zusammen:

  • Win32_NTLogEvent ist die abzufragende WMI-Klasse.
  • Logfile ist die Eigenschaft.
  • System ist der gesuchte Wert der Eigenschaft Logfile. Nur die Ereignisse, bei denen die Eigenschaft Logfile den Wert System hat, werden zurückgeben.

Wenn Sie Abfragen mit einer WHERE-Bedingung schreiben, müssen Sie darauf achten, den Wert richtig zu formatieren. Das verwendete Format hängt von der abgefragten Eigenschaft ab (String, Zahl, Boolean-Wert, usw.).

Verwenden von Strings in WHERE-Bedingungen

Vielleicht ist Ihnen aufgefallen, dass der Wert (System) in der vorhergehenden Abfrage in Hochkommata eingeschlossen war. Dies ist immer dann erforderlich, wenn der Wert für die WHERE-Bedingung ein String ist. Das folgende Script gibt zum Beispiel die Namen aller Dienste zurück, die angehalten sind:

  • Win32_Service ist die WMI-Klasse, die abgefragt wird.
  • State ist die Eigenschaft.
  • Stopped ist der gesuchte Wert der Eigenschaft. Da es sich um einen String handelt muss dieser in Hochkommata eingeschlossen werden:
strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE State = 'Stopped'")

For Each objService In colServices
    Wscript.Echo objService.Name
Next

Verwenden von Zahlen- und Boolean-Werten in WHERE-Bedingungen

Wenn Sie Zahlen oder Boolean-Werte (True oder False) verwenden, dann müssen diese nicht in Hochkommata eingeschlossen werden. Das folgende Script fragt zum Beispiel alle Dienste ab, die angehalten werden können:

  • Win32_Service ist die abgefragte WMI-Klasse.
  • AcceptPause ist die Eigenschaft.
  • True ist der gesuchte Wert der Eigenschaft.
strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE AcceptPause = True")

For Each objService In colServices
    Wscript.Echo objService.Name
Next

Verwenden von Variablen in einer WHERE-Bedingung

Statt ein Script zu schreiben, das immer die gleichen Informationen abfragt, können Sie das Script so verändern, dass Sie die gesuchten Informationen über Kommandozeilenargumente angeben können.

Hierzu müssen Sie den gesuchten Wert in einer Variablen speichern und diese dann in der WQL-Abfrage verwenden. Nehmen wir einmal an, die gewünschte Abfrage soll so aussehen:

SELECT * FROM Win32_Service WHERE State = 'Stopped'"

Diese Abfrage können wir nun verändern. Statt den String direkt in die Abfrage einzutragen, können Sie diesen auch in einer Variablen speichern.

strState = "Stopped"

Diese variable können Sie nun in der Abfrage verwenden:

"SELECT * FROM Win32_Service WHERE State ='" & strState & "'"

Wie Sie wissen, können Sie Strings mit dem kaufmännischen Und verketten. Die gilt natürlich auch für eine Mischung aus Strings und Variablen, die Strings enthalten.

Wenn Sie das nächste Script unter dem Namen ServiceState.vbs speichern, können Sie es mit der folgenden Befehlszeile aufrufen:

cscript servicestate.vbs running

strState = Wscript.Arguments.Item(0)

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE State = '" & strState & "'")

For Each objService In colServices
    Wscript.Echo objService.Name
Next

Im Script wird die Zeile mit der WQL-Abfrage dann zu folgender Abfrage aufgelöst:

    ("SELECT * FROM Win32_Service WHERE State = 'running'")

Das Script liefert so alle im Moment ausgeführten Dienste zurück.

Zielgerichtete Abfragen über AND oder OR erstellen

Mit den Schlüsselwörtern AND und OR können Sie komplexere Abfragen erstellen.

Mit dem Schlüsselwort AND können Sie den Bereich einer Abfrage einschränken. Nehmen wir zum Beispiel einmal an, Sie möchten eine Liste der Dienste mit dem Starttyp Automatisch, die angehalten sind, abfragen. Hierzu sind in der WHERE-Bedingung zwei Parameter notwendig - die Eigenschaft State, die den Wert Stopped haben muss und die Eigenschaft StartMode, die den Wert Auto haben muss. Die beiden Parameter müssen Sie mit dem Schlüsselwort AND verknüpfen:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
  ("SELECT * FROM Win32_Service WHERE State = 'Stopped' AND StartMode = 'Auto'")

For Each objService In colServices
    Wscript.Echo objService.Name
Next

Mit dem Schlüsselwort OR können Sie hingegen den Abfragebereich erweitern. Nehmen wir an, Sie benötigen alle Dienste, die den Status stopped oder paused haben. In diesem Fall verwenden Sie das Schlüsselwort OR.

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_Service WHERE State = 'Stopped' OR State = 'Paused'")

For Each objService In colServices
    Wscript.Echo objService.Name
Next

Ausgewählte Eigenschaften für ausgewählte Instanzen einer Klasse zurückgeben

Sie haben die Möglichkeit, nur ausgewählte Eigenschaften für ausgewählte Klassen zurückzugeben. Hierzu gehen Sie folgendermaßen vor:

  • Geben Sie die zurückzugebenden Eigenschaften an.
  • Schränken Sie die zurückgegebenen Instanzen über eine WHERE-Bedingung ein.

Eine solche Abfrage ist sozusagen eine Kombination aus zwei Abfragen. Das folgende Script gibt nur die Eigenschaften Name und State der Dienste zurück, die angehalten werden können:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
strComputer & "\root\cimv2")

Set colServices = objSWbemServices.ExecQuery _
    ("SELECT Name, State FROM Win32_Service WHERE AcceptPause = True")

For Each objService In colServices
    Wscript.Echo objService.Name, objService.State
Next

Schnellere Abfragen über Forward-only erzeugen

In einigen Fällen können Sie eine Abfrage über die Option Forward-Only beschleunigen. Unter Windows 2000 benötigt ein Script zur Abfrage von 10.000 Ereignissen zum Beispiel 47 Sekunden. Mit der Option Forward-Only sind es nur noch 28 Sekunden. Die Differenz von 19 Sekunden scheint nicht sehr groß zu sein, aber wenn Sie das Script auf allen 50 Domänencontrollern ausführen, sieht die Sache ganz anders aus.

Für die Forward-Only-Auflistung von Elementen müssen Sie der Methode ExecQuery drei Parameter angeben. Der erste Parameter ist die WQL-Abfrage. Der zweite Parameter gibt die Abfragesprache an - sie sollten Ihn entweder nicht definieren oder hier 'WQL' angeben. Der dritte Parameter ist der Wert 48. Er steht für zwei Flags (Schalter):

  • wbemFlagReturnImmediately (Dezimalwert 16) - Dieser Schalter sorgt dafür, dass ExecQuery semisynchron ausgeführt wird.
  • wbemFlagForwardOnly (Dezimalwert 32) - Dieser Schalter sorgt dafür, dass eine Forward-Only-Collection zurückgeben wird.

Eine Forward-Only-Auflistung wird normalerweise schneller als eine normale Abfrage ausgeführt - außerdem benötigt sie weniger Speicher. Wie Sie wissen, wird jedoch jedes Element einer solchen Collection nach der ersten Abfrage aus dem Speicher entfernt. Sie können also nicht zweimal auf ein Element zugreifen.

Das folgende Script verwendet das Forward-Only-Flag und gibt Ereignisse aus dem Ereignisprotokoll zurück:

Const wbemFlagReturnImmediately = 16
Const wbemFlagForwardOnly = 32

strComputer = "."
Set objSWbemServices = _
    GetObject("winmgmts:{(Security)}\\" & strComputer & "\root\cimv2")

Set colNTLogEvents = objSWbemServices.ExecQuery _
    ("SELECT * FROM Win32_NTLogEvent", , _
     wbemFlagReturnImmediately + wbemFlagForwardOnly)

For Each objNTLogEvent In colNTLogEvents
    Wscript.Echo "LogFile:        " & objNTLogEvent.LogFile        & _
vbCrLf & _
                 "RecordNumber:   " & objNTLogEvent.RecordNumber   & _
vbCrLf & _
                 "Type:            " & objNTLogEvent.Type           & _
vbCrLf & _
                 "TimeGenerated:  " & objNTLogEvent.TimeGenerated  & _
vbCrLf & _
                 "Source:          " & objNTLogEvent.SourceName     & _
vbCrLf & _
                 "Category:        " & objNTLogEvent.Category       & _
vbCrLf & _
                 "CategoryString: " & objNTLogEvent.CategoryString & _
vbCrLf & _
                 "Event:           " & objNTLogEvent.EventCode      & _
vbCrLf & _
                 "User:            " & objNTLogEvent.User           & _
vbCrLf & _
                 "Computer:        " & objNTLogEvent.ComputerName   & _
vbCrLf & _
                 "Message:         " & objNTLogEvent.Message        & _
vbCrLf
Next

Wenn Sie das Forward-Only-Flag verwenden, können Sie die Methode SWbemObjectSet.Count nicht mehr verwenden. Die Methode Count zählt die Elemente einer Collection, indem es sie einzeln durchgeht. Hierbei werden die Elemente einer Forward-Only-Collection natürlich alle aus dem Speicher entfernt.

Arbeiten mit Datum- und Zeitwerten

Die Handhabung von Daten und Zeiten durch WMI ist etwas verwirrend. Das folgende einfache Script gibt zum Beispiel das Installationsdatum des Betriebssystems zurück:

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
strComputer & "\root\cimv2")
Set colOS = objSWbemServices.ExecQuery _
("SELECT * FROM Win32_OperatingSystem")
For Each objOS in colOS
    Wscript.Echo objOS.InstallDate
Next

Wenn Sie das Script unter CScript ausführen, erhalten Sie die folgende Ausgabe:

20011224113047.000000+60

Das ist kein Fehler - die Ausgabe des Scripts ist tatsächlich 20011224113047.000000+60. Dieser Wert besagt, dass das Betriebssystem am 24. Dezember 2001 installiert wurde. Das Datum ist korrekt - das Problem ist, dass das Datum im UTC-Format angezeigt wird (Universal Time Coordinate).

Im UTC-Format werden Daten so angezeigt: yyyymmddHHMMSS.xxxxxx±UUU. Die einzelnen Buchstaben bedeuten:

  • yyyy das Jahr.
  • mm der Monat.
  • dd der Tag.
  • HH die Stunde (im 24-Stunden Format).
  • MM die Minuten.
  • SS die Sekunden.
  • xxxxxx die Millisekunden.
  • ±UUU die Differenz der lokalen Zeitzone und Greenwich Mean Time (GMT) in Sekunden.

Der Wert 20011224113047.000000+60 kann also so übersetzt werden:

  • 2001 Jahr.
  • 12 Monat (Dezember).
  • 24 Tag.
  • 11 Stunden.
  • 30 Minuten.
  • 47 Sekunden.
  • 000000 Millisekunden.
  • -480 Differenz der lokalen Zeitzone zu GMT.

Bei einem solchen Format ist es natürlich nicht ganz einfach, Daten und Uhrzeiten abzufragen. Stellen Sie sich vor, Sie möchten eine Liste mit allen Ordnern abfragen, die nach dem 3.12.2002 erstellt wurden. Klingt einfach - die Klasse Win32_Directory stellt schließlich eine Eigenschaft mit dem Namen CreationDate zur Verfügung.

Unglücklicherweise können Sie als Datum nicht einfach 3/9/2002 angeben. Das folgende Script versucht dies und gibt keine Daten zurück:

dtmTargetDate = #3/9/2002#

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
strComputer & "\root\cimv2")

Set colDirectories = objSWbemServices.ExecQuery _
  ("SELECT * FROM Win32_Directory WHERE CreationDate > '" & _
  dtmTargetDate & "'")

For Each objDirectory In colDirectories
    Wscript.Echo objDirectory.Name
Next

Stattdessen müssen Sie das Datum im UTC-Format angeben:

dtmTargetDate = "20020903000000.000000+60"

strComputer = "."
Set objSWbemServices = GetObject("winmgmts:\\" & _
  strComputer & "\root\cimv2")

Set colDirectories = objSWBemServices.ExecQuery _
  ("SELECT * FROM Win32_Directory WHERE CreationDate > '" & _
  dtmTargetDate & "'")

For Each objDirectory In colDirectories
    Wscript.Echo objDirectory.Name
Next

Aufgrund dieser Probleme müssen Sie zwei Aufgaben ausführen können:

  • Konvertieren von WMI-Datumwerten in das Standardformat.
  • Konvertieren von Standard-Datumwerten in das WMI-Format.

WMI-Datumwerte in das Standardformat konvertieren

Auch wenn UTC-Datumwerte zuerst ein wenig verwirrend aussehen, sind sie doch relativ einfach zu konvertieren. Das liegt erstens daran, dass die Datumswerte in Form von Strings vorliegen und damit auch mit Stringfunktionen bearbeitet werden können - und zweitens daran, dass UTC ein Format mit festen Größen verwendet. Das Jahr ist zum Beispiel immer vier Ziffern lang. In Tabelle 6.10. sehen Sie diese festen Größen.

Tabelle 6.10: Zeichenpositionen im UTC-Format

Zeichenposition

Beschreibung

Beispielwert

1-4

Jahr - vier Zeichen.

2002

5-6

Monat - zwei Zeichen.

10

7-8

Tag - zwei Zeichen.

18

9-14

Stunden, Minuten und Sekunden -
sechs Zeichen.

000000

15

Ein Punkt

.

16-21

Millisekunden - sechs Zeichen.

000000

22-25

Unterschied zu GMT - drei Zeichen.

-480

Um ein Datum zu konvertieren wählen Sie einfach die entsprechenden Teile aus. Das UTC-Datum 20020710113047.000000+60 können Sie zum Beispiel so konvertieren:

  1. Tag extrahieren (10).
  2. Monat extrahieren (07).
  3. Jahr extrahieren (2002).
  4. Die extrahierten Werte zum Standardformat zusammensetzen: 10/07/2002.

Sie können die einzelnen Komponenten über die VBScript-Funktionen Left und Mid extrahieren (diese Funktionen werden im Kapitel VBScript besprochen). Um zum Beispiel den Tag zu extrahieren (die Zeichen an Position 7 und 8) verwenden Sie die folgende Codezeile (dtmInstallDate ist die Variable, die den zu konvertierenden Wert enthält):

Mid(dtmInstallDate, 7 ,2)

Die folgende Funktion konvertiert ein komplettes UTC-Datum in ein Standarddatum. Es führt die folgenden Schritte durch:

WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _
     Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _
         & " " & Mid (dtmInstallDate, 9, 2) & ":" & _
             Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _
                 13, 2))

Für den UTC-Wert 20020219145216.000000-480 wirddas folgende Datum zurückgegeben:

2/19/02 2:52:16 PM

Script 6.19 fragt das Datum ab, an dem das Betriebsystem installiert wurde. Das Datum wird über die Funktion WMIDateStringToDate in ein Standarddatum konvertiert.

Script 6.19: Konvertieren eine UTC-Werts in ein Standarddatum



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set objOS = objSWbemServices.ExecQuery("SELECT * FROM Win32_OperatingSystem")

For Each strOS in objOS

dtmInstallDate = strOS.InstallDate

strReturn = WMIDateStringToDate(dtmInstallDate)

Wscript.Echo strReturn

Next

Function WMIDateStringToDate(dtmInstallDate)

WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _

Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _

& " " & Mid (dtmInstallDate, 9, 2) & ":" & _

Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _

13, 2))

End Function

Ein Standarddatum in ein WMI-Datum konvertieren

Um ein WMI-Datum zu erstellen, sind zwei Schritte erforderlich. Erstens müssen Sie die Differenz in Minuten zu GMT feststellen, und zweitens müssen Sie das Datum zum einem UTC-Wert konvertieren.

Feststellen der Differenz zu GMT

Glücklicherweise ist es ganz einfach, diese Differenz über WMI abzufragen. Die Klasse Win32_TimeZone stellt hierzu eine Eigenschaft mit dem Namen Bias zur Verfügung. Script 6.20 zeigt, wie diese Eigenschaft abgefragt werden kann.

Script 6.20: Abfragen der Differenz zu GMT



1

2

3

4

5

6

7

8

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colTimeZone = objSWbemServices.ExecQuery _

("SELECT * FROM Win32_TimeZone")

For Each objTimeZone in colTimeZone

Wscript.Echo "Differenz: "& objTimeZone.Bias

Next

Wenn Sie das Script unter CScript ausführen, erhalten Sie auf einem deutschen Computer die folgende Ausgabe:

Differenz: -480

Ein Datum in einen UTC-Wert konvertieren

Das Zusammenbauen eines UTC-Datums ist eigentlich ganz einfach. Sie verketten einfach die entsprechenden Zahlen zu einem langen String. Es gibt jedoch eine Schwierigkeit: Monat und Tag müssen zweistellig sein. Am 10.12 ist dies kein Problem - was machen wir jedoch am 2.6?

Sie fügen dem Wert einfach eine führende Null hinzu - so wird aus 2.6 ganz einfach 02.06. Hierzu verwenden Sie die VBScript-Funktion Len, um die Länge des Wertes zu prüfen (die Zahl der Ziffern):

If Len(dtmMonth) = 1 Then
    dtmMonth = "0" & dtmMonth
End If

Script 6.21 konvertiert das aktuelle Datum in ein UTC-Datum. Wenn es den Zeitwert zum Datum hinzufügt, verwendet es die Funktion CStr. Diese stellt sicher, dass der Wert als String und nicht als Zahl behandelt wird.

Script 6.21: Konvertieren des aktuellen Datums in ein UTC-Datum



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colTimeZone = objSWbemServices.ExecQuery _

("SELECT * FROM Win32_TimeZone")

For Each objTimeZone in colTimeZone

strBias = objTimeZone.Bias

Next


dtmCurrentDate = Date

dtmTargetDate = Year(dtmCurrentDate)


dtmMonth = Month(dtmCurrentDate)

If Len(dtmMonth) = 1 Then

dtmMonth = "0" & dtmMonth

End If


dtmTargetDate = dtmTargetDate & dtmMonth


dtmDay = Day(dtmCurrentDate)

If Len(dtmDay) = 1 Then

dtmDay = "0" & dtmDay

End If


dtmTargetDate = dtmTargetDate & dtmDay & "000000.000000"

dtmTargetDate = dtmTargetDate & Cstr(strBias)

Script 6.22 demonstriert eine praktische Verwendung der Konvertierung. Es ruft alle Ordner ab, die nach einem bestimmten Datum erstellt wurden (in diesem Fall der 18.10.2003):

Script 6.22 Retrieving Folders Based on Creation Date



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colTimeZone = objSWbemServices.ExecQuery _

("SELECT * FROM Win32_TimeZone")

For Each objTimeZone in colTimeZone

strBias = objTimeZone.Bias

Next


dtmCurrentDate = "18/10/2003"

dtmTargetDate = Year(dtmCurrentDate)


dtmMonth = Month(dtmCurrentDate)

If Len(dtmMonth) = 1 Then

dtmMonth = "0" & dtmMonth

End If


dtmTargetDate = dtmTargetDate & dtmMonth


dtmDay = Day(dtmCurrentDate)

If Len(dtmDay) = 1 Then

dtmDay = "0" & dtmDay

End If


dtmTargetDate = dtmTargetDate & dtmDay & "000000.000000"

dtmTargetDate = dtmTargetDate & Cstr(strBias)


Set colFolders = objSWbemServices.ExecQuery _

("SELECT * FROM Win32_Directory WHERE CreationDate < '" & _

dtmtargetDate & "'")

For Each objFolder in colFolders

Wscript.Echo objFolder.Name

Next

Scripte auf Basis von WMI-Vorlagen erstellen

In den folgenden Abschnitten finden Sie grundlegende Scriptvorlagen, mit denen Sie die folgenden Aktionen durchführen können:

  • Abfragen und Anzeigen der Eigenschaften von verwalteten Ressourcen.
  • Ändern der Eigenschaften von verwalteten Ressourcen.
  • Methoden einer WMI-Klasse aufrufen.
  • Eine neue Instanz einer verwalteten Ressource erstellen.
  • Vorhandene Instanzen einer verwalteten Ressource löschen.
Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Alle Scriptvorlagen werden gegen den lokalen Computer ausgeführt ("."). Um das Script gegen einen Remotecomputer auszuführen, ändern Sie einfach den Wert der Variable strComputer:
strComputer = "atl-dc-01"

Abfragen und Anzeigen der einzelnen Eigenschaften verwalteter Ressourcen

Script 6.23 gibt Informationen über die installierten Dienste zurück. Es kann jedoch sehr schnell so angepasst werden, dass es Informationen über jede andere verwaltete Ressource zurückgibt.

Script 6.23: Vorlage zum Abfragen und Anzeigen von Ressourceneigenschaften



1

2

3

4

5

6

7

8

9

10

11

12

13

strComputer = "."

strNamespace = "\root\cimv2"

strClassName = "Win32_Service"


Set objSWbemServices = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & strNamespace)


Set colInstances = objSWbemServices.ExecQuery _

("SELECT * FROM" & strClassName)

For Each objInstance in colInstances

Wscript.Echo "Caption " & objInstance.Caption

Wscript.Echo "Description " & objInstance.Description

Next

Um die Vorlage mit anderen WMI-Klassen zu verwenden:

  • Setzen Sie die Variable strClassName auf die entsprechende WMI-Klasse.
  • Setzen Sie - wenn nötig - die Variable strNamespace auf den entsprechenden WMI-Namespace.
  • Ersetzt die Zeilen in der For-Each-Schleife durch die entsprechenden Eigenschaften

Abfragen und Anzeigen aller Eigenschaften einer verwalteten Ressource

Script 6.24 fragt alle Eigenschaften und die Werte einer Klasse ab.

Script 6.24: Vorlage zum Abfragen und Anzeigen aller Eigenschaften einer Ressource



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

strComputer = "."

strNamespace = "\root\cimv2"

strClassName = "Win32_Process"



Set objSWbemServices = _

GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_

strComputer & strNamespace)


Set colInstances = objSWbemServices.ExecQuery("SELECT * FROM " &_

strClassName)


Wscript.Echo "Eigenschaften der Klasse " & strClassName

Wscript.Echo "================================================="


iCount = 0

For Each objInstance in colInstances

iCount = iCount + 1

Set colProperties = objInstance.Properties_


Wscript.Echo vbCrLf

Wscript.Echo "******************"

Wscript.Echo "INSTANZ NUMMER: " & iCount

Wscript.Echo "******************"

Wscript.Echo vbCrLf


For Each objProperty in colProperties

Wscript.Echo objProperty.Name & " : " & objProperty.Value

Next

Wscript.Sleep(2000)

Next

Um diese Vorlage mit anderen WMI-Klassen zu verwenden:

  • Setzen Sie den Wert von strClassName auf die entsprechende WMI-Klasse.
  • Wenn notwendig, ändern Sie den Wert von strNamespace.

Schreiben von Ressourceneigenschaften

Script 6.25 fragt alle Instanzen der Klasse Win32_OSRecoveryConfiguration ab. Es ändert die Werte von einigen Eigenschaften und wendet diese dann über die Methode Put_ an.

Dn151185.note(de-de,TechNet.10).gifAnmerkung:

Diese Vorlage funktioniert nur für Eigenschaften, die schreibbar sind. Bei allen anderen Eigenschaften führt es zu einem Fehler.

Script 6.25: Vorlage zum Schreiben von Ressourceneigenschaften



1

2

3

4

5

6

7

8

9

10

11

12

13

14

strComputer = "."

strClassName = "Win32_OSRecoveryConfiguration"

strNamespace = "\root\cimv2"


Set objSWbemServices = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & strNamespace)

Set colInstances = objSWbemServices.ExecQuery _

("SELECT * FROM " & strClassName)

For Each objInstance in colInstances

objInstance.DebugInfoType = 1

objInstance.DebugFilePath = "c:\scripts\memory.dmp"

objInstance.OverWriteExistingDebugFile = False

objInstance.Put_

Next

Um die Vorlage mit anderen WMI-Klassen zu verwenden und andere Eigenschaften zu ändern:

  • Setzen Sie den Wert von strClassName auf die entsprechende WMI-Klasse.
  • Wenn notwendig, ändern Sie den Wert von strNamespace.
  • Ersetzt die Zeilen in der For-Each-Schleife durch die entsprechenden Eigenschaften

Aufrufen von Methoden

Script 6.26 kann als Vorlage für ein Script verwendet werden, das WMI-Methoden aufruft. Dieses Script ruft die Methode StopService der Klasse Win32_Service auf, um den Dienst Alerter anzuhalten.

Script 6.26: Vorlage zum Aufrufen von Methoden



1

2

3

4

5

6

7

8

9

10

11

12

13

14

strComputer = "."

strNamespace = "\root\cimv2"

strClassName = "Win32_Service"

strKeyName = "Name"

strKeyValue = "Alerter"


Set objSWbemServices = GetObject("winmgmts:" &_

"{impersonationLevel=impersonate}!\\" & strComputer & strNamespace)

Set colInstances = objSWbemServices.ExecQuery _

("SELECT * FROM " & strClassName & " WHERE " & strKeyName & " = '" &_

strKeyValue & "'")

For Each objInstance in colInstances

objInstance.StopService()

Next

Um die Vorlage mit anderen WMI-Klassen zu verwenden und andere Eigenschaften zu ändern:

  • Setzen Sie den Wert von strClassName auf die entsprechende WMI-Klasse.
  • Wenn notwendig, ändern Sie den Wert von strNamespace.
  • Setzen Sie den Wert von strKeyName auf den Namen der Eigenschaft, die in der WHERE-Bedingung verwendet wird.
  • Setzen Sie den Wert von strKeyValue auf den entsprechenden Wert für diese Eigenschaft.
  • Ersetzt Sie die Zeilen in der For-Each-Schleife durch die entsprechenden Methodenaufrufe

Erstellen von Ressourcen

Script 6.27 verwendet die Methode Create, um einen neuen freigegebenen Ordner zu erstellen.

Script 6.27: Vorlage zum Erstellen von Ressourcen



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

strComputer = "."

strNamespace = "\root\cimv2"

strClassName = "Win32_Share"


Set objSWbemServices = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & strNamespace)


Set objNewShare = objSWbemServices.Get(strClassName)

Set objInParams = _ objNewShare.Methods_("Create").InParameters.SpawnInstance_()


objInParams.Properties_.Item("Description") = "New Share Description"

objInParams.Properties_.Item("Name") = "New Share Name"

objInParams.Properties_.Item("Path") = "C:\scripts\shared"

objInParams.Properties_.Item("Type") = 0


objNewShare.ExecMethod_ "Create", objInParams

Um die Vorlage mit anderen WMI-Klassen zu verwenden und andere Eigenschaften zu ändern:

  • Setzen Sie den Wert von strClassName auf die entsprechende WMI-Klasse.
  • Wenn notwendig, ändern Sie den Wert von strNamespace.
  • Ersetzt die Zeilen in der For-Each-Schleife durch die erforderlichen neuen Zeilen.

Löschen von Ressourcen

Script 6.28 löscht den freigegebenen Ordner mit dem Namen "New Share Name."

Script 6.28: Vorlage zum Löschen von Ressourcen



1

2

3

4

5

6

7

8

9

10

11

12

13

strComputer = "."

strNamespace = "\root\cimv2"

strClassName = "Win32_Share"

strKeyName = "Name"

strKeyValue = "New Share Name"


Set objSWbemServices = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & strNamespace)


Set objInstance = objSWbemServices.Get(strClassName & "." &_

strKeyName & "='" &_

strKeyValue & "'")

objInstance.Delete

Um die Vorlage mit anderen WMI-Klassen zu verwenden und andere Eigenschaften zu ändern:

  • Setzen Sie den Wert von strClassName auf die entsprechende WMI-Klasse.
  • Wenn notwendig, ändern Sie den Wert von strNamespace.
  • Ersetzt Sie die Zeilen in der For-Each-Schleife durch die erforderlichen neuen Zeilen.
  • Setzten Sie den Wert von strKeyName auf die Schlüsseleigenschaft der Klasse.
  • Setzen Sie den Wert von strKeyValue auf den entsprechenden Wert für diese Eigenschaft.

Überwachen von Ressourcen über WMI-Ereignisbenachrichtigungen

Über WMI-Ereignisbenachrichtigungen können Sie den Status einer verwalteten Ressource überwachen und auf ein Problem reagieren.

Statt zum Beispiel zu warten bis der freie Festplattenplatz aufgebraucht ist, können Sie eine WMI-Ereignisbenachrichtigung einrichten, die Sie per E-Mail benachrichtigt, wenn der freie Speicherplatz unter einen bestimmten Wert fällt.

Scripte, die verwaltete Ressourcen überwachen, sehen genauso aus wie andere WMI-Scripte. Script 6.29 überwacht zum Beispiel die Prozesse auf einem Computer und zeigt eine Nachricht an, wenn ein Prozess mit dem Namen Notepad.exe gestartet wurde.

Wenn Sie das Script unter CScript ausführen, sehen Sie nur, dass das Script gestartet wird und nicht beendet wird. Das Script wartet einfach auf das entsprechende Ereignis.

Wenn Sie dann Notepad starten, zeigt das Script die folgende Fehlermeldung an:

Notepad.exe wurde soeben gestartet.

Script 6.29: Überwachen des Prozesses Notepad.exe



1

2

3

4

5

6

7

8

9

10

11

12

13

14

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:" &_

"{impersonationLevel=impersonate}!" &_

"\\" & strComputer & "\root\cimv2")


Set objEventSource = objSWbemServices.ExecNotificationQuery( _

"SELECT * FROM __InstanceCreationEvent " &_

"WITHIN 10 " &_

"WHERE TargetInstance " &_

"ISA 'Win32_Process' " &_

"AND TargetInstance.Name = 'notepad.exe'")


Set objEventObject = objEventSource.NextEvent()

Wscript.Echo "Notepad.exe wurde soeben gestartet."

In den Zeilen 1 bis 4 baut das Script eine Verbindung zum Namespace root\cimv2 auf.

In den Zeilen 6 bis 11 wird eine Benachrichtigungsabfrage über die Methode ExecNotificationQuery ausgeführt. Der WQL-Abfragestring wird in den Zeilen 7 bis 11 erstellt. Der Abfragestring enthält die neuen Schlüsselwörter WITHIN und ISA. Diese werden später besprochen.

In Zeile 13 wird die Methode NextEvent verwendet, um das Script anzuhalten und auf das nächste durch die Abfrage beschriebene Ereignis zu warten.

In Zeile 14 wir eine Nachricht angezeigt, wenn das Ereignis aufgetreten ist.

Script 6.30 überwachen die Dienste auf einem Computer und zeigt eine Nachricht an, wenn Sie der Status des Dienstes Alerter ändert. Starten Sie das Script und führen Sie die Befehle net start alerter oder net stop alerter aus. Sie erhalten die folgende Ausgabe:

Status des Dienstes alerter hat sich geändert.

Script 6.30: Überwachen des Dienstes Alerter



1

2

3

4

5

6

7

8

9

10

11

12

13

14

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:" &_

"{impersonationLevel=impersonate}!" &_

"\\" & strComputer & "\root\cimv2")


Set objEventSource = objSWbemServices.ExecNotificationQuery( _

"SELECT * FROM __InstanceModificationEvent " &_

"WITHIN 10 " &_

"WHERE TargetInstance " &_

"ISA 'Win32_Service' " &_

"AND TargetInstance.Name = 'alerter'")


Set objEventObject = objEventSource.NextEvent()

Wscript.Echo "Status des Dienstes alerter hat sich geändert."

Vergleichen Sie das Script mit Script 6.29. Die Elemente, die sich unterscheiden, sind fett formatiert. Es gibt vier Unterschiede:

  • Der überwachte Ereignistyp:
    __InstanceCreationEvent wurde in __InstanceModificationEvent geändert.
  • Die WMI-Klasse der zu überwachenden Ressource:
    Win32_Process wurde in Win32_Service geändert.
  • Der Wert der Eigenschaft Name:
    notepad.exe wurde in alerter geändert.
  • Die angezeigte Nachricht.

Die drei Schritte eines Überwachungsscripts

Die Überwachung von Ressourcen erfolgt über drei Schritte:

  1. Aufbau einer Verbindung zu einem WMI-Namespace auf einem Computer.
    strComputer = "."
    Set objSWbemServices = GetObject("winmgmts:" &_
    "{impersonationLevel=impersonate}!" &_
    "\\" & strComputer & "\root\cimv2")
  2. Ausführen einer Benachrichtigungsabfrage.
    Hierzu wird eine WQL-Abfrage mit den neuen Schlüsselwörtern WITHIN und ISA verwendet.
    Set objEventSource = objSWbemServices.ExecNotificationQuery( _
    "SELECT * FROM __InstanceModificationEvent " &_
    "WITHIN 10 " &_
    "WHERE TargetInstance " &_
    "ISA 'Win32_Service' " &_
    "AND TargetInstance.Name = 'alerter'")
  3. Empfangen des Ereignisses und Durchführung der erforderlichen Aktionen.
    Im dritten Schritt wird die Methode NextEvent aufgerufen. Das Script hält an und wartet auf das Auftreten des Ereignisses. Dann verarbeitet des die weiteren Zeilen:
    Set objEventObject = objEventSource.NextEvent()
    Wscript.Echo "Status des Dienst Alerter hat sich geändert."

Es gibt einige wichtige Unterschiede zwischen Standard-WMI-Abfragen und Ereignisbenachrichtigungsabfragen.

Ereignisbenachrichtigungsabfragen verwenden Ereignisklassen.

Statt Instanzen von verwalteten Ressourcen abzufragen, verwenden Ereignisbenachrichtigungsabfragen Instanzen einer Ereignisklasse. Die Klasse __InstanceModificationEvent stellt zum Beispiel das Ereignis dar, das auftritt, wenn eine Instanz verändert wird - __InstanceDeletionEvent und __InstanceModificationEvent treten bei Löschen und Ändern von Instanzen auf. Jede dieser drei Klassen ist von der mehr allgemeinen Klasse __InstanceOperationEvent abgeleitet.

Ereignisbenachrichtigungsabfragen verwenden das Schlüsselwort WITHIN

Da die Klasse Win32_Service nicht über einen WMI-Eventprovider verfügt, muss das Schlüsselwort WITHIN verwendet werden, damit der WMI-Abfragemechanismus alle 10 Sekunden ausgeführt wird. Theoretisch kann es passieren, dass Ereignisse verpasst werden - zum Beispiel dann, wenn die Abfrage nur alle 30 Sekunden verwendet wird.

Ereignisbenachrichtigungsabfragen verwenden das Objekt TargetInstance

Es ist ziemlich unwahrscheinlich, dass Sie sich bei jeder erstellten Instanz einer WMI-Klasse benachrichtigen lassen möchten. Stattdessen sind Sie wahrscheinlich an einer bestimmten Klasse interessiert. Mit TargetInstance sind Sie in der Lage, diese Instanz anzugeben.

TargetInstance ist ein Objekt, das als Reaktion auf ein Ereignis erstellt wird. Es hat dieselben Eigenschaften und Werte wie das Objekt, dass das Ereignis ausgelöst hat. Außerdem gibt es ein WMI-Objekt mit dem Namen PreviousInstance. Dieses Objekt enthält die Eigenschaften und Werte, die vor dem Ereignis vorhanden waren. Über diese beiden Objekte können Sie feststellen, was durch das Ereignis geändert wurde.

Ereignisbenachrichtigungsabfragen verwenden das Schlüsselwort ISA

Über dieses Schlüsselwort können Sie prüfen, ob eine bestimmte Instanz zu einer bestimmten Klasse gehört. Es entspricht im Groben dem Gleichheitszeichen.

Wie die Ereignisbenachrichtigung arbeitet

Wie für jede verwaltete Ressource gibt es auch für jedes Ereignis eine Klasse. Wenn ein Ereignis auftritt, wird eine Instanz der entsprechenden Klasse verwendet.

Es gibt drei Haupttypen von WMI-Ereignisklassen, die alle von der Klasse __Event abgeleitet sind: Intrinsic, Extrinsic und Timer Events. Die Intrinsic-Klasse wird wiederum durch drei Klassen repräsentiert __NamespaceOperationEvent, __InstanceOperationEvent und __ClassOperationEvent.

Die von __Event abgeleiteten Klassen müssen in jedem Namespace vorhanden sein, der Ressourcen enthält, die überwacht werden können. In Abbildung 6.5 sehen Sie die von __Event abgeleiteten Klassen im Namespace \root\default.

Dn151185.6FA1947E6602275B6272677270FC5FEE(de-de,TechNet.10).png

Abbildung 6.5: Hierarchie der Ereignisklassen

Intrinsic-Ereignisse

Mit Intrinsic-Ereignissen werden Ressourcen überwacht, die durch eine Klasse im CIM-Repository repräsentiert werden. Sie können außerdem zu Überwachung von Änderungen an einem Namespace oder einer Klasse verwendet werden.

Ein Intrinsic-Ereignis wird durch eine Instanz einer Klasse repräsentiert, die von den Klassen __InstanceOperationEvent, __NamespaceOperationEvent oder __ClassOperationEvent abgeleitet ist. Alle Änderungen an Instanzen werden durch die Klasse __InstanceOperationEvent und den von dieser Klasse abgeleiteten Klassen __InstanceCreationEvent, __InstanceModificationEvent und __InstanceDeletionEvent repräsentiert.

Eine Überwachung dieser Instanzen führen Sie über eine WQL-Benachrichtigungsabfrage durch. Die entsprechende WQL-Syntax sieht so aus:

SELECT * FROM __InstanceOperationEventOrDerivedClass WITHIN PollingInterval WHERE TargetInstance ISA WMIClassName 
AND TargetInstance.WMIClassPropertyName = Value

Die von __InstanceOperationEvent abgeleitete Klasse, die Sie zur Überwachung registrieren, ist von dem zu überwachenden Ereignis abhängig.

Erstellung einer Ressource: __InstanceCreationEvent

Die Benachrichtigungsabfrage für die Erstellung einer Ressource sieht folgendermaßen aus:

SELECT * FROM __InstanceCreationEvent WITHIN PollingInterval WHERE 
TargetInstance ISA 'Win32_Process' and TargetInstance.Name = 'notepad.exe'

Änderung einer Ressource: __InstanceModificationEvent

Die Benachrichtigungsabfrage für die Änderung einer Ressource sieht folgendermaßen aus:

SELECT * FROM __InstanceModificationEvent WITHIN PollingInterval WHERE 
TargetInstance ISA 'Win32_Service' and TargetInstance.Name = 'alerter'

Löschen einer Ressource: __InstanceDeletionEvent

Die Benachrichtigungsabfrage für das Löschen einer Ressource sieht folgendermaßen aus:

SELECT * FROM __InstanceDeletionEvent WHERE 
TargetInstance ISA 'Win32_Process' and TargetInstance.Name = 'notepad.exe'

Extrinsic-Ereignisse

Mit diesen Ereignissen überwachen Sie eine Ressource, die nicht durch eine Klasse im CIM-Repository repräsentiert ist. Mit Extrinsic-Ereignissen können Sie zum Beispiel überwachen, ob Änderungen an der Registrierung vorgenommen wurden.

Scripte, die Extrinsic-Ereignisse verwenden, gehen genau wie Scripte mit Intrinsic-Ereignissen vor. Die entsprechenden Klassen werden jedoch von der Klasse __ExtrinsicEvent abgeleitet.

Erweiterte Überwachung

Die Überwachung über ein WMI-Script unterliegt einigen Einschränkungen:

  • Instanzen können nur über eine einzelne Eigenschaft überwacht werden.
  • Es kann nur ein Ereignis überwacht werden.
  • Es kann nur ein Ereignistyp überwacht werden: Erstellen, Ändern oder Löschen.
  • Es kann nur ein Ressourcentyp überwacht werden.

Die folgenden Beispielscripte zeigen, wie Sie diese Beschränkungen umgehen können.

Überwachen einer bestimmten Ressource

Sie können die Ressource genauer angeben, wenn Sie die WHERE-Bedingung erweitern. Script 6.31 definiert, dass die Eigenschaft DeviceID den Wert CPU0 haben muss, und dass die Eigenschaft LoadPercentage einen Wert größer 90 haben muss.

Script 6.31: Überwachen der ersten CPU auf eine Auslastung von mehr als 90 Prozent



1

2

3

4

5

6

7

8

9

10

11

12

Set objSWbemServices = _

GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")


strWQL = "SELECT * FROM __InstanceModificationEvent " &_

"WITHIN 5 " &_

"WHERE TargetInstance ISA 'Win32_Processor' " &_

"AND TargetInstance.DeviceID='CPU0' " &_

"AND TargetInstance.LoadPercentage > 90"


Set objEventSource = objSWbemServices.ExecNotificationQuery(strWQL)

Set objEventObject = objEventSource.NextEvent()

Wscript.Echo "Load Percentage on CPU0 exceeded 90%."

Mehr als ein Ereignis überwachen

Script 6.29 und Script 6.30 werden nach dem Auftreten des Ereignisses beendet. Wenn die Scripte nach einem Ereignis auf weitere Ereignisse reagieren soll, sind hierzu nur wenige Änderungen erforderlich. Fassen Sie den Aufruf der Methode NextEvent und die Ausgabe einfach in eine Endlosschleife ein.

Script 6.32: Fortwährende Überwachung der ersten CPU auf eine Auslastung von mehr als 90 Prozent



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

strComputer = "."

Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\root\cimv2")


strWQL = "SELECT * FROM __InstanceModificationEvent " & _

"WITHIN 5 " & _

"WHERE TargetInstance ISA 'Win32_Processor' " & _

"AND TargetInstance.DeviceID='CPU0' " & _

"AND TargetInstance.LoadPercentage > 90"


Set objSWbemEventSource = objSWbemServices.ExecNotificationQuery(strWQL)


While True

Set objSWbemObject = objSWbemEventSource.NextEvent()

WScript.Echo "Load Percentage on CPU0 exceeded 90%."

Wend

Mehr als einen Ereignistyp überwachen

Script 6.29 verarbeitet nur die Erstellungs-Ereignisse. Script 6.30 verarbeitet nur Änderungs-Ereignisse. Nehmen wir jedoch an, Sie möchten benachrichtigt werden wenn Notepad gestartet wird, wenn die Instanz von Notepad geändert wird und wenn Notepad gelöscht wird. Bis jetzt müssten Sie hierzu drei Scripte schreiben und starten.

Die Klassen __InstanceCreationEvent, __InstanceModificationEvent und __InstanceDeletionEvent sind alle von der Klasse __InstanceOperationEvent abgeleitet. Wenn Sie also in der WQL-Benachrichtigungsabfrage __InstanceOperationEvent verwenden, dann werden Sie über alle Ereignisse informiert.

Script 6.33: Überwachung mehrerer Ereignisse für Notepad.exe



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

strComputer = "."

Set objSWbemServices = GetObject("winmgmts:" &_

"{impersonationLevel=impersonate}!" &_

"\\" & strComputer & "\root\cimv2")


Set objEventSource = objSWbemServices.ExecNotificationQuery( _

"SELECT * FROM __InstanceOperationEvent " &_

"WITHIN 1 " &_

"WHERE TargetInstance " &_

"ISA 'Win32_Process' " &_

"AND TargetInstance.Name = 'notepad.exe'")


Set objEventObject = objEventSource.NextEvent()

Select Case objEventObject.Path_.Class

Case "__InstanceCreationEvent"

Wscript.Echo "Instanz von Notepad.exe gestartet."

Case "__InstanceDeletionEvent"

Wscript.Echo "Instanz von Notepad.exe beendet."

Case "__InstanceModificationEvent"

Wscript.Echo "Instanz von Notepad.exe geändert."

End Select

Mehrere Ressourcentypen überwachen

Script 6.29 überwacht einen Prozess und Script 6.30 überwacht einen Dienst. Es scheint also so, als würde für jede Ressource ein eigenes Script benötigt. Dies ist jedoch nicht richtig - die beiden Ressourcen können auch in einem Script überwacht werden. Hierzu müssen Sie zwei Änderungen vornehmen:

  • Sie müssen die WQL-Abfrage durch logische ORs erweitern, um Benachrichtigungen von mehreren Ressourcen zu erhalten (Zeilen 12-14).
  • Um festzustellen, wo ein Ereignis herkommt, müssen Sie die vom Ereignisobjekt zurückerhaltene Klasse überprüfen (Zeile 17-22).

Script 6.34: Überwachen eines Dienstes und eines Prozesses



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

strComputer = "."

Set objSWbemServices = _

GetObject("winmgmts:\\" & strComputer & "\root\cimv2")


Set objSWbemEventSource = objSWbemServices.ExecNotificationQuery( _

"SELECT * FROM __InstanceModificationEvent " & _

"WITHIN 1 " & _

"WHERE (TargetInstance " & _

"ISA 'Win32_Process' " & _

"AND TargetInstance.Name = 'notepad.exe') " & _

"OR (TargetInstance " & _

"ISA 'Win32_Service' " & _

"AND TargetInstance.Name='w3svc')")


Set objSWbemObject = objSWbemEventSource.NextEvent()

Select Case objSWbemObject.TargetInstance.Path_.Class

Case "Win32_Process"

WScript.Echo "Instanz von notepad.exe geändert."

Case "Win32_Service"

WScript.Echo "Status von Dienst W3SVC geändert."

End Select

Dn151185.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

| Home | Technische Artikel | Community