Hey, Scripting Guy! Question

Hey, Scripting Guy! We have an application that installs a WMI class named UIDLightInfo. That class includes a property named UIDLightState. How can I tell whether or not I can change the value of this property?

-- JC

SpacerHey, Scripting Guy! AnswerScript Center

Hey, JC. You know, we once reviewed a scripting course where the authors continually dealt with the question, “How do I know if I can do x?” Their answer was always the same: “Try it and see what happens. If your script blows up that means you probably can’t do it.” We were always glad that these guys were teaching a scripting class rather than serving as driving instructors:

“Do you think we’d survive if I drove off this cliff?”

“Try it and see what happens.”

Admittedly, there might be times when the only way to find out an answer is to close your eyes, run the script, and hope for the best. This isn’t one of those times, however. WMI is a very powerful technology for retrieving information about processes, services, and other items involving your computer; it’s an equally powerful technology for retrieving information about WMI itself. If you want to know something about WMI namespaces, classes, methods, properties, or what-have-you, the best advice is to just ask WMI.And that’s exactly what this particular script does. This is a generic script that can check a specified property, in a specified class, in a specified namespace, on a specified computer, and then return the following information:

Whether the property stores values as an array.

The data type of the property.

Whether the property is read-write or read-only.

Here’s the script:

strComputer = "."
strNamespace = "\root\cimv2"
strClass = "Win32_Printer"
strProperty = "PortName"

blnWriteable = False

Set objClass = GetObject("winmgmts:\\" & strComputer & strNameSpace & ":" & strClass)

For Each objClassProperty In objClass.Properties_
    If objClassProperty.Name = strProperty Then
        If objClassProperty.IsArray Then
            Wscript.Echo "This property is an array."
        End If

        Select Case objClassProperty.CIMType
            Case 8
                Wscript.Echo "This is a string property."
            Case 11
                Wscript.Echo "This is a Boolean property."
            Case 13
                Wscript.Echo "This is an Object property."
            Case 101
                Wscript.Echo "This is a date-time property."
            Case 102
            Wscript.Echo "This is a Reference property."
            Case 103
                Wscript.Echo "This is a string-type property."
            Case Else
                Wscript.Echo "This is a numeric property."
        End Select

        For Each objQualifier in ObjClassProperty.Qualifiers_
            If objQualifier.Name = "write" Then
                blnWriteable = True
            End If
        Next
    End If
Next

If blnWriteable = True Then
    Wscript.Echo "This property is read-write."
Else
    Wscript.Echo "This property is read-only."
End If

We begin by defining some variables that will be used to connect to the desired computer, namespace, class, and property. Our sample script connects to the root\cimv2 namespace on the local computer and queries the PortName property in the Win32_Printer class; if you want to query a different property/class/whatever, just change the values accordingly. For example, assuming your UIDLightInfo class is found in the root\cimv2 namespace then the first four lines of your script might look like this:

strComputer = "."
strNamespace = "\root\cimv2"
strClass = "UIDLightInfo"
strProperty = "UIDLightState"

In addition, we assign the value False to a fifth variable, blnWriteable. We’re going to assume, by default, that all properties are read-only; that’s what the False is for. Later in the script we’ll test to see if the property is writeable; if it is, then we’ll change the value of blnWriteable to True. Otherwise we’ll just leave it be.

We then use this line of code to connect to the WMI service and bind to the desired class:

Set objClass = GetObject("winmgmts:\\" & strComputer & strNameSpace & ":" & strClass)

When we bind to a class (as opposed to returning instances of that class) we can retrieve information about the class itself. For example, each WMI class has a property named Properties_; as you might expect, this contains a list of all the properties for that class. We use this line of code to set up a For Each loop to walk through the collection of properties:

For Each objClassProperty In objClass.Properties_

Inside that loop we check each property to see if the property name matches the name we assigned to the variable strProperty. If it does, we retrieve some detailed information about that particular property; that’s because properties also have properties. For example, we can look at the IsArray property to determine whether or not the property stores values as an array:

If objClassProperty.IsArray Then
    Wscript.Echo "This property is an array."
End If

In addition, we can use the CIMType property to determine the data type for the property. Because CIMType returns information as an integer value, we set up a Select Case block to convert the value to something a bit more meaningful. For example, if CIMType is an 8, our script echoes back the fact that the property has a string data type:

Case 8
    Wscript.Echo "This is a string property."

Last, but surely not least, we take a look at the “qualifiers” for this property. Qualifiers are additional information that might or might not be present; if they are present they help define the property. For example, if the property has the read qualifier then that property is readable; if the property has the write qualifier, then the property is writeable. We use the following code to loop through all the qualifiers for the property, looking for one with the name write. If we find one, that means that the property is writeable, and we change the value of blnWriteable to True:

For Each objQualifier in ObjClassProperty.Qualifiers_
    If objQualifier.Name = "write" Then
        blnWriteable = True
    End If
Next

We echo whether the property is read-only or read-write, and then call it quits. When we run this script on a Windows XP computer we get back output like this:

This is a string property.
This property is read-write.

Because the property is read-write you now know that you can change it using a script.