PowerShell WMI and CIM

WMI (Windows Management Instrumentation) and CIM (Common Information Model) are two ways to query deep system information in Windows — hardware details, running services, installed software, disk partitions, network adapters, and much more. PowerShell gives you cmdlets to access all of this data with a single line of code.

WMI vs CIM — What Is the Difference?

+----------------------+        +----------------------+
|        WMI           |        |        CIM           |
|  (Old approach)      |        |  (Modern approach)   |
|                      |        |                      |
|  Get-WmiObject       |        |  Get-CimInstance     |
|  Windows only        |        |  Cross-platform      |
|  Uses DCOM protocol  |        |  Uses WS-Man/WSMan   |
|  PowerShell 2-5.1    |        |  PowerShell 3+       |
|  Deprecated in PS7   |        |  Recommended now     |
+----------------------+        +----------------------+
Both access the same underlying data. CIM is the modern replacement. New scripts should always use CIM cmdlets.

Understanding WMI/CIM Classes

WMI and CIM organize system data into classes. Each class represents a category of system information.
Win32_ComputerSystem  → Computer name, RAM, manufacturer
Win32_OperatingSystem → OS name, version, install date
Win32_Processor       → CPU model, cores, clock speed
Win32_LogicalDisk     → Drive letters, size, free space
Win32_NetworkAdapter  → Network card info
Win32_Service         → Windows services
Win32_Process         → Running processes
Win32_BIOS            → BIOS version and date
Win32_PhysicalMemory  → RAM sticks, capacity, speed

Basic CIM Queries

Get Computer Information

# Computer name, manufacturer, model, total RAM
Get-CimInstance -ClassName Win32_ComputerSystem |
    Select-Object Name, Manufacturer, Model,
        @{Label="RAM (GB)"; Expression={[math]::Round($_.TotalPhysicalMemory / 1GB, 2)}}

Sample Output

Name        Manufacturer    Model              RAM (GB)
----        ------------    -----              --------
PC-ALICE    Dell Inc.       Inspiron 5590      15.84

Get Operating System Details

Get-CimInstance -ClassName Win32_OperatingSystem |
    Select-Object Caption, Version, BuildNumber, OSArchitecture, LastBootUpTime

Get CPU Information

Get-CimInstance -ClassName Win32_Processor |
    Select-Object Name, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed

Get Disk Space

Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" |
    Select-Object DeviceID,
        @{Label="Size (GB)";  Expression={[math]::Round($_.Size / 1GB, 1)}},
        @{Label="Free (GB)";  Expression={[math]::Round($_.FreeSpace / 1GB, 1)}},
        @{Label="Used %";     Expression={[math]::Round((($_.Size - $_.FreeSpace) / $_.Size) * 100, 1)}}

Sample Output

DeviceID  Size (GB)  Free (GB)  Used %
--------  ---------  ---------  ------
C:        237.5      85.2       64.1
D:        465.8      310.4      33.4

Filtering CIM Results

Use the -Filter parameter to narrow results — it runs the filter on the remote system before sending data, making queries faster.
# Get only stopped services
Get-CimInstance -ClassName Win32_Service -Filter "State='Stopped'"

# Get services set to start automatically
Get-CimInstance -ClassName Win32_Service -Filter "StartMode='Auto'"

# Get a specific process by name
Get-CimInstance -ClassName Win32_Process -Filter "Name='chrome.exe'"

Diagram: How CIM Query Works

PowerShell Script
      |
      |  Get-CimInstance -ClassName Win32_LogicalDisk
      v
+---------------------+
|   CIM Infrastructure|
|   (WMI Provider)    |
+---------------------+
      |
      |  Queries Windows WMI Repository
      v
+---------------------+
|   Windows OS        |
|   (Hardware/OS data)|
+---------------------+
      |
      |  Returns objects
      v
PowerShell — receives structured data ready to filter/format

List All Available CIM Classes

# List all Win32 classes
Get-CimClass -Namespace root/cimv2 | Where-Object CimClassName -like "Win32_*"

