Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit focus mode

Chapter 7 - Working with WMI

  • 2025-03-24
Feedback

In this article

WMI and CIM

Windows PowerShell ships by default with cmdlets for working with other technologies, such asWindows Management Instrumentation (WMI). The WMI cmdlets are deprecated and aren't available inPowerShell 6+, but are covered here as you might encounter them in older scripts running on WindowsPowerShell. For new development, use the CIM cmdlets instead.

Several native WMI cmdlets exist in PowerShell without you having to install any other software ormodules.Get-Command can be used to determine what WMI cmdlets exist in Windows PowerShell. Thefollowing results are from a Windows 11 system running PowerShell version 5.1. Your results mightdiffer depending on the PowerShell version you're running.

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

The Common Information Model (CIM) cmdlets were introduced in PowerShell 3.0 and are grouped withina dedicated module. To list all available CIM cmdlets, use theGet-Command cmdlet with theModule parameter, as shown in the following example.

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

The CIM cmdlets still allow you to work with WMI, so don't be confused when someone states:"When Iquery WMI with the PowerShell CIM cmdlets".

As previously mentioned, WMI is a separate technology from PowerShell, and you're just using the CIMcmdlets to access WMI. You might find an old VBScript that uses WMI Query Language (WQL) to queryWMI, such as in the following example.

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.VersionNext

You can take the WQL query from the VBScript and use it with theGet-CimInstance cmdlet withoutany modifications.

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

The previous example isn't how I typically query WMI with PowerShell. But it works and allows you toeasily migrate existing Visual Basic scripts to PowerShell. When writing a one-liner to query WMI, Iuse the following syntax.

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

If you only want the serial number, pipe the output toSelect-Object and specify only theSerialNumber property.

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

By default, when querying WMI, several properties that are never used are retrieved behind thescenes. It doesn't matter much when querying WMI on the local computer. But once you start queryingremote computers, it's not only extra processing time to return that information but also moreunnecessary information to send across the network.Get-CimInstance has aProperty parameterthat limits the information retrieved, making the WMI query more efficient.

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

The previous results returned an object. To return a string, use theExpandProperty parameter.

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

You could also use the dotted syntax style to return a string, eliminating the need to pipe toSelect-Object.

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

Query Remote Computers with the CIM cmdlets

You should still be running PowerShell as a local admin and domain user. When you try to queryinformation from a remote computer using theGet-CimInstance cmdlet, you receive an access deniederror message.

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

Many people have security concerns regarding PowerShell, but you have the same permissions inPowerShell as in the GUI. No more and no less. The problem in the previous example is that the userrunning PowerShell doesn't have rights to query WMI information from the DC01 server. You couldrelaunch PowerShell as a domain administrator sinceGet-CimInstance doesn't have aCredentialparameter. But that isn't a good idea because anything you run from PowerShell would run as a domainadmin. Depending on the situation, that scenario could be dangerous from a security standpoint.

Using the principle of least privilege, elevate to your domain admin account on a per-command basisusing theCredential parameter if a command has one.Get-CimInstance doesn't have aCredential parameter, so the solution in this scenario is to create aCimSession first.Then, use theCimSession instead of a computer name to query WMI on the remote computer.

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

The CIM session was stored in a variable named$CimSession. Notice that you also specify theGet-Credential cmdlet in parentheses so that it executes first, prompting for alternatecredentials, before creating the new session. I show you another more efficient way to specifyalternate credentials later in this chapter, but it's important to understand this basic conceptbefore making it more complicated.

You can now use the CIM session created in the previous example with theGet-CimInstance cmdlet toquery the BIOS information from WMI on the remote computer.

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

There are several other benefits to using CIM sessions instead of just specifying a computer name.When you run multiple queries to the same computer, using a CIM session is more efficient than usingthe computer name for each query. Creating a CIM session only sets up the connection once. Then,multiple queries use that same session to retrieve information. Using the computer name requires thecmdlets to set up and tear down the connection with each query.

