The below simple VBS example retrieves CPU caption, architecture and family from WMI:
s = ""
For Each Item In GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\Root\CIMV2").InstancesOf("Win32_Processor")
s = s & "Caption = " & Item.Caption & vbCrLf
s = s & "Architecture = " & Item.Architecture & vbCrLf
s = s & "Family = " & Item.Family & vbCrLf
Next
WScript.Echo s
The output for me is:
Caption = Intel64 Family 6 Model 42 Stepping 7
Architecture = 9
Family = 198
What I want is to retrieve more descriptive values for architecture and family instead of indexes. Such properties have Values
qualifier, which specifies a list of possible values for the property, and ValueMap
qualifier, which specifies the integer values of the corresponding string values in Values
. That qualifiers are shown on the screenshots I made of two utilities:
WMI Code Creator
WMI CIM Studio
On the last screenshot you can see Win32_Processor
class, Architecture
propertry, Values
qualifier, that contains the array of six strings: x86, MIPS, Alpha, PowerPC, ia64, x64
which corresponds the indexes from array in ValueMap
qualifier: 0, 1, 2, 3, 6, 9
. However the below code doesn't enumerate the qualifiers marked as amended in WMI CIM Studio, such as Description
and Values
for unknown reason:
Set objClass = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Processor")
s = ""
For Each objQualifier In objClass.Properties_("Architecture").Qualifiers_
s = s & objQualifier.Name & " = "
If IsArray(objQualifier.Value) Then
s = s & "{" & Join(objQualifier.Value, ", ") & "}"
Else
s = s & objQualifier.Value
End If
s = s & vbCrLf
Next
WScript.Echo s
I tried to run it on x64 and x86 hosts, and it returns the same output, as follows:
CIMTYPE = uint16
MappingStrings = {WMI}
read = True
ValueMap = {0, 1, 2, 3, 6, 9}
While I expected:
CIMTYPE = uint16
Description = The Architecture property specifies the processor architecture used by this platform. It returns one of the following integer values:
0 - x86
1 - MIPS
2 - Alpha
3 - PowerPC
6 - ia64
9 - x64
MappingStrings = {WMI}
read = True
ValueMap = {0, 1, 2, 3, 6, 9}
Values = {x86, MIPS, Alpha, PowerPC, ia64, x64}
How can I get that qualifiers? Is there any other way to retrieve them?
UPDATE
I've managed to get all property qualifiers, including amended, thanks to @Kul-Tigin for pointing me in the right direction and providing links. Having access to the qualifiers, I extract Values
and ValueMap
arrays from class and create a sort of conversion table oMap
intended for an integer property value translation into an associated string:
Const wbemFlagUseAmendedQualifiers = 131072
Set oService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\Root\CIMV2")
s = ""
For Each oInstance In oService.InstancesOf("Win32_Processor")
For Each sName In Array("Caption", "Family")
s = s & sName & " = " & oInstance.Properties_.Item(sName).Value & vbCrLf
Next
Next
s = s & vbCrLf
Set oClass = oService.Get("Win32_Processor", wbemFlagUseAmendedQualifiers)
Set oProperty = oClass.Properties_.Item("Family")
aValues = oProperty.Qualifiers_.Item("Values")
aValueMap = oProperty.Qualifiers_.Item("ValueMap")
Set oMap = CreateObject("Scripting.Dictionary")
For i = 0 To UBound(aValues)
oMap(aValueMap(i)) = aValues(i)
Next
For Each sKey In oMap
s = s & sKey & " = " & oMap(sKey) & vbCrLf
Next
WScript.Echo s
The output for me is as follows:
Caption = Intel64 Family 6 Model 42 Stepping 7
Family = 198
1 = Other
2 = Unknown
3 = 8086
4 = 80286
5 = 80386
6 = 80486
7 = 8087
8 = 80287
9 = 80387
10 = 80487
11 = Pentium(R) brand
12 = Pentium(R) Pro
13 = Pentium(R) II
14 = Pentium(R) processor with MMX(TM) technology
15 = Celeron(TM)
16 = Pentium(R) II Xeon(TM)
17 = Pentium(R) III
18 = M1 Family
19 = M2 Family
24 = K5 Family
25 = K6 Family
26 = K6-2
27 = K6-3
28 = AMD Athlon(TM) Processor Family
29 = AMD(R) Duron(TM) Processor
30 = AMD29000 Family
31 = K6-2+
32 = Power PC Family
33 = Power PC 601
34 = Power PC 603
35 = Power PC 603+
36 = Power PC 604
37 = Power PC 620
38 = Power PC X704
39 = Power PC 750
48 = Alpha Family
49 = Alpha 21064
50 = Alpha 21066
51 = Alpha 21164
52 = Alpha 21164PC
53 = Alpha 21164a
54 = Alpha 21264
55 = Alpha 21364
64 = MIPS Family
65 = MIPS R4000
66 = MIPS R4200
67 = MIPS R4400
68 = MIPS R4600
69 = MIPS R10000
80 = SPARC Family
81 = SuperSPARC
82 = microSPARC II
83 = microSPARC IIep
84 = UltraSPARC
85 = UltraSPARC II
86 = UltraSPARC IIi
87 = UltraSPARC III
88 = UltraSPARC IIIi
96 = 68040
97 = 68xxx Family
98 = 68000
99 = 68010
100 = 68020
101 = 68030
112 = Hobbit Family
120 = Crusoe(TM) TM5000 Family
121 = Crusoe(TM) TM3000 Family
122 = Efficeon(TM) TM8000 Family
128 = Weitek
130 = Itanium(TM) Processor
131 = AMD Athlon(TM) 64 Processor Family
132 = AMD Opteron(TM) Family
144 = PA-RISC Family
145 = PA-RISC 8500
146 = PA-RISC 8000
147 = PA-RISC 7300LC
148 = PA-RISC 7200
149 = PA-RISC 7100LC
150 = PA-RISC 7100
160 = V30 Family
176 = Pentium(R) III Xeon(TM)
177 = Pentium(R) III Processor with Intel(R) SpeedStep(TM) Technology
178 = Pentium(R) 4
179 = Intel(R) Xeon(TM)
180 = AS400 Family
181 = Intel(R) Xeon(TM) processor MP
182 = AMD AthlonXP(TM) Family
183 = AMD AthlonMP(TM) Family
184 = Intel(R) Itanium(R) 2
185 = Intel Pentium M Processor
190 = K7
200 = IBM390 Family
201 = G4
202 = G5
203 = G6
204 = z/Architecture base
250 = i860
251 = i960
260 = SH-3
261 = SH-4
280 = ARM
281 = StrongARM
300 = 6x86
301 = MediaGX
302 = MII
320 = WinChip
350 = DSP
500 = Video Processor
I tried the code on another PC also:
Caption = AMD64 Family 21 Model 56 Stepping 1
Family = 72
...
There are few details on MSDN about Standard Qualifiers usage:
ValueMap
This qualifier can be used alone or in combination with the Values qualifier. When used in combination with the Values qualifier, the location of the value in the ValueMap array provides the location of the corresponding entry in the Values array. Use the ValueMap qualifier only with string and integer values. The syntax for representing an integer value in the value map array is [+|=]digit[*digit]. The content, maximum number of digits, and represented value are constrained by the type of the associated property. For example, uint8 may not be signed, must be less than four digits, and must represent a value less than 256.
Values
This property also specifies an array of string values to be mapped to an enumeration property. This qualifier can be applied to either an integer property or a string property, and the mapping can be implicit or explicit. If the mapping is implicit, integer or string property values represent ordinal positions in the Values array. If the mapping is explicit, the property must be an integer, and valid property values are listed in the array defined by the ValueMap qualifier. For more information, see Value Map.
If a ValueMap qualifier is not present, the Values array is indexed (zero-relative) by using the value in the associated property, method return type, or method parameter. If a ValueMap qualifier is present, the values index is defined by the location of the property value in the value map.
Now I'm stuck in retrieving the appropriate string, since there is no such index neither 198
nor 72
in ValueMap
qualifier.
The answer is,
Values
/ValueMap
qualifier string table is incomplete and can't be used. You must create such table yourself if you want to map every index into the string value.The value of
Family
property ofWin32_Processor
class comes from Processor Information SMBIOS structure. Values are defined by specification (latest document as of Jan 2018), the table on 46th page contains needed strings:Using this data you can create string table and maintain it as new processor types will by introduced in new SMBIOS versions.
Similar data in the form of C++ enum can be found here.