Delen via


Hoofdstuk 7 - Werken met WMI

WMI en CIM

Windows PowerShell wordt standaard geleverd met cmdlets voor het werken met andere technologieën, zoals Windows Management Instrumentation (WMI). De WMI-cmdlets zijn afgeschaft en zijn niet beschikbaar in PowerShell 6+, maar worden hier besproken, omdat u deze kunt tegenkomen in oudere scripts die worden uitgevoerd in Windows PowerShell. Voor nieuwe ontwikkeling gebruikt u in plaats daarvan de CIM-cmdlets.

Er bestaan verschillende systeemeigen WMI-cmdlets in PowerShell zonder dat u andere software of modules hoeft te installeren. Get-Command kan worden gebruikt om te bepalen welke WMI-cmdlets er bestaan in Windows PowerShell. De volgende resultaten zijn afkomstig van een Windows 11-systeem met PowerShell versie 5.1. Uw resultaten kunnen verschillen, afhankelijk van de PowerShell-versie die u gebruikt.

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

De CIM-cmdlets (Common Information Model) zijn geïntroduceerd in PowerShell 3.0 en zijn gegroepeerd in een toegewezen module. Als u alle beschikbare CIM-cmdlets wilt weergeven, gebruikt u de Get-Command cmdlet met de moduleparameter , zoals wordt weergegeven in het volgende voorbeeld.

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

Met de CIM-cmdlets kunt u nog steeds met WMI werken, dus niet verwarren wanneer iemand zegt: 'Wanneer ik WMI opvraag met de PowerShell CIM-cmdlets'.

Zoals eerder vermeld, is WMI een afzonderlijke technologie van PowerShell en gebruikt u alleen de CIM-cmdlets voor toegang tot WMI. Mogelijk vindt u een oud VBScript dat WMI Query Language (WQL) gebruikt om een query uit te voeren op WMI, zoals in het volgende voorbeeld.

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

U kunt de WQL-query uit vbScript nemen en gebruiken met de Get-CimInstance cmdlet zonder wijzigingen.

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

Het vorige voorbeeld is niet hoe ik doorgaans WMI bevraag met PowerShell. Maar het werkt en stelt u in staat om eenvoudig bestaande Visual Basic-scripts naar PowerShell te migreren. Bij het schrijven van een one-liner om een query uit te voeren op WMI, gebruik ik de volgende syntaxis.

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

Als u alleen het serienummer wilt, geeft u de uitvoer door Select-Object en geeft u alleen de eigenschap SerialNumber op.

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

Bij het uitvoeren van query's op WMI worden standaard verschillende eigenschappen opgehaald die nooit worden gebruikt achter de schermen. Het maakt niet veel uit wanneer u een query uitvoert op WMI op de lokale computer. Maar als u een query uitvoert op externe computers, is het niet alleen extra verwerkingstijd om die informatie te retourneren, maar ook onnodige informatie om via het netwerk te verzenden. Get-CimInstance heeft een eigenschapsparameter die de opgehaalde informatie beperkt, waardoor de WMI-query efficiënter wordt.

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

De vorige resultaten retourneerden een object. Als u een tekenreeks wilt retourneren, gebruikt u de parameter ExpandProperty .

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

U kunt ook de puntsgewijze syntaxisstijl gebruiken om een tekenreeks te retourneren, waardoor pijpen naar Select-Object overbodig wordt.

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

Query's uitvoeren op externe computers met de CIM-cmdlets

Je moet PowerShell nog steeds uitvoeren als lokale beheerder en domeingebruiker. Wanneer u probeert gegevens op te vragen van een externe computer met behulp van de Get-CimInstance cmdlet, ontvangt u een foutbericht over geweigerde toegang.

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

Veel mensen hebben beveiligingsproblemen met betrekking tot PowerShell, maar u hebt dezelfde machtigingen in PowerShell als in de GUI. Niet meer en niet minder. Het probleem in het vorige voorbeeld is dat de gebruiker met PowerShell geen rechten heeft om WMI-gegevens op te vragen van de DC01-server. U kunt PowerShell opnieuw starten als domeinbeheerder, omdat Get-CimInstance deze geen referentieparameter heeft. Maar dat is geen goed idee omdat alles wat u uitvoert vanuit PowerShell als domeinbeheerder zou worden uitgevoerd. Afhankelijk van de situatie kan dat scenario gevaarlijk zijn vanuit het oogpunt van beveiliging.

Gebruik het principe van minimale bevoegdheden om uw domeinbeheerdersaccount per opdracht uit te breiden met behulp van de parameter Referentie als een opdracht er een heeft. Get-CimInstance heeft geen referentieparameter , dus de oplossing in dit scenario is om eerst een CimSession te maken. Gebruik vervolgens de CimSession in plaats van een computernaam om een query uit te voeren op WMI op de externe computer.

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