# Search for disk-related classes
Get-CimClass -Namespace root/cimv2 | Where-Object CimClassName -like "*Disk*"

Getting BIOS and Hardware Info

# BIOS version and release date
Get-CimInstance -ClassName Win32_BIOS |
    Select-Object Manufacturer, Name, Version, ReleaseDate

# Physical memory modules (RAM sticks)
Get-CimInstance -ClassName Win32_PhysicalMemory |
    Select-Object BankLabel,
        @{Label="Capacity (GB)"; Expression={$_.Capacity / 1GB}},
        Speed

# Network adapters
Get-CimInstance -ClassName Win32_NetworkAdapter -Filter "PhysicalAdapter=True" |
    Select-Object Name, MACAddress, Speed

Getting Installed Software

# List all installed programs (from Win32_Product — slow but thorough)
Get-CimInstance -ClassName Win32_Product |
    Select-Object Name, Version, Vendor |
    Sort-Object Name |
    Format-Table -AutoSize

# Faster alternative using registry
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" |
    Select-Object DisplayName, DisplayVersion, Publisher |
    Sort-Object DisplayName |
    Format-Table -AutoSize

Running CIM Queries on Remote Computers

CIM uses the modern WS-Management protocol, making remote queries safe and firewall-friendly.
# Query a single remote computer
Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName "SERVER01"

# Query multiple computers at once
$servers = @("SERVER01", "SERVER02", "SERVER03")
Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName $servers -Filter "DriveType=3"

# Use a CIM session for repeated queries (more efficient)
$session = New-CimSession -ComputerName "SERVER01"
Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $session
Get-CimInstance -ClassName Win32_Processor -CimSession $session
Remove-CimSession -CimSession $session

CIM vs WMI Cmdlet Comparison

TaskOld WMI (avoid)Modern CIM (use this)
Query a classGet-WmiObject Win32_DiskGet-CimInstance Win32_Disk
Remote queryGet-WmiObject -ComputerNameGet-CimInstance -ComputerName
List classesGet-WmiObject -ListGet-CimClass
Invoke a methodInvoke-WmiMethodInvoke-CimMethod

Real-World Example: System Health Report

function Get-SystemHealth {
    $os   = Get-CimInstance Win32_OperatingSystem
    $cpu  = Get-CimInstance Win32_Processor
    $disk = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'"
    $ram  = Get-CimInstance Win32_ComputerSystem

    $freeRamGB  = [math]::Round($os.FreePhysicalMemory / 1MB, 2)
    $totalRamGB = [math]::Round($ram.TotalPhysicalMemory / 1GB, 2)
    $freeDiskGB = [math]::Round($disk.FreeSpace / 1GB, 1)
    $totalDiskGB= [math]::Round($disk.Size / 1GB, 1)

    Write-Output "=== System Health Report ==="
    Write-Output "Computer : $($ram.Name)"
    Write-Output "OS       : $($os.Caption) ($($os.OSArchitecture))"
    Write-Output "CPU      : $($cpu.Name)"
    Write-Output "RAM      : $freeRamGB GB free of $totalRamGB GB"
    Write-Output "Disk C:  : $freeDiskGB GB free of $totalDiskGB GB"
    Write-Output "Uptime   : $((Get-Date) - $os.LastBootUpTime | Select-Object -ExpandProperty Days) day(s)"
}

Get-SystemHealth

Sample Output

=== System Health Report ===
Computer : PC-ALICE
OS       : Microsoft Windows 11 Pro (64-bit)
CPU      : Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
RAM      : 6.42 GB free of 15.84 GB
Disk C:  : 85.2 GB free of 237.5 GB
Uptime   : 3 day(s)

Summary

WMI and CIM provide access to deep hardware and OS information that regular PowerShell cmdlets cannot reach. CIM is the modern, recommended approach — faster, cross-platform, and firewall-friendly. Use Get-CimInstance with the right class name to pull CPU, disk, RAM, BIOS, network, and software data from local or remote computers. The data returns as structured objects, ready for filtering, formatting, and reporting.

Leave a Comment

Your email address will not be published. Required fields are marked *