Chapter 12Lesson 03~160 minutes

CIM, WMI History, and Structured Windows Management

Use the Windows-only CimCmdlets model to discover management classes, query structured instances, filter evidence, and understand the WMI-to-CIM transition.

Learning objectives

  • Explain the management problem CIM solves and its relationship to WMI.
  • Recognize that CimCmdlets are Windows-only in PowerShell 7.6.
  • Distinguish CIM classes, namespaces, properties, methods, and instances.
  • Discover schemas with Get-CimClass instead of memorizing class lists.
  • Query and filter read-only Windows management evidence with Get-CimInstance.
  • Understand CimSession as a bridge to later remoting.

1. CIM gives Windows management data a structured model

Operating systems expose thousands of management facts: OS version, boot time, disks, processes, network adapters, firmware, services, and more. Hard-coding a different parser for every command is fragile. CIM (Common Information Model) defines management classes with named properties and methods so tools can query structured state.

In current PowerShell 7.6, the CimCmdlets module is Windows-only. This lesson is therefore a Windows administration path, not a cross-platform abstraction.

2. WMI and CIM: history without carrying legacy habits forward

WMI (Windows Management Instrumentation) is Microsoft's Windows management infrastructure and historically exposed many Win32_* classes. Older Windows PowerShell scripts often use WMI-era command patterns. Modern PowerShell administration should prefer Get-CimInstance, Get-CimClass, and related CimCmdlets where appropriate.

The class names can still begin with Win32_ because CIM cmdlets are querying the Windows management schema; “CIM cmdlet” does not mean the underlying Windows class names were renamed.

3. Detect the Windows CIM capability before depending on it

$cimAvailable = $IsWindows -and [bool](Get-Command Get-CimInstance -ErrorAction SilentlyContinue)
[pscustomobject]@{
    IsWindows    = $IsWindows
    CimAvailable = $cimAvailable
    Module       = (Get-Module -ListAvailable CimCmdlets | Select-Object -First 1 -ExpandProperty Name)
}

4. A class is the schema; an instance is one observed object

A CIM class describes possible properties and methods. A CIM instance is one snapshot of a managed item. Learn discovery before memorizing class names.

if ($IsWindows) {
    $class = Get-CimClass -Namespace root/cimv2 -ClassName Win32_OperatingSystem
    $class | Select-Object CimClassName,CimSystemProperties
    $class.CimClassProperties |
        Select-Object -First 12 Name,CimType
}

5. Namespaces organize management classes

A namespace is a logical container for management classes. Many commonly used Windows classes live under root/cimv2. Do not scan every namespace in production by default; discovery queries can be expensive and may encounter access restrictions.

if ($IsWindows) {
    Get-CimInstance -Namespace root -ClassName __Namespace |
        Select-Object -First 15 Name
}

6. Read-only OS information as structured data

if ($IsWindows) {
    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    [pscustomobject]@{
        Caption        = $os.Caption
        Version        = $os.Version
        Architecture   = $os.OSArchitecture
        LastBootUpTime = $os.LastBootUpTime
        ComputerName   = $os.CSName
    }
}

7. Filter at the management provider when possible

Pulling every instance and filtering afterward wastes work. Get-CimInstance -Filter sends a WMI Query Language (WQL) filter to the provider. Keep filters simple and quote string values carefully.

if ($IsWindows) {
    $query = "ProcessId = $PID"
    Get-CimInstance -ClassName Win32_Process -Filter $query |
        Select-Object ProcessId,ParentProcessId,Name,ExecutablePath,CommandLine
}

8. Ask for the properties you need

Management classes can be very wide. Select a stable operational contract rather than dumping every property into logs. This makes evidence smaller and reduces accidental exposure of sensitive fields.

if ($IsWindows) {
    Get-CimInstance -ClassName Win32_LogicalDisk -Filter 'DriveType = 3' |
        Select-Object DeviceID,
            @{Name='SizeGB';Expression={[math]::Round($_.Size/1GB,2)}},
            @{Name='FreeGB';Expression={[math]::Round($_.FreeSpace/1GB,2)}}
}

9. Methods exist, but discovery is safer than invocation

CIM classes may expose methods—operations that can change system state. For example, management classes can contain methods related to process creation or system control. This lesson discovers method names but does not invoke state-changing methods.

if ($IsWindows) {
    $class = Get-CimClass -ClassName Win32_OperatingSystem
    $class.CimClassMethods.Keys | Sort-Object
}

10. CIM sessions are a reusable connection boundary

A CimSession represents connection information for CIM operations. Sessions are valuable when many queries target the same remote Windows computer because connection setup and policy can be centralized. Transport/authentication details belong to the remoting chapter; here the important model is that session creation is explicit and reusable.

# Bridge example only; do not run without an approved remote Windows target.
# $session = New-CimSession -ComputerName 'server01'
# Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem
# Remove-CimSession $session

11. Lab: discover a class before querying it

On Windows, this read-only lab finds candidate classes by property name, inspects one schema, queries one instance, and builds a clean report. Non-Windows learners can still run the capability check and study the object contract; the CimCmdlets themselves are not available there.

if (-not $IsWindows) {
    'CIM lab requires Windows in PowerShell 7.6.'
} else {

$osClass = Get-CimClass -Namespace root/cimv2 -ClassName Win32_OperatingSystem
$osClass.CimClassProperties |
    Sort-Object Name |
    Select-Object Name,CimType

$interesting = 'Caption','Version','OSArchitecture','LastBootUpTime','CSName'
$missing = $interesting | Where-Object { $_ -notin $osClass.CimClassProperties.Name }
if ($missing) { throw "Expected properties were not found: $($missing -join ', ')" }

$os = Get-CimInstance -ClassName Win32_OperatingSystem
[pscustomobject]@{
    Computer = $os.CSName
    OS       = $os.Caption
    Version  = $os.Version
    Arch     = $os.OSArchitecture
    BootUtc  = $os.LastBootUpTime.ToUniversalTime()
}
}

12. Common mistakes

  • Presenting CimCmdlets as cross-platform in current PowerShell 7.6.
  • Memorizing a long Win32_* list instead of using Get-CimClass discovery.
  • Querying every property/instance and filtering only after retrieval.
  • Invoking CIM methods without understanding side effects or privilege requirements.
  • Mixing remote-session transport design into simple local inventory code.

13. Knowledge check

Question 1. What is the difference between a CIM class and a CIM instance?

Question 2. Are CimCmdlets cross-platform in PowerShell 7.6?

Question 3. Why can a modern CIM query still use a class named Win32_OperatingSystem?

Question 4. Why prefer provider-side filtering?

Question 5. What is a CimSession?

14. Summary and next bridge

CIM gives Windows management data a discoverable class/instance model. In PowerShell 7.6, CimCmdlets are Windows-only, so capability detection is mandatory. Use Get-CimClass to discover schemas, Get-CimInstance for read-only evidence, narrow filters/properties, and explicit sessions for future remote work. Next we combine process/system facts with Windows event records to build evidence-first incident snapshots.

15. Authoritative references

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.