WMI classes are organized in so-called namespaces that start at “root” and work like a directory structure. The default namespace is root\cimv2, and when you do not specify a namespace, you can only see the WMI classes located in the default namespace. This is what we have been using in the past parts of this series.

There are many more namespaces with many additional WMI classes, some of which can be highly useful. Before we explore this part of WMI, be advised that you are going to tap into sparsely documented areas of Windows that are not necessarily intended for general audiences. You may have to google, and classes found here may be available on specific Windows operating systems and/or license types only.

To get a list of WMI namespaces available on your computer, run the code below:

# create a new queue
$namespaces = [System.Collections.Queue]::new()

# add an initial namespace to the queue
# any namespace in the queue will later be processed
$namespaces.Enqueue('root')

# process all elements on the queue until all are taken
While ($namespaces.Count -gt 0 -and ($current = $namespaces.Dequeue()))
{
    # find child namespaces
    Get-CimInstance -Namespace $current -ClassName __Namespace -ErrorAction Ignore |
    # ignore localization namespaces
    Where-Object Name -NotMatch '^ms_\d{2}' |
    ForEach-Object {
        # construct the full namespace name
        $childnamespace = '{0}\{1}' -f $current, $_.Name
        # add namespace to queue
        $namespaces.Enqueue($childnamespace)
    }

    # output current namespace
    $current
}

The code may run for some time, so grab a coffee. The result is the list of namespaces available on your machine and may look similar to this:

 
root
root\subscription
root\DEFAULT
root\CIMV2
root\msdtc
root\Cli
root\Intel_ME
root\SECURITY
root\HyperVCluster
root\SecurityCenter2
root\RSOP
root\PEH
root\StandardCimv2
root\WMI
root\MSPS
root\directory
root\Policy
root\virtualization
root\Interop
root\Hardware
root\ServiceModel
root\SecurityCenter
root\Microsoft
root\Appv
root\dcim
root\CIMV2\mdm
root\CIMV2\Security
root\CIMV2\power
root\CIMV2\TerminalServices
root\HyperVCluster\v2
root\RSOP\User
root\RSOP\Computer
root\StandardCimv2\embedded
root\directory\LDAP
root\virtualization\v2
root\Microsoft\HomeNet
root\Microsoft\protectionManagement
root\Microsoft\Windows
root\Microsoft\SecurityClient
root\Microsoft\Uev
root\dcim\sysman
root\CIMV2\mdm\dmmap
root\CIMV2\Security\MicrosoftTpm
root\CIMV2\Security\MicrosoftVolumeEncryption
root\Microsoft\Windows\RemoteAccess
root\Microsoft\Windows\Dns
root\Microsoft\Windows\Powershellv3
root\Microsoft\Windows\Hgs
root\Microsoft\Windows\WindowsUpdate
root\Microsoft\Windows\DeviceGuard
root\Microsoft\Windows\TaskScheduler
root\Microsoft\Windows\DesiredStateConfigurationProxy
root\Microsoft\Windows\SmbWitness
root\Microsoft\Windows\Wdac
root\Microsoft\Windows\StorageReplica
root\Microsoft\Windows\winrm
root\Microsoft\Windows\AppBackgroundTask
root\Microsoft\Windows\DHCP
root\Microsoft\Windows\PS_MMAgent
root\Microsoft\Windows\Storage
root\Microsoft\Windows\HardwareManagement
root\Microsoft\Windows\SMB
root\Microsoft\Windows\EventTracingManagement
root\Microsoft\Windows\DesiredStateConfiguration
root\Microsoft\Windows\Attestation
root\Microsoft\Windows\CI
root\Microsoft\Windows\dfsn
root\Microsoft\Windows\DeliveryOptimization
root\Microsoft\Windows\Defender
root\dcim\sysman\biosattributes
root\dcim\sysman\wmisecurity
root\Microsoft\Windows\RemoteAccess\Client
root\Microsoft\Windows\Storage\PT
root\Microsoft\Windows\Storage\Providers_v2
root\Microsoft\Windows\Storage\PT\Alt  
 

Once you know the names of namespaces, use the previous parts of this mini-series to query the WMI class names located in a given namespace. For example, the code below lists all WMI classes in the namespace 'root\Microsoft\Windows\WindowsUpdate':

$ns = 'root\Microsoft\Windows\WindowsUpdate'
Get-CimClass -Namespace $ns | 
  Select-Object -ExpandProperty CimClassName | 
  Sort-Object

Class names that start with a double underscore are for internal purposes:

 
__AbsoluteTimerInstruction
__ACE
__AggregateEvent
__ClassCreationEvent
__ClassDeletionEvent
__ClassModificationEvent
__ClassOperationEvent
__ClassProviderRegistration
__ConsumerFailureEvent
__Event
__EventConsumer
__EventConsumerProviderRegistration
__EventDroppedEvent
__EventFilter
__EventGenerator
__EventProviderRegistration
__EventQueueOverflowEvent
__ExtendedStatus
__ExtrinsicEvent
__FilterToConsumerBinding
__IndicationRelated
__InstanceCreationEvent
__InstanceDeletionEvent
__InstanceModificationEvent
__InstanceOperationEvent
__InstanceProviderRegistration
__IntervalTimerInstruction
__MethodInvocationEvent
__MethodProviderRegistration
__NAMESPACE
__NamespaceCreationEvent
__NamespaceDeletionEvent
__NamespaceModificationEvent
__NamespaceOperationEvent
__NotifyStatus
__NTLMUser9X
__ObjectProviderRegistration
__PARAMETERS
__PropertyProviderRegistration
__Provider
__ProviderRegistration
__QOSFailureEvent
__SecurityDescriptor
__SecurityRelatedClass
__SystemClass
__SystemEvent
__SystemSecurity
__thisNAMESPACE
__TimerEvent
__TimerInstruction
__TimerNextFiring
__Trustee
__Win32Provider
CIM_ClassCreation
CIM_ClassDeletion
CIM_ClassIndication
CIM_ClassModification
CIM_Error
CIM_Indication
CIM_InstCreation
CIM_InstDeletion
CIM_InstIndication
CIM_InstModification
MSFT_ExtendedStatus
MSFT_WmiError
MSFT_WUOperations
MSFT_WUSettings
MSFT_WUUpdate  
 

To query the class MSFT_WUSettings in this namespace (if present on your machine), run this:

$ns = 'root\Microsoft\Windows\WindowsUpdate'
Get-CimInstance -ClassName MSFT_WUSettings -Namespace $ns

The result is an exception which indicates that you may be up for surprises when exploring new and sparsely documented internal WMI classes. Depending on your operating system and license type, operations may or may not be supported. If they are not supported, you may end up with a “provider failure” exception.

In addition, some WMI classes (like the ones in this namespace) are not so much designed to contain properties and return information. Instead, they contain methods (commands), in this case to manage Windows Update:

$ns = 'root\Microsoft\Windows\WindowsUpdate'
Get-CimClass -Namespace $ns -ClassName 'MSFT_WUOperations' |
  Select-Object -ExpandProperty CimClassMethods

The result shows the methods:

 
Name           ReturnType Parameters                              Qualifiers           
----           ---------- ----------                              ----------           
ScanForUpdates     UInt32 {SearchCriteria, Updates}               {implemented, static}
InstallUpdates     UInt32 {DownloadOnly, Updates, RebootRequired} {implemented, static}
 

Here is a practical example for Windows Server 2019 machines. The script remotely accesses the servers (in parallel) and uses local WMI to check for security updates, then installs them:

# list of names of Windows Server 2019 machines to update:
$servers="Server2019-IIS","Server2019-AD"

$ns = "root/Microsoft/Windows/WindowsUpdate"
$class = "MSFT_WUOperations"

Invoke-Command -ComputerName $servers -ScriptBlock {
    # find missing updates:
    $arg = @{SearchCriteria="IsInstalled=0 AND AutoSelectOnWebSites=1"}
    $r = Invoke-CimMethod -Namespace $ns -ClassName $class -MethodName ScanForUpdates -Arguments $arg

    # install missing updates:
    if ($r.Updates)
    {
        $arg = @{Updates=$r.Updates}
        Invoke-CimMethod -Namespace $ns -ClassName $class -MethodName InstallUpdates -Arguments $arg
    }
}

Note that the code above works on Windows Server 2019 but fails on Windows Server 2016 (because WMI class names slightly changed). If you still would like to dig deeper, we can highly recommend https://github.com/microsoft/MSLab/blob/master/Scenarios/Windows%20Update/readme.md which is a rich set of examples on how to use WMI to manage Windows Updates on Windows Servers.

And if you’re interested in WMI in general, head over to https://powershell.one/wmi/commands for more information.




Twitter This Tip! ReTweet this Tip!

Anonymous