Freigeben über


Kapitel 7 – Arbeiten mit WMI

WMI und CIM

Windows PowerShell wird standardmäßig mit Cmdlets für die Arbeit mit anderen Technologien wie der Windows-Verwaltungsinstrumentation (Windows Management Instrumentation, WMI) ausgeliefert. Die WMI-Cmdlets sind veraltet und sind in PowerShell 6+ nicht verfügbar, werden aber hier behandelt, da sie in älteren Skripts auftreten können, die unter Windows PowerShell ausgeführt werden. Verwenden Sie für die neue Entwicklung stattdessen die CIM-Cmdlets.

In PowerShell sind mehrere systemeigene WMI-Cmdlets vorhanden, ohne dass Sie andere Software oder Module installieren müssen. Get-Command kann verwendet werden, um zu bestimmen, welche WMI-Cmdlets in Windows PowerShell vorhanden sind. Die folgenden Ergebnisse stammen aus einem Windows 11-System mit PowerShell, Version 5.1. Ihre Ergebnisse können sich je nach der PowerShell-Version unterscheiden, die Sie ausführen.

Get-Command -Noun WMI*
CommandType     Name                                               Version
-----------     ----                                               -------
Cmdlet          Get-WmiObject                                      3.1.0.0
Cmdlet          Invoke-WmiMethod                                   3.1.0.0
Cmdlet          Register-WmiEvent                                  3.1.0.0
Cmdlet          Remove-WmiObject                                   3.1.0.0
Cmdlet          Set-WmiInstance                                    3.1.0.0

Die Common Information Model (CIM)-Cmdlets wurden in PowerShell 3.0 eingeführt und sind in einem dedizierten Modul gruppiert. Um alle verfügbaren CIM-Cmdlets aufzulisten, verwenden Sie das Get-Command Cmdlet mit dem Parameter "Module ", wie im folgenden Beispiel gezeigt.

Get-Command -Module CimCmdlets
CommandType     Name                                               Version
-----------     ----                                               -------
Cmdlet          Export-BinaryMiLog                                 1.0.0.0
Cmdlet          Get-CimAssociatedInstance                          1.0.0.0
Cmdlet          Get-CimClass                                       1.0.0.0
Cmdlet          Get-CimInstance                                    1.0.0.0
Cmdlet          Get-CimSession                                     1.0.0.0
Cmdlet          Import-BinaryMiLog                                 1.0.0.0
Cmdlet          Invoke-CimMethod                                   1.0.0.0
Cmdlet          New-CimInstance                                    1.0.0.0
Cmdlet          New-CimSession                                     1.0.0.0
Cmdlet          New-CimSessionOption                               1.0.0.0
Cmdlet          Register-CimIndicationEvent                        1.0.0.0
Cmdlet          Remove-CimInstance                                 1.0.0.0
Cmdlet          Remove-CimSession                                  1.0.0.0
Cmdlet          Set-CimInstance                                    1.0.0.0

Die CIM-Cmdlets ermöglichen es Ihnen weiterhin, mit WMI zu arbeiten. Lassen Sie sich daher nicht verwechseln, wenn jemand sagt: "Wenn ich WMI mit den PowerShell CIM-Cmdlets abfrage".

Wie bereits erwähnt, ist WMI eine separate Technologie von PowerShell, und Sie verwenden nur die CIM-Cmdlets für den Zugriff auf WMI. Möglicherweise finden Sie ein altes VBScript, das WMI-Abfragesprache (WQL) zum Abfragen von WMI verwendet, z. B. im folgenden Beispiel.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\CIMV2")

Set colBIOS = objWMIService.ExecQuery _
    ("Select * from Win32_BIOS")

For each objBIOS in colBIOS
    Wscript.Echo "Manufacturer: " & objBIOS.Manufacturer
    Wscript.Echo "Name: " & objBIOS.Name
    Wscript.Echo "Serial Number: " & objBIOS.SerialNumber
    Wscript.Echo "SMBIOS Version: " & objBIOS.SMBIOSBIOSVersion
    Wscript.Echo "Version: " & objBIOS.Version
Next

Sie können die WQL-Abfrage aus dem VBScript verwenden und ohne Änderungen mit dem Get-CimInstance Cmdlet verwenden.

Get-CimInstance -Query 'Select * from Win32_BIOS'
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 3810-1995-1654-4615-2295-2755-89
Version           : VRTUAL - 4001628

Im vorherigen Beispiel wird nicht gezeigt, wie ich WMI mit PowerShell in der Regel abfrage. Es funktioniert jedoch und ermöglicht es Ihnen, vorhandene Visual Basic-Skripts auf einfache Weise zu PowerShell zu migrieren. Beim Schreiben eines Einzeiligens zum Abfragen von WMI verwende ich die folgende Syntax.

Get-CimInstance -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 3810-1995-1654-4615-2295-2755-89
Version           : VRTUAL - 4001628

Wenn Sie nur die Seriennummer möchten, leiten Sie die Ausgabe an Select-Object weiter und spezifizieren Sie nur die SerialNumber-Eigenschaft.

Get-CimInstance -ClassName Win32_BIOS |
    Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89