TheGet-CimInstance cmdlet uses the WSMan protocol by default, which means the remote computerneeds PowerShell version 3.0 or higher to connect. It's actually not the PowerShell version thatmatters, it's the stack version. The stack version can be determined using theTest-WSMan cmdlet.It needs to be version 3.0, which you find with PowerShell version 3.0 and higher.

Test-WSMan -ComputerName dc01
wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentit                  y.xsdProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsdProductVendor   : Microsoft CorporationProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0

The older WMI cmdlets use the DCOM protocol, which is compatible with older versions of Windows.However, the firewall typically blocks DCOM on newer versions of Windows. TheNew-CimSessionOptioncmdlet allows you to create a DCOM protocol connection for use withNew-CimSession. This optionallows theGet-CimInstance cmdlet to communicate with versions of Windows as old as Windows Server2000. This ability also means that PowerShell isn't required on the remote computer when using theGet-CimInstance cmdlet with a CimSession configured to use the DCOM protocol.

Create the DCOM protocol option using theNew-CimSessionOption cmdlet and store it in a variable.

$DCOM = New-CimSessionOption -Protocol Dcom

For efficiency, you can store your domain administrator or elevated credentials in a variable so youdon't have to constantly enter them for each command.

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

I have a server named SQL03 that runs Windows Server 2008 (non-R2). It's the newest Windows Serveroperating system that doesn't have PowerShell installed by default.

Create aCimSession to SQL03 using the DCOM protocol.

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

Notice in the previous command that you specify the variable named$Cred as the value for theCredential parameter instead of manually entering your credentials again.

The output of the query is the same regardless of the underlying protocol.

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

TheGet-CimSession cmdlet is used to see what CimSessions are currently connected and whatprotocols they use.

Get-CimSession
Id           : 1Name         : CimSession1InstanceId   : 80742787-e38e-41b1-a7d7-fa1369cf1402ComputerName : dc01Protocol     : WSMANId           : 2Name         : CimSession2InstanceId   : 8fcabd81-43cf-4682-bd53-ccce1e24aecbComputerName : sql03Protocol     : DCOM

Retrieve and store the previously created CimSessions in a variable named$CimSession.

$CimSession = Get-CimSession

Query both computers with one command, one using the WSMan protocol and the other with DCOM.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006Manufacturer      : American Megatrends Inc.Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHzSerialNumber      : 0986-6980-3916-0512-6608-8243-13Version           : VRTUAL - 4001628PSComputerName    : dc01SMBIOSBIOSVersion : 090006Manufacturer      : American Megatrends Inc.Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHzSerialNumber      : 7237-7483-8873-8926-7271-5004-86Version           : VRTUAL - 4001628PSComputerName    : sql03

One of my blog articles on WMI and CIM cmdlets features a PowerShell function that automaticallydetects whether to use WSMan or DCOM and then sets up the appropriate CIM session for you. For moreinformation, seePowerShell Function to Create CimSessions to Remote Computers with Fallback to Dcom.

When you finish with the CIM sessions, remove them with theRemove-CimSession cmdlet. To removeall CIM sessions, pipeGet-CimSession toRemove-CimSession.

Get-CimSession | Remove-CimSession

Summary

In this chapter, you learned about using PowerShell to work with WMI on local and remote computers.You also learned how to use the CIM cmdlets to work with remote computers using the WSMan and DCOMprotocols.

Review

  1. What's the difference in the WMI and CIM cmdlets?
  2. By default, what protocol does theGet-CimInstance cmdlet use?
  3. What are some benefits of using a CIM session instead of specifying a computer name withGet-CimInstance?
  4. How do you specify an alternate protocol other than the default one for use withGet-CimInstance?
  5. How do you close or remove CIM sessions?

References

Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, seeour contributor guide.

Feedback

Was this page helpful?

YesNo

In this article

Was this page helpful?

YesNo