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:
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.
Say Goodbye to Traditional PC Lifecycle Management
Traditional IT tools, including Microsoft SCCM, Ghost Solution Suite, and KACE, often require considerable custom configurations by T3 technicians (an expensive and often elusive IT resource) to enable management of a hybrid onsite + remote workforce. In many cases, even with the best resources, organizations are finding that these on-premise tools simply cannot support remote endpoints consistently and reliably due to infrastructure limitations.
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
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.
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
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
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
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
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
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.