Erstellen eines WMI-Skripts

Sie können alle über WMI verfügbar gemachten Informationen mithilfe von Skripts anzeigen oder bearbeiten. Skripts können in jeder Skriptsprache geschrieben werden, die Microsoft ActiveX-Skripthosting unterstützt, beispielsweise Visual Basic Scripting Edition (VBScript), PowerShell und Perl. Windows Script Host (WSH), Active Server Page und Internet Explorer können WMI-Skripts hosten.

Hinweis

Die primäre Skriptsprache, die derzeit von WMI unterstützt wird, ist PowerShell. WMI umfasst aber auch eine stabile Skriptunterstützung für VBScript und andere Sprachen, die auf die Skripterstellungs-API für WMI zugreifen.

 

WMI-Skriptsprachen

Die beiden von WMI unterstützten Hauptssprachen sind PowerShell und VBScript (über Windows Script Host oder WSH).

  • PowerShell wurde im Hinblick auf eine enge Integration mit WMI entwickelt. Daher sind viele der zugrunde liegenden Elemente von WMI in die WMI-Cmdlets integriert: Get-WmiObject, Set-WmiInstance, Invoke-WmiMethod und Remove-WmiObject. In der folgenden Tabelle werden die allgemeinen Prozesse beschrieben, die für den Zugriff auf WMI-Informationen verwendet werden. Beachten Sie, dass die meisten dieser Beispiele zwar „Get-WMIObject“ verwenden, viele der PowerShell-WMI-Cmdlets aber die gleichen Parameter wie -Class oder -Credentials aufweisen. Daher funktionieren viele dieser Prozesse auch für andere Objekte. Eine ausführlichere Erläuterung von PowerShell und WMI finden Sie unter Verwenden des Cmdlets „Get-WMiObject“ und Windows PowerShell – die WMI-Verbindung.

  • VBScript ruft dagegen explizit die Skripterstellungs-API für WMI auf, wie oben erwähnt. Auch andere Sprachen, z. B. Perl, können die Skripterstellungs-API für WMI verwenden. Für die Zwecke dieser Dokumentation verwenden die meisten Beispiele, die die Skripterstellungs-API für WMI veranschaulichen, VBScript. Ist eine Programmiertechnik jedoch vbScript-spezifisch, wird mit einem Kommentar darauf hingewiesen.

    VBScript verfügt im Wesentlichen über zwei separate Möglichkeiten für den Zugriff auf WMI. Die erste ist die Verwendung eines SWbemLocator-Objekts zum Herstellen einer Verbindung mit WMI. Alternativ können Sie GetObject und einen Moniker verwenden. Ein Moniker ist eine Zeichenfolge, die eine Reihe von Elementen beschreiben kann: Ihre Anmeldeinformationen, Identitätswechseleinstellungen, den Computer, mit dem Sie eine Verbindung herstellen möchten, den WMI-Namespace (d. h. den allgemeinen Speicherort, an dem WMI Objektgruppen speichert) und das WMI-Objekt, das Sie abrufen möchten. Viele der folgenden Beispiele beschreiben beide Techniken. Weitere Informationen finden Sie unter Erstellen einer Monikerzeichenfolge und Beschreiben des Speicherorts eines WMI-Objekts.

    Unabhängig davon, welche Technik Sie zum Herstellen einer Verbindung mit WMI verwenden, rufen Sie wahrscheinlich ein oder mehrere Objekte aus der Skripterstellungs-API ab. Am häufigsten ist SWbemObject, das von WMI zum Beschreiben eines WMI-Objekts verwendet wird. Alternativ können Sie ein SWbemServices-Objekt verwenden, um den WMI-Dienst selbst zu beschreiben, oder ein SWbemObjectPath-Objekt, um den Speicherort eines WMI-Objekts zu beschreiben. Weitere Informationen finden Sie unter Skripterstellung mit „SWbemObject“ und Hilfsobjekte für die Skripterstellung.

Wie kann ich WMI und eine Skriptsprache verwenden...

...um eine Verbindung zu WMI herzustellen?

Rufen Sie für VBScript und die Skripterstellungs-API für WMI ein SWbemServices-Objekt mit einem Moniker und einem Aufruf von GetObject ab. Alternativ können Sie über einen Aufruf von SWbemLocator.ConnectServer eine Verbindung mit dem Server herstellen. Anschließend können Sie das Objekt verwenden, um auf einen bestimmten WMI-Namespace oder eine bestimmte WMI-Klasseninstanz zuzugreifen.

