Introduction to WMI on Windows Server 2019
Windows Management Instrumentation (WMI) is a core Windows infrastructure technology that provides a standardized interface for managing and monitoring Windows systems. WMI implements the Distributed Management Task Force (DMTF) Common Information Model (CIM) standard, making it an industry-standard approach to system management. On Windows Server 2019, WMI exposes thousands of classes organized into namespaces that provide access to hardware information, operating system configuration, running processes, services, event logs, network configuration, and virtually every manageable aspect of the system. Administrators use WMI via PowerShell’s Get-WmiObject and Get-CimInstance cmdlets, through scripting languages, and through management tools including System Center Operations Manager and SCCM.
Understanding WMI Architecture
WMI uses a hierarchical namespace structure. The primary namespace for most management tasks is rootCIMv2, which contains classes representing the operating system, hardware, and processes. Other important namespaces include rootMicrosoftWindowsStorage for storage management, rootRSOP for Resultant Set of Policy data, rootMicrosoftWindowsDefender for Defender Antivirus, and rootMicrosoftWindowsHardwareManagement for hardware health. List available namespaces:
Get-CimInstance -Namespace root -ClassName __Namespace | Select-Object Name
Get-WmiObject -Namespace root -Class __Namespace | Select-Object Name
List all classes in the rootCIMv2 namespace:
Get-CimClass -Namespace root/CIMv2 | Select-Object CimClassName | Where-Object {$_.CimClassName -like "Win32*"} | Sort-Object CimClassName | Format-Table
Querying System Information with WMI
Use WMI to retrieve comprehensive system information. The preferred modern approach uses Get-CimInstance which uses WinRM transport instead of DCOM:
Get-CimInstance Win32_ComputerSystem | Select-Object Name, Domain, Manufacturer, Model, TotalPhysicalMemory, NumberOfLogicalProcessors, DNSHostName
Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber, InstallDate, LastBootUpTime, TotalVisibleMemorySize, FreePhysicalMemory, OSArchitecture
Get-CimInstance Win32_BIOS | Select-Object Manufacturer, Name, SerialNumber, SMBIOSBIOSVersion, ReleaseDate
Get-CimInstance Win32_Processor | Select-Object Name, MaxClockSpeed, NumberOfCores, NumberOfLogicalProcessors, LoadPercentage, SocketDesignation
Get-CimInstance Win32_PhysicalMemory | Select-Object BankLabel, Capacity, Speed, Manufacturer, PartNumber | ForEach-Object {$_.Capacity = $_.Capacity/1GB; $_}
Managing Services via WMI
WMI provides complete service management capabilities including starting, stopping, pausing, and changing service configuration:
Get-CimInstance Win32_Service | Where-Object {$_.State -eq "Running"} | Select-Object Name, DisplayName, StartMode, PathName | Format-Table -AutoSize
Get-CimInstance Win32_Service -Filter "Name='Spooler'" | Select-Object Name, State, StartMode, StartName
$service = Get-CimInstance Win32_Service -Filter "Name='Spooler'"
Invoke-CimMethod -InputObject $service -MethodName "StopService"
Invoke-CimMethod -InputObject $service -MethodName "StartService"
Invoke-CimMethod -InputObject $service -MethodName "ChangeStartMode" -Arguments @{StartMode="Disabled"}
Find services running with non-system accounts (important for security auditing):
Get-CimInstance Win32_Service | Where-Object {$_.StartName -notmatch "LocalSystem|NetworkService|LocalService|NT AUTHORITY|NT SERVICE"} | Select-Object Name, DisplayName, StartName, State
Process Management with WMI
WMI provides detailed process information and management capabilities. Win32_Process includes the full command line, creation date, and parent process ID:
Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine, CreationDate | Sort-Object CreationDate -Descending | Format-Table -AutoSize
# Top 10 processes by virtual memory size
Get-CimInstance Win32_Process | Sort-Object VirtualSize -Descending | Select-Object -First 10 ProcessId, Name, VirtualSize, WorkingSetSize | ForEach-Object {
[PSCustomObject]@{
PID = $_.ProcessId
Name = $_.Name
VirtualSizeMB = [math]::Round($_.VirtualSize/1MB, 0)
WorkingSetMB = [math]::Round($_.WorkingSetSize/1MB, 0)
}
} | Format-Table
Terminate a process via WMI:
$process = Get-CimInstance Win32_Process -Filter "Name='notepad.exe'"
Invoke-CimMethod -InputObject $process -MethodName "Terminate"
Network Configuration via WMI
Query and modify network configuration using WMI classes:
Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled -eq $true} | Select-Object Description, IPAddress, DefaultIPGateway, DNSServerSearchOrder, MACAddress
Get-CimInstance Win32_NetworkAdapter | Where-Object {$_.PhysicalAdapter -eq $true} | Select-Object Name, Speed, MACAddress, NetConnectionStatus, NetConnectionID
Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled} | ForEach-Object {
[PSCustomObject]@{
Adapter = $_.Description
IP = $_.IPAddress -join ", "
Mask = $_.IPSubnet -join ", "
Gateway = $_.DefaultIPGateway -join ", "
DNS = $_.DNSServerSearchOrder -join ", "
DHCP = $_.DHCPEnabled
}
}
Configure a static IP address via WMI:
$nic = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.IPEnabled -and $_.Description -like "*Ethernet*"} | Select-Object -First 1
$nic.EnableStatic("192.168.1.100", "255.255.255.0")
$nic.SetGateways("192.168.1.1", 1)
$nic.SetDNSServerSearchOrder(@("192.168.1.10","192.168.1.11"))
WMI Event Subscriptions for Monitoring
WMI supports event subscriptions that trigger actions when specific conditions occur. Create a permanent WMI event subscription to detect new processes being launched, useful for security monitoring:
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'"
$filter = Set-WmiInstance -Namespace rootsubscription -Class __EventFilter -Arguments @{
Name = "ProcessCreationFilter"
EventNamespace = "rootcimv2"
QueryLanguage = "WQL"
Query = $query
}
$consumer = Set-WmiInstance -Namespace rootsubscription -Class LogFileEventConsumer -Arguments @{
Name = "ProcessCreationConsumer"
FileName = "C:WMILogsProcessCreation.log"
Text = "New process: %TargetInstance.Name% PID: %TargetInstance.ProcessId% at %TIME_CREATED%"
}
Set-WmiInstance -Namespace rootsubscription -Class __FilterToConsumerBinding -Arguments @{
Filter = $filter
Consumer = $consumer
}
WMI Security and DCOM Configuration
Configure WMI security to allow remote management from specific accounts while preventing unauthorized access. WMI uses DCOM for remote connections. Configure DCOM access permissions:
dcomcnfg.exe # Opens Component Services for GUI configuration
# Or configure via WMI Security in the WMI Control snap-in (wmimgmt.msc)
Grant a non-administrative user read access to WMI namespaces:
$wmiNS = "rootcimv2"
$account = "CONTOSOMonitorUser"
$wmisecurity = Get-WmiObject -Namespace $wmiNS -Class __systemsecurity
$binarySD = @($null)
$wmisecurity.GetSD($binarySD) | Out-Null
$converter = New-Object System.Management.ManagementClass Win32_SecurityDescriptorHelper
$sd = $converter.BinarySDToSDDL($binarySD[0])
Write-Host "Current WMI Security Descriptor: $($sd.SDDL)"
Configure Windows Firewall to allow WMI remote queries from specific management hosts:
Enable-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)"
New-NetFirewallRule -DisplayName "WMI Remote Management" -Direction Inbound -Protocol TCP -LocalPort 135 -Action Allow -RemoteAddress 192.168.1.100
Set-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)" -Enabled True -Profile Domain
Remote WMI Queries
Query WMI on remote Windows Server 2019 machines using Get-CimInstance with CIM sessions for efficient multi-server querying:
$servers = "Server01","Server02","Server03"
$cred = Get-Credential
$sessions = New-CimSession -ComputerName $servers -Credential $cred
Get-CimInstance Win32_OperatingSystem -CimSession $sessions | Select-Object PSComputerName, Caption, FreePhysicalMemory, LastBootUpTime
Get-CimInstance Win32_Service -CimSession $sessions -Filter "State='Stopped' AND StartMode='Auto'" | Select-Object PSComputerName, Name, DisplayName, StartMode
Remove-CimSession $sessions
WMI on Windows Server 2019 remains a cornerstone technology for system management, automation, and monitoring, providing rich programmatic access to all aspects of Windows server configuration and health through standardized, queryable classes.