How to Inventory Remote Computers Using PowerShell

Windows Management Instrumentation (WMI) is a management infrastructure built-in to Windows for querying management and operations data. It can be used to query local and remote computers for information like running processes, installed software, BIOS information, and much more.

WMI vs CIM

WMI is based on the Common Information Model (CIM), which is an open-source standard used to access and display information about IT systems.

PowerShell’s Get-WMIObject cmdlet lets you query local and remote computers. But Get-WMIObject is being deprecated. That’s because Microsoft introduced CIM based cmdlets in PowerShell v3.0. There are several different CIM cmdlets available in PowerShell:

  • Get-CimSession
  • New-CimSession
  • Remove-CimSession
  • Get-CimInstance
  • New-CimInstance
  • Remove-CimInstance
  • Set-CimInstance

When using the CIM cmdlets to query remote devices, PowerShell uses WinRM, otherwise known as PowerShell remoting. WinRM uses a secure connection and Active Directory and Kerberos for authentication. So, in this article, I’m going to show you how to use Get-CimInstance to query remote devices so that you can gather inventory information.

Query a remote device using CIM

Before we start, it’s important to understand that Get-CimInstance relies on PowerShell remoting. PowerShell remoting is enabled by default in Windows Server. But if you want to query remote client versions of Windows, like Windows 10, you will need to enable PowerShell remoting on those devices before you can use Get-CimInstance.

A typical Get-CimInstance command in PowerShell looks something like this:

Get-CimInstance -Class Win32_Bios -ComputerName DC1
Image #1 Expand
Figure1 4
How to Inventory Remote Computers Using PowerShell (Image Credit: Russell Smith)

Exploring CIM classes

The -ComputerName parameter specifies the name of the remote computer. In this case, I’m querying a computer named DC1. If you want to query the local device, just omit the -ComputerName parameter. The -Class parameter specifies the class that you want to query.

There are many classes that cover most aspects of the operating system and hardware. The easiest way to determine which class and property you need to query, to get the information you want, is using WMI Explorer. WMI Explorer is a free application that you can download from GitHub here.

Once downloaded, run WmiExplorer.exe. To the right of the Computer field below the File menu, click Connect. This will connect WMI Explorer to the local computer. If you want to explore the available classes on a remote device, enter the computer name in the Computer field and click Connect.

Image #2 Expand
Figure2 3
How to Inventory Remote Computers Using PowerShell (Image Credit: Russell Smith)

 

Under Namespaces, double click ROOT\CIMV2. This will display a list of available classes in the Classes tab to the right. In the Quick Filter field, you can search for a class. For example, you could look for BIOS information, as shown in #IMAGE2. Then double click each available class to display instances. Switching to the Properties tab will show all the available properties.

The information provided by WMI Explorer allows us to fine tune our PowerShell command to get more precise information. For example, the following command displays each running process name along with its kernel time from largest to smallest:

Get-CimInstance -Class Win32_Process -ComputerName DC1 | Select-Object -Property Name,KernelModeTime | Sort-Object KernelModeTime -Descending
Image #3 Expand
Figure3
How to Inventory Remote Computers Using PowerShell (Image Credit: Russell Smith)

 

You can also query more than one remote device simultaneously by specifying additional devices, separated by commas, in the -ComputerName property:

Get-CimInstance -Class Win32_Process -ComputerName DC1,DC2,DC3

Networking configuration

Here are some more examples of information you might want to collect during an inventory. The following commands gather information, like IP address, from all network adapters on a device:

$properties = 'IPAddress', 'IPSubnet', 'DefaultIPGateway', 'MACAddress', 'DHCPEnabled', 'DHCPServer', 'DHCPLeaseObtained', 'DHCPLeaseExpires', 'Description'

Get-CimInstance -Class Win32_NetworkAdapterConfiguration -ComputerName DC1 | Select-Object -Property $properties

Windows Update

In the code below, we use the QuickFixEngineering class to get the Windows Update patches installed on a device. Adding the -Property parameter to Get-CimInstance runs the command more efficiently by pulling only the required properties across the network.

$properties = 'HotFixID', 'Description', 'InstalledOn'

Get-CimInstance -ClassName Win32_QuickFixEngineering -ComputerName DC1 -Property $properties | Select-Object -Property $properties | Sort-Object InstalledOn -Descending

Software

CIM only queries software on a device that was install using Windows Installer. So, that’s quite a big limitation. But nevertheless, here’s how to do it:

$properties = 'Name', 'Version', 'InstallDate'

Get-CimInstance -ClassName Win32_Product -ComputerName DC1 -Property $properties | Select-Object -Property $properties | Sort-Object Name
Image # Expand
Figure4
How to Inventory Remote Computers Using PowerShell (Image Credit: Russell Smith)

WMI Explorer and PowerShell CIM cmdlets are a powerful combination

WMI Explorer and PowerShell CIM cmdlets together provide a powerful tool for organizations looking to query servers for information or perform hardware and configuration inventories. Inventories of client devices might be best served by another solution, like Microsoft Intune, if the devices aren’t connected to the same network as your management servers and PCs. That is because PowerShell remoting isn’t enabled by default in client SKUs and it works best when remote devices connect to the corporate network with a VPN that’s configured for ‘manage out’ scenarios.