The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Discover CIM classes | Get-CimClass -Namespace 'root/cimv2' -ClassName 'Win32_*' |
Select-Object -First 25 CimClassName | View examples |
| Inspect class properties | (Get-CimClass -ClassName 'Win32_ComputerSystem').CimClassProperties |
Select-Object Name, CimType | View examples |
| Inventory Windows version | Get-CimInstance -ClassName 'Win32_OperatingSystem' |
Select-Object Caption, Version, BuildNumber, OSArchitecture, LastBootUpTime | View examples |
| Inventory computer identity | Get-CimInstance -ClassName 'Win32_ComputerSystem' |
Select-Object Manufacturer, Model, Name, Domain, TotalPhysicalMemory | View examples |
| Inventory firmware identity | Get-CimInstance -ClassName 'Win32_BIOS' |
Select-Object Manufacturer, SMBIOSBIOSVersion, ReleaseDate, SerialNumber | View examples |
| Inventory processors | Get-CimInstance -ClassName 'Win32_Processor' |
Select-Object DeviceID, Name, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed | View examples |
| Inventory memory modules | Get-CimInstance -ClassName 'Win32_PhysicalMemory' |
Select-Object DeviceLocator, Capacity, Speed, Manufacturer, PartNumber | View examples |
| Inventory physical disks | Get-CimInstance -ClassName 'Win32_DiskDrive' |
Select-Object Index, Model, SerialNumber, InterfaceType, Size, Status | View examples |
| Inventory fixed volumes | Get-CimInstance -ClassName 'Win32_LogicalDisk' -Filter 'DriveType = 3' |
Select-Object DeviceID, VolumeName, FileSystem, Size, FreeSpace | View examples |
| Inventory enabled IP adapters | Get-CimInstance -ClassName 'Win32_NetworkAdapterConfiguration' -Filter 'IPEnabled = TRUE' |
Select-Object Description, MACAddress, IPAddress, DefaultIPGateway | View examples |
| Inventory signed drivers | Get-CimInstance -ClassName 'Win32_PnPSignedDriver' |
Select-Object DeviceName, Manufacturer, DriverVersion, DriverDate, InfName | View examples |
| Run a WQL projection | Get-CimInstance -Query `
'SELECT DeviceID,Size,FreeSpace FROM Win32_LogicalDisk WHERE DriveType=3' | View examples |
| Create a Kerberos CIM session | New-CimSession -ComputerName 'server01.contoso.com' `
-Authentication Kerberos | View examples |
| Query through a CIM session | Get-CimInstance -CimSession $session -ClassName 'Win32_OperatingSystem' |
Select-Object CSName, Caption, Version, LastBootUpTime | View examples |
| Close a CIM session | Remove-CimSession -CimSession $session | View examples |
| Export selected inventory | $inventory |
Export-Csv -LiteralPath './hardware-inventory.csv' -NoTypeInformation -Encoding utf8 | View examples |
CIM cmdlets expose Windows Management Instrumentation through typed objects without relying on the legacy Get-WmiObject cmdlet. Build an inventory from stable identifiers, collect only properties you need, and distinguish reported configuration from live health. CimCmdlets are Windows-only; remote collection normally uses WS-Man and requires network reachability, authentication, namespace permissions, and compatible Windows management endpoints.
Step by step
Detailed examples
Discover the provider schema before writing a fleet query
CIM class availability and populated properties vary by Windows edition, hardware, installed roles, provider version, and privilege. Use Get-CimClass to confirm the namespace and declared properties on a representative host, then request only fields your report needs. The CimCmdlets module is built into supported Windows PowerShell and PowerShell releases on Windows. These discovery commands are read-only and do not implement WhatIf because they do not request a state change.
Get-Module -ListAvailable CimCmdlets | Select-Object Name, Version, Path
$class = Get-CimClass -Namespace 'root/cimv2' -ClassName 'Win32_ComputerSystem'
$class | Select-Object CimClassName, CimSystemProperties
$class.CimClassProperties | Select-Object Name, CimType, Qualifiers Anchor inventory to host and operating-system identity
Computer names, domain membership, model strings, and installed memory come from Win32_ComputerSystem; OS caption, version, build, architecture, and boot time come from Win32_OperatingSystem. Treat TotalPhysicalMemory as bytes and keep raw values in machine-readable exports. A successful response proves what the provider reported at collection time, not that the machine is patched, supported, or healthy.
$computer = Get-CimInstance -ClassName 'Win32_ComputerSystem'
$os = Get-CimInstance -ClassName 'Win32_OperatingSystem'
[pscustomobject]@{ Host = $computer.Name; Domain = $computer.Domain; Manufacturer = $computer.Manufacturer; Model = $computer.Model; Windows = $os.Caption; Build = $os.BuildNumber; Architecture = $os.OSArchitecture; LastBoot = $os.LastBootUpTime } Preserve firmware and component identifiers without over-trusting them
BIOS, processor, and memory classes expose SMBIOS and vendor data that can be blank, padded, duplicated, virtualized, or inaccurate. Serial numbers may be sensitive asset identifiers. Normalize whitespace, retain the source host and collection timestamp, and compare against vendor tooling before making warranty or firmware decisions. Inventory needs no elevation on many systems, but specific providers and remote ACLs can require administrative rights.
Get-CimInstance Win32_BIOS | Select-Object Manufacturer, SMBIOSBIOSVersion, ReleaseDate, SerialNumber
Get-CimInstance Win32_Processor | Select-Object DeviceID, Name, NumberOfCores, NumberOfLogicalProcessors
Get-CimInstance Win32_PhysicalMemory | Select-Object DeviceLocator, Capacity, Speed, Manufacturer, PartNumber Keep physical devices, partitions, and logical volumes distinct
Win32_DiskDrive describes devices while Win32_LogicalDisk describes drive-letter or logical resources; neither relationship should be inferred from array order. DriveType 3 selects fixed disks but may include virtual storage. Status is a coarse provider value, not predictive disk health. Read-only CIM inventory causes no reboot, but storage remediation is a separate elevated and potentially destructive workflow that cannot be made safe by adding WhatIf to an unrelated query.
Get-CimInstance Win32_LogicalDisk -Filter 'DriveType = 3' | ForEach-Object {
[pscustomobject]@{ Drive = $_.DeviceID; Label = $_.VolumeName; FileSystem = $_.FileSystem; SizeGiB = [math]::Round($_.Size / 1GB, 2); FreeGiB = [math]::Round($_.FreeSpace / 1GB, 2) }
} Handle array-valued network data and large driver inventories
IPAddress, subnet, DNS server, and gateway properties can contain multiple IPv4 and IPv6 values. Expand or join them explicitly rather than relying on table truncation. PnP driver inventories can be large and may expose devices that are absent or disabled; capture DeviceID or InfName when correlation matters. Querying is read-only, but remote access can be denied by firewall, WS-Man, DCOM, namespace, or UAC policy independently.
Get-CimInstance Win32_NetworkAdapterConfiguration -Filter 'IPEnabled = TRUE' | ForEach-Object {
[pscustomobject]@{ Description = $_.Description; MAC = $_.MACAddress; Addresses = ($_.IPAddress -join ';'); Gateways = ($_.DefaultIPGateway -join ';'); DnsServers = ($_.DNSServerSearchOrder -join ';') }
} Filter at the provider and shape after retrieval
-Filter and WQL -Query reduce returned instances, while Select-Object shapes PowerShell output after retrieval. WQL quoting is not PowerShell quoting, so keep fleet filters simple and test them read-only. Avoid SELECT * against expensive provider classes at scale. CIM query cmdlets have no WhatIf because they are observational; Invoke-CimMethod and Set-CimInstance can mutate remote state and require method-specific impact analysis rather than assuming universal ShouldProcess support.
$query = 'SELECT DeviceID,VolumeName,FileSystem,Size,FreeSpace FROM Win32_LogicalDisk WHERE DriveType=3'
Get-CimInstance -Query $query | Select-Object DeviceID, VolumeName, FileSystem, Size, FreeSpace Create, reuse, and close explicit remote sessions
New-CimSession uses WS-Man when a computer name is supplied unless a different session option is selected. Prefer FQDNs, Kerberos in an AD domain, HTTPS or trusted enterprise configuration outside Kerberos, and least-privilege namespace access. Do not use SkipCA, SkipCN, NoEncryption, TrustedHosts wildcards, or embedded passwords as convenience fixes. A session can be created without elevation if permissions allow; remote inventory never implies permission to administer the target and normally requires no reboot.
$session = New-CimSession -ComputerName 'server01.contoso.com' -Authentication Kerberos
try {
Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem | Select-Object CSName, Caption, Version, BuildNumber, LastBootUpTime
} finally {
Remove-CimSession -CimSession $session
} Export curated evidence with provenance
Select a stable schema and add source host and UTC collection time before export. Export-Csv writes a local file and can overwrite an existing path only when permitted; it does not validate retention, access control, or privacy. Generate a unique destination, verify it does not exist, protect asset identifiers, and hash or sign the final artifact when chain of custody matters. WhatIf previews the file-writing cmdlet but cannot prove free space, downstream ingestion, or access controls.
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$path = Join-Path $PWD "hardware-inventory-$stamp.csv"
if (Test-Path -LiteralPath $path) { throw "Refusing to overwrite $path" }
$inventory | Export-Csv -LiteralPath $path -NoTypeInformation -Encoding utf8 -WhatIf Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