Standardmäßig werden beim Abfragen von WMI mehrere eigenschaften, die nie verwendet werden, hinter den Kulissen abgerufen. Beim Abfragen von WMI auf dem lokalen Computer spielt es keine Rolle. Sobald Sie jedoch beginnen, Remote-Computer abzufragen, bedeutet das nicht nur eine längere Verarbeitungszeit, um diese Informationen zurückzugeben, sondern auch mehr unnötige Informationen, die über das Netzwerk gesendet werden. Get-CimInstance verfügt über einen Property-Parameter , der die abgerufenen Informationen begrenzt, wodurch die WMI-Abfrage effizienter wird.

Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
    Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89

Die vorherigen Ergebnisse haben ein Objekt zurückgegeben. Verwenden Sie den ExpandProperty-Parameter , um eine Zeichenfolge zurückzugeben.

Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
    Select-Object -ExpandProperty SerialNumber
3810-1995-1654-4615-2295-2755-89

Sie können auch die Punkt-Syntax verwenden, um eine Zeichenfolge zurückzugeben, ohne dass eine Weiterleitung an Select-Object erforderlich ist.

(Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber).SerialNumber
3810-1995-1654-4615-2295-2755-89

Abfragen von Remotecomputern mit den CIM-Cmdlets

Sie sollten PowerShell weiterhin als lokaler Administrator und Domänenbenutzer ausführen. Wenn Sie versuchen, Informationen von einem Remotecomputer mithilfe des Get-CimInstance Cmdlets abzufragen, erhalten Sie eine Fehlermeldung mit dem Zugriff verweigert.

Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
Get-CimInstance : Access is denied.
At line:1 char:1
+ Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (root\cimv2:Win32_BIOS:Stri
   ng) [Get-CimInstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infra
   structure.CimCmdlets.GetCimInstanceCommand
    + PSComputerName        : dc01

Viele Personen haben Sicherheitsbedenken in Bezug auf PowerShell, aber Sie verfügen über die gleichen Berechtigungen in PowerShell wie in der GUI. Nicht mehr und nicht weniger. Das Problem im vorherigen Beispiel besteht darin, dass der Benutzer, der PowerShell ausführt, keine Rechte zum Abfragen von WMI-Informationen vom DC01-Server hat. Sie können PowerShell als Domänenadministrator neu starten, da Get-CimInstance kein Parameter für Anmeldeinformationen enthalten ist. Das ist aber keine gute Idee, da alles, was Sie über PowerShell ausführen, als Domänenadministrator ausgeführt wird. Je nach Situation könnte dieses Szenario aus Sicherheitsgründen gefährlich sein.

Verwenden Sie das Prinzip der geringsten Rechte, indem Sie für jeden Befehl Ihr Domänen-Admin-Konto mithilfe des Parameters "Credential" anheben, wenn dieser über einen verfügt. Get-CimInstance verfügt nicht über einen Credential-Parameter , daher besteht die Lösung in diesem Szenario darin, zuerst eine CimSession zu erstellen. Verwenden Sie dann die CimSession anstelle eines Computernamens, um WMI auf dem Remotecomputer abzufragen.

$CimSession = New-CimSession -ComputerName dc01 -Credential (Get-Credential)
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential

Die CIM-Sitzung wurde in einer Variablen mit dem Namen $CimSessiongespeichert. Beachten Sie, dass Sie das Get-Credential Cmdlet auch in Klammern angeben, sodass es zuerst ausgeführt wird, indem Sie vor dem Erstellen der neuen Sitzung zur Eingabe alternativer Anmeldeinformationen aufgefordert werden. Ich zeige Ihnen eine weitere effizientere Möglichkeit, alternative Anmeldeinformationen später in diesem Kapitel anzugeben, aber es ist wichtig, dieses grundlegende Konzept zu verstehen, bevor Sie es komplizierter machen.

Sie können nun die im vorherigen Beispiel erstellte CIM-Sitzung mit dem Get-CimInstance Cmdlet verwenden, um die BIOS-Informationen von WMI auf dem Remotecomputer abzufragen.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 0986-6980-3916-0512-6608-8243-13
Version           : VRTUAL - 4001628
PSComputerName    : dc01

Es gibt mehrere weitere Vorteile für die Verwendung von CIM-Sitzungen, anstatt nur einen Computernamen anzugeben. Wenn Sie mehrere Abfragen auf demselben Computer ausführen, ist die Verwendung einer CIM-Sitzung effizienter als die Verwendung des Computernamens für jede Abfrage. Beim Erstellen einer CIM-Sitzung wird die Verbindung nur einmal eingerichtet. Anschließend verwenden mehrere Abfragen dieselbe Sitzung, um Informationen abzurufen. Die Verwendung des Computernamens erfordert, dass die Cmdlets die Verbindung mit jeder Abfrage einrichten und abreißen.

Das Get-CimInstance Cmdlet verwendet standardmäßig das WSMan-Protokoll, was bedeutet, dass der Remotecomputer PowerShell Version 3.0 oder höher benötigt, um eine Verbindung herzustellen. Es ist eigentlich nicht die PowerShell-Version, die wichtig ist, sondern die Stapelversion. Die Stapelversion kann mithilfe des Test-WSMan Cmdlets bestimmt werden. Es muss Version 3.0 sein, die Sie mit PowerShell, Version 3.0 und höher, finden.

Test-WSMan -ComputerName dc01
wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentit
                  y.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0

Die älteren WMI-Cmdlets verwenden das DCOM-Protokoll, das mit älteren Versionen von Windows kompatibel ist. Die Firewall blockiert DCOM jedoch in neueren Versionen von Windows in der Regel. Mit dem New-CimSessionOption cmdlet können Sie eine DCOM-Protokollverbindung für die Verwendung mit New-CimSession erstellen. Mit dieser Option kann das Get-CimInstance Cmdlet mit Windows-Versionen wie Windows Server 2000 kommunizieren. Dies bedeutet auch, dass PowerShell nicht auf dem Remotecomputer erforderlich ist, wenn das Get-CimInstance Cmdlet mit einer CimSession verwendet wird, die für die Verwendung des DCOM-Protokolls konfiguriert ist.

Erstellen Sie die DCOM-Protokolloption mithilfe des New-CimSessionOption Cmdlets, und speichern Sie sie in einer Variablen.

$DCOM = New-CimSessionOption -Protocol Dcom

Aus Effizienzgründen können Sie Ihren Domänenadministrator oder Anmeldeinformationen mit erhöhten Rechten in einer Variablen speichern, sodass Sie sie für jeden Befehl nicht ständig eingeben müssen.

$Cred = Get-Credential
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential

Ich habe einen Server namens SQL03, der Windows Server 2008 (nicht R2) ausführt. Es ist das neueste Windows Server-Betriebssystem, das PowerShell nicht standardmäßig installiert hat.

Erstellen Sie eine CimSession zu SQL03 mithilfe des DCOM-Protokolls.

$CimSession = New-CimSession -ComputerName sql03 -SessionOption $DCOM -Credential $Cred

Beachten Sie im vorherigen Befehl, dass Sie die Variable angeben, die als Wert für den Parameter "$Cred" benannt ist, anstatt Ihre Anmeldeinformationen erneut manuell einzugeben.

Die Ausgabe der Abfrage ist unabhängig vom zugrunde liegenden Protokoll identisch.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 7237-7483-8873-8926-7271-5004-86
Version           : VRTUAL - 4001628
PSComputerName    : sql03

Das Get-CimSession Cmdlet wird verwendet, um zu sehen, welche CimSessions derzeit verbunden sind und welche Protokolle sie verwenden.

Get-CimSession
Id           : 1
Name         : CimSession1
InstanceId   : 80742787-e38e-41b1-a7d7-fa1369cf1402
ComputerName : dc01
Protocol     : WSMAN

Id           : 2
Name         : CimSession2
InstanceId   : 8fcabd81-43cf-4682-bd53-ccce1e24aecb
ComputerName : sql03
Protocol     : DCOM

Dient zum Abrufen und Speichern der zuvor erstellten CimSessions in einer Variablen mit dem Namen $CimSession.

$CimSession = Get-CimSession

Fragen Sie beide Computer mit einem Befehl ab, dabei nutzt einer das WSMan-Protokoll und der andere DCOM.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 0986-6980-3916-0512-6608-8243-13
Version           : VRTUAL - 4001628
PSComputerName    : dc01

SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 7237-7483-8873-8926-7271-5004-86
Version           : VRTUAL - 4001628
PSComputerName    : sql03

Einer meiner Blogartikel über WMI- und CIM-Cmdlets stellt eine PowerShell-Funktion vor, die automatisch erkennt, ob WSMan oder DCOM verwendet werden soll, und richtet dann die entsprechende CIM-Sitzung für Sie ein. Weitere Informationen finden Sie unter PowerShell-Funktion zum Erstellen von CimSessions zu Remote-Computern mit Rückgriff auf Dcom.

Wenn Sie mit den CIM-Sitzungen fertig sind, entfernen Sie sie mit dem Remove-CimSession Cmdlet. Um alle CIM-Sitzungen zu entfernen, leiten Sie Get-CimSession zu Remove-CimSession.

Get-CimSession | Remove-CimSession

Zusammenfassung

In diesem Kapitel haben Sie erfahren, wie Sie PowerShell für die Arbeit mit WMI auf lokalen und Remotecomputern verwenden. Außerdem haben Sie erfahren, wie Sie die CIM-Cmdlets verwenden, um mit Remotecomputern mit den WSMan- und DCOM-Protokollen zu arbeiten.

Rezension

  1. Was ist der Unterschied in den WMI- und CIM-Cmdlets?
  2. Welches Protokoll verwendet das Get-CimInstance Cmdlet standardmäßig?
  3. Was sind einige Vorteile der Verwendung einer CIM-Sitzung anstelle der Angabe eines Computernamens mit Get-CimInstance?
  4. Wie definieren Sie ein alternatives Protokoll als das Standardprotokoll zur Verwendung mit Get-CimInstance?
  5. Wie schließen oder entfernen Sie CIM-Sitzungen?

Verweise