De CIM-sessie is opgeslagen in een variabele met de naam $CimSession. U ziet dat u ook de Get-Credential cmdlet tussen haakjes opgeeft, zodat deze eerst wordt uitgevoerd, waarbij u om alternatieve referenties wordt gevraagd voordat u de nieuwe sessie maakt. Ik laat u een andere efficiëntere manier zien om alternatieve referenties verderop in dit hoofdstuk op te geven, maar het is belangrijk om dit basisconcept te begrijpen voordat u het ingewikkelder maakt.

U kunt nu de CIM-sessie die in het vorige voorbeeld is gemaakt, gebruiken met de Get-CimInstance cmdlet om de BIOS-gegevens van WMI op de externe computer op te vragen.

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

Er zijn verschillende andere voordelen voor het gebruik van CIM-sessies in plaats van alleen een computernaam op te geven. Wanneer u meerdere query's uitvoert op dezelfde computer, is het gebruik van een CIM-sessie efficiënter dan het gebruik van de computernaam voor elke query. Als u een CIM-sessie maakt, wordt de verbinding slechts eenmaal ingesteld. Vervolgens gebruiken meerdere query's dezelfde sessie om informatie op te halen. Als u de computernaam gebruikt, moeten de cmdlets de verbinding met elke query opzetten en verbreken.

De Get-CimInstance cmdlet maakt standaard gebruik van het WSMan-protocol, wat betekent dat de externe computer PowerShell versie 3.0 of hoger nodig heeft om verbinding te maken. Het is eigenlijk niet de PowerShell-versie die belangrijk is, het is de stackversie. De stackversie kan worden bepaald met behulp van de Test-WSMan cmdlet. Het moet versie 3.0 zijn, die u vindt met PowerShell versie 3.0 en hoger.

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

De oudere WMI-cmdlets gebruiken het DCOM-protocol, dat compatibel is met oudere versies van Windows. De firewall blokkeert echter doorgaans DCOM in nieuwere versies van Windows. Met de New-CimSessionOption cmdlet kunt u een DCOM-protocolverbinding maken voor gebruik met New-CimSession. Met deze optie kan de Get-CimInstance cmdlet communiceren met versies van Windows zo oud als Windows Server 2000. Deze mogelijkheid betekent ook dat PowerShell niet vereist is op de externe computer wanneer u de Get-CimInstance cmdlet gebruikt met een CimSession die is geconfigureerd voor het gebruik van het DCOM-protocol.

Maak de DCOM-protocoloptie met behulp van de New-CimSessionOption cmdlet en sla deze op in een variabele.

$DCOM = New-CimSessionOption -Protocol Dcom

Voor efficiëntie kunt u uw domeinbeheerder of verhoogde referenties opslaan in een variabele, zodat u deze niet voortdurend hoeft in te voeren voor elke opdracht.

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

Ik heb een server met de naam SQL03 waarop Windows Server 2008 (niet-R2) wordt uitgevoerd. Het is het nieuwste Windows Server-besturingssysteem waarop PowerShell niet standaard is geïnstalleerd.

Maak een CimSession naar SQL03 met behulp van het DCOM-protocol.

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

U ziet in de vorige opdracht dat u de variabele met de naam $Cred opgeeft als de waarde voor de parameter Referentie in plaats van uw referenties handmatig opnieuw in te voeren.

De uitvoer van de query is hetzelfde, ongeacht het onderliggende protocol.

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

De Get-CimSession cmdlet wordt gebruikt om te zien welke CimSessions momenteel zijn verbonden en welke protocollen ze gebruiken.

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

Haal de eerder gemaakte CimSessions op en sla deze op in een variabele met de naam $CimSession.

$CimSession = Get-CimSession

Voer een query uit op beide computers met één opdracht, één met behulp van het WSMan-protocol en de andere met 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

Een van mijn blogartikelen over WMI- en CIM-cmdlets bevat een PowerShell-functie die automatisch detecteert of WSMan of DCOM moet worden gebruikt en vervolgens de juiste CIM-sessie voor u instelt. Zie de PowerShell-functie voor het maken van CimSessions voor externe computers met terugval naar Dcom voor meer informatie.

Wanneer u klaar bent met de CIM-sessies, verwijdert u deze met de Remove-CimSession cmdlet. Als u alle CIM-sessies wilt verwijderen, sluist Get-CimSession u naar Remove-CimSession.

Get-CimSession | Remove-CimSession

Samenvatting

In dit hoofdstuk hebt u geleerd hoe u PowerShell kunt gebruiken om met WMI te werken op lokale en externe computers. U hebt ook geleerd hoe u de CIM-cmdlets gebruikt om met externe computers te werken met behulp van de WSMan- en DCOM-protocollen.

Recensie

  1. Wat is het verschil in de WMI- en CIM-cmdlets?
  2. Welk protocol gebruikt de Get-CimInstance cmdlet standaard?
  3. Wat zijn enkele voordelen van het gebruik van een CIM-sessie in plaats van een computernaam op te geven met Get-CimInstance?
  4. Hoe geeft u een ander alternatief protocol op dan de standaardprotocol voor gebruik met Get-CimInstance?
  5. Hoe sluit of verwijdert u CIM-sessies?

Verwijzingen