Bei PowerShell wird die Verbindung mit WMI in der Regel direkt im Cmdletaufruf hergestellt, wodurch keine zusätzlichen Schritte erforderlich sind.

Weitere Informationen finden Sie unter Beschreiben des Speicherorts eines WMI-Objekts, Erstellen einer Monikerzeichenfolge und Herstellen einer Verbindung mit WMI mithilfe von VBScript.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")

' Second example: implicitly uses the local compuer (.) and default namespace ("root\cimv2")
Set objWMIService = GetObject("winmgmts:")

#Already has all the defaults set
get-WmiObject Win32_LogicalDisk

#Or, to be explicit,
get-WmiObject -class Win32_LogicalDisk -Computer "." -Namespace "root\cimv2" -Impersonation Impersonate

...um Informationen aus WMI abzurufen?

Verwenden Sie für VBScript und die Skripterstellungs-API für WMI eine Abruffunktion, z. B. WbemServices.Get oder WbemServices.InstancesOf. Sie können auch den Klassennamen des abzurufenden Objekts in einem Moniker platzieren, was möglicherweise effizienter ist.

Verwenden Sie für PowerShell den Parameter -Class. Beachten Sie, dass „-Class“ der Standardparameter ist, daher müssen Sie ihn nicht explizit angeben.

Weitere Informationen finden Sie unter Abrufen von WMI-Klassen- oder Instanzdaten.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")
Set colScheduledJobs = objService.InstancesOf("Win32_ScheduledJob")

' Second example
SSet Service = GetObject("WinMgmts:{impersonationLevel=impersonate}!Win32_Service=""ALERTER""")

#default - you don't actually need to use the -Class parameter
Get-WMIObject Win32_WmiSetting

#but you can if you want to
Get-WMIObject -Class Win32_WmiSetting

...um eine WMI-Abfrage zu erstellen?

Verwenden Sie für VBScript und die Skripterstellungs-API für WMI die Methode SWbemServices.ExecQuery.

Verwenden Sie für PowerShell den Parameter -Query. Sie können auch mit dem Parameter -Filter filtern.

Weitere Informationen finden Sie unter Abfragen von WMI.

strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colScheduledJobs = objWMIService.ExecQuery("Select * from Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

Get-WmiObject -query "SELECT * FROM Win32_logicalDisk WHERE DeviceID = 'C:'"

#or

get-wmiObject -Class Win32_LogicalDisk -Filter "DeviceID = 'C:'"

...um eine Aufzählung über eine Liste von WMI-Objekten zu erstellen?

Verwenden Sie für VBScript und die Skripterstellungs-API für WMI das Containerobjekt SWbemObjectSet, das im Skript als Sammlung behandelt wird, die aufgezählt werden kann. Sie können SWbemObjectSet aus einem Aufruf aus SWbemServices.InstancesOf oder SWbemServices.ExecQuery abrufen.

PowerShell kann Aufzählungen wie jedes andere Objekt abrufen und behandeln, für WMI gelten keine Besonderheiten.

Weitere Informationen finden Sie unter Zugreifen auf eine Sammlung.

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDevice")

$logicalDevices = Get-WmiObject CIM_LogicalDevice
foreach ($device in $logicalDevices)
{
    $device.name
}

#or, to be more compact

Get-WmiObject cim_logicalDevice | ForEach-Object { $_.name }

...um auf einen anderen WMI-Namespace zuzugreifen?

Geben Sie für VBScript und die Skripterstellungs-API für WMI den Namespace im Moniker an. Alternativ können Sie den Namespace explizit im Aufruf von SwbemLocator.ConnectServer angeben.

Verwenden Sie für PowerShell den Parameter -Namespace. Der Standardnamespace ist „root\cimV2“. Viele ältere Klassen werden jedoch in „root\default“ gespeichert.

Um den Speicherort einer bestimmten WMI-Klasse zu finden, sehen Sie sich die Referenzseite an. Alternativ können Sie einen Namespace mithilfe von „get-WmiObject“ manuell untersuchen.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")

' Second example
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")

Get-WmiObject -list * -Namespace root\default

#or, to retrieve all namespaces,
Get-WmiObject -Namespace root -Class __Namespace

...um alle untergeordneten Instanzen einer Klasse abzurufen?

Für Sprachen, die die Skripterstellungs-API für WMI und PowerShell direkt verwenden, unterstützt WMI das Abrufen der untergeordneten Klassen einer Basisklasse. Daher müssen Sie nur nach der übergeordneten Klasse suchen, um die untergeordneten Instanzen abzurufen. Im folgenden Beispiel wird nach CIM_LogicalDisk gesucht. Dabei handelt es sich um eine vorinstallierte WMI-Klasse, die logische Datenträger auf einem Windows-basierten Computersystem darstellt. Daher gibt die Suche nach dieser übergeordneten Klasse auch Instanzen von Win32_LogicalDisk zurück, womit von Windows Festplatten beschrieben werden. Weitere Informationen finden Sie unter Common Information Model. WMI stellt ein komplettes Schema solcher vorinstallierten Klassen bereit, mit denen Sie auf verwaltete Objekte zugreifen und diese steuern können. Weitere Informationen finden Sie unter Win32-Klassen und WMI-Klassen.

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Name
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.Name  }

...um ein WMI-Objekt zu suchen?

Sowohl für die Skripterstellungs-API für WMI als auch für PowerShell verwendet WMI eine Kombination aus Namespace, Klassenname und Schlüsseleigenschaften, um eine bestimmte WMI-Instanz eindeutig zu identifizieren. Zusammen wird dies als WMI-Objektpfad bezeichnet. Für VBScript beschreibt die Eigenschaft SWbemObject.Path_ den Pfad für jedes angegebene Objekt, das von der Skripterstellungs-API zurückgegeben wird. Für PowerShell verfügt jedes WMI-Objekt über eine __PATH-Eigenschaft. Weitere Informationen finden Sie unter Beschreiben des Speicherorts eines WMI-Objekts.

Zusätzlich zum Namespace- und Klassennamen verfügt ein WMI-Objekt auch über eine Schlüsseleigenschaft, die diese Instanz im Vergleich zu anderen Instanzen auf Ihrem Computer eindeutig identifiziert. Die Eigenschaft DeviceID ist beispielsweise die Schlüsseleigenschaft für die Klasse Win32_LogicalDisk. Weitere Informationen finden Sie unter Managed Object Format.

Schließlich ist der relative Pfad einfach eine verkürzte Form des Pfads und enthält den Klassennamen und den Schlüsselwert. In den folgenden Beispielen kann der Pfad "\\computerName\root\cimv2:Win32_LogicalDisk.DeviceID=“D:““ sein, während der relative Pfad „Win32LogicalDisk.DeviceID=“D““ lautet.

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Path_.Relpath

'or to get the path
For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Path_
#retrieving the path
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.__PATH  }

#retrieving the relative path
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.__RELPATH  }

...um Informationen in WMI festzulegen?

Verwenden Sie für VBScript und die Skripterstellungs-API für WMI die Methode SWbemObject.Put_.

Für PowerShell können Sie entweder die „Put“-Methode oder set-WmiInstance verwenden.

Weitere Informationen finden Sie unter Ändern einer Instanzeigenschaft.

wbemCimtypeString = 8
Set objSWbemService = GetObject("Winmgmts:root\default")
Set objClass = objSWbemService.Get()
objClass.Path_.Class = "NewClass"

' Add a property
' String property
objClass.Properties_.add "PropertyName", wbemCimtypeString  
' Make the property a key property 
objClass.Properties_("PropertyName").Qualifiers_.add "key", true

' Write the new class to the root\default namespace in the repository
Set objClassPath = objClass.Put_
WScript.Echo objClassPath.Path

'Create an instance of the new class using SWbemObject.SpawnInstance
Set objNewInst = GetObject("Winmgmts:root\default:NewClass").Spawninstance_

objNewInst.PropertyName = "My Instance"

' Write the instance into the repository
Set objInstancePath = objNewInst.Put_
WScript.Echo objInstancePath.Path

$mySettings = get-WMIObject Win32_WmiSetting
$mySettings.LoggingLevel = 1
$mySettings.Put()

#or

Set-WMIInstance -class Win32_WMISetting -argument @{LoggingLevel=1}

...um andere Anmeldeinformationen zu verwenden?

Verwenden Sie für VBScript und die Skripterstellungs-API für WMI die Parameter UserName und Password in der Methode SWbemLocator.ConnectServer.

Verwenden Sie für PowerShell den Parameter -Credential.

Beachten Sie, dass Sie alternative Anmeldeinformationen nur auf einem Remotesystem verwenden können. Weitere Informationen finden Sie unter Schützen von Skripterstellungsclients.

strComputer = "remoteComputerName" 
strDomain = "DOMAIN" 
Wscript.StdOut.Write "Please enter your user name:"
strUser = Wscript.StdIn.ReadLine 
Set objPassword = CreateObject("ScriptPW.Password")
Wscript.StdOut.Write "Please enter your password:"
strPassword = objPassword.GetPassword()
 
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, _
                                                     "Root\CIMv2", _
                                                     strUser, _
                                                     strPassword, _
                                                     "MS_409", _
                                                     "ntlmdomain:" + strDomain)
Set colSwbemObjectSet = objSWbemServices.ExecQuery("Select * From Win32_Process")
For Each objProcess in colSWbemObjectSet
    Wscript.Echo "Process Name: " & objProcess.Name 
Next

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_Process -Credential FABRIKAM\administrator  `
-ComputerName $Computer

...um auf einen Remotecomputer zuzugreifen?

Geben Sie für VBScript und die Skripterstellungs-API für WMI den Namen des Computers explizit im Moniker oder im Aufruf von SWbemLocator.ConnectServer an. Weitere Informationen finden Sie unter Herstellen einer Remoteverbindung mit WMI mithilfe von VBScript.

Verwenden Sie für PowerShell den Parameter -ComputerName. Weitere Informationen finden Sie unter Herstellen einer Remoteverbindung mit WMI mithilfe von PowerShell.

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer("myRemoteServerName", "root\cimv2")
Set colScheduledJobs = objService.ExecQuery("SELECT * FROM Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

'example 2

strComputer = "myRemoteServerName"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colScheduledJobs = objWMIService.ExecQuery("Select * from Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_logicalDisk -ComputerName $Computer

...um Authentifizierungs- und Identitätswechselebenen festzulegen?

Verwenden Sie für VBScript und die Skripterstellungs-API für WMI die SWbemServices.Security_-Eigenschaft für das zurückgegebene Serverobjekt, oder legen Sie die relevanten Werte im Moniker fest.

Verwenden Sie für PowerShell die Parameter -Authentication bzw. -Impersonation. Weitere Informationen finden Sie unter Schützen von Skripterstellungsclients.

Weitere Informationen finden Sie unter Schützen von Skripterstellungsclients.

' First example
Set Service = GetObject("WinMgmts:{impersonationLevel=impersonate}!Win32_Service=""ALERTER""")

' Second example
Set Locator = CreateObject("WbemScripting.SWbemLocator")
Set Service = Locator.ConnectServer       
service.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate  
Set objinstance = Service.Get("Win32_Service=""ALERTER""")

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_Process -Impersonation Impersonate `
 -Authentication PacketIntegrity -Credential FABRIKAM\administrator -ComputerName $Computer

...um Fehler in WMI zu behandeln?

Für die Skripterstellungs-API für WMI kann der Anbieter ein SWbemLastError-Objekt mit weiteren Informationen zu einem Fehler bereitstellen.

Insbesondere in VBScript wird die Fehlerbehandlung auch mithilfe des nativen Err-Objekts unterstützt. Sie können auch auf das Objekt SWbemLastError zugreifen, wie oben beschrieben. Weitere Informationen finden Sie unter Abrufen eines Fehlercodes.

Für PowerShell können Sie die Standardtechniken zur Fehlerbehandlung in PowerShell verwenden. Weitere Informationen finden Sie unter Einführung in die Fehlerbehandlung in PowerShell.

'using Err
On Error Resume Next
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process.Handle='one'")
Wscript.Echo Err.Number

'using SWbemLastError

On Error Resume Next
Set obj = GetObject("winmgmts:root\cimv2:Win32_Process.Handle='one'")
Set LastError = createobject("wbemscripting.swbemlasterror")
Wscript.Echo "Operation = " & LastError.operation & VBCRLF & "ParameterInfo = " _
            & LastError.ParameterInfo & VBCRLF & "ProviderName = " & LastError.ProviderName