Listing All The WMI Class Properties With VBA

In my past WMI articles:

I’ve always shown you how to retrieve a specific element, specific value. Today, however, I thought I’d share a very simple ‘tool’ that I created to help me see what a class could provide me as information. Yes, there is the documentation, but sometimes, seeing the real-life output from your own device greatly aid in the learning process. Understanding what the difference is between DeviceId, Caption and Name … is much easier to do when you see, for yourself, the concrete values returned by WMI.

As such, I developed a very simple function that will enumerate all the properties of the specified WMI Class, thus allowing you to review the output, and this in turn can help you build your own procedure to retrieve just the right property value.

The hardest thing to understand, figure out, was the fact that in WMI, you don’t iterate of .Properties but rather .Properties_ (notice the underscore at the end!). Once you know that the rest is straightforward coding. The result then becomes:

'---------------------------------------------------------------------------------------
' Procedure : WMI_EnumerateClassProperties
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Enumerate all the properties of the specified WMI Class in the
'               VBA Immediate Window
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Late Binding  -> None required
'             Early Binding -> Microsoft WMI Scripting VX.X Library
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sClass    : WMI Class to enumerate the properties of
'
' Usage:
' ~~~~~~
' WMI_EnumerateClassProperties "Win32_BIOS"
' WMI_EnumerateClassProperties "Win32_DiskDrive"
' WMI_EnumerateClassProperties "Win32_Environment"
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2015-04-22              Initial Release
' 2         2022-01-27              Updated Copyright, Error Handler
' 3         2022-01-31              Added handling of array values
'---------------------------------------------------------------------------------------
Sub WMI_EnumerateClassProperties(ByVal sClass As String)
    On Error GoTo Error_Handler
    #Const WMI_EarlyBind = False    'True => Early Binding / False => Late Binding
    #If WMI_EarlyBind = True Then
        Dim oWMI              As WbemScripting.SWbemServices
        Dim oCols             As WbemScripting.SWbemObjectSet
        Dim oCol              As WbemScripting.SWbemObject
        Dim oPrp              As WbemScripting.SWbemProperty
    #Else
        Dim oWMI              As Object
        Dim oCols             As Object
        Dim oCol              As Object
        Dim oPrp              As Object
        Const wbemFlagReturnImmediately = 16    '(&H10)
        Const wbemFlagForwardOnly = 32    '(&H20)
    #End If

    Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    Set oCols = oWMI.ExecQuery("SELECT * FROM " & sClass, , wbemFlagReturnImmediately Or wbemFlagForwardOnly)

    For Each oCol In oCols
        For Each oPrp In oCol.Properties_
        If oPrp.IsArray = True Then
            'Need to create a conversion routine based on the oPrp.CIMType to return the proper value
            Debug.Print oPrp.Name, String(5, "?")
        Else
            Debug.Print oPrp.Name, oPrp.Value
        End If
            
        Next oPrp
        Debug.Print
    Next

Error_Handler_Exit:
    On Error Resume Next
    If Not oPrp Is Nothing Then Set oPrp = Nothing
    If Not oCol Is Nothing Then Set oCol = Nothing
    If Not oCols Is Nothing Then Set oCols = Nothing
    If Not oWMI Is Nothing Then Set oWMI = Nothing
    Exit Sub

Error_Handler:
    Debug.Print Err.Number, Err.Description
    MsgBox "The following error has occurred." & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: GetClassProperties" & vbCrLf & _
           "Error Description: " & Err.Description, _
           vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Sub

That’s it! Now with a simple command such as:

WMI_EnumerateClassProperties "Win32_BootConfiguration"

You can get output like:

BootDirectory C:\WINDOWS
Caption       \Device\Harddisk0\Partition1
ConfigurationPath           C:\WINDOWS
Description   \Device\Harddisk0\Partition1
LastDrive     T:
Name          BootConfiguration
ScratchDirectory            C:\WINDOWS\system32\config\systemprofile\AppData\Local\Temp
SettingID     Null
TempDirectory C:\WINDOWS\system32\config\systemprofile\AppData\Local\Temp

and so on.

I hope this helps a few people out there explore a little of what WMI has to offer.

A Few Resources on the Subject

2 responses on “Listing All The WMI Class Properties With VBA

    1. Daniel Pineault Post author

      Without seeing what you are seeing it is hard to say what is going on.

      Some properties don’t necessarily have values.

      You’re best bet is to post your question in a Forum with examples of the output you are getting.