Reputation: 24476
This is a complicated idea, and I hope you'll bear with me as its articulation is difficult.
It seems that some WMI classes have a primitive value that can be queried, while others do not. This has practical significance.
Take, for instance, the Win32_Processor class. Its primitive value, as far as I can tell, is the value of its instance's DeviceID
column. This allows querying, for example, the architecture (32 / 64-bitness) of the running OS with a tidy one-liner, like this JScript example:
var arch = GetObject("winmgmts:root\\cimv2:Win32_Processor='cpu0'").AddressWidth
In that example, GetObject
acts as a sort of select instance where primitive value="cpu0"
and returns a single instance, rather than a collection. This works as intended.
On the other hand, the Win32_OperatingSystem class has no primitive value that I've been able to find. Like the Win32_Processor
class DeviceID
column, the MSDN documentation for Win32_OperatingSystem
claims that the CreationClassName
column is the table's key
field.
Assume that predictably, CreationClassName=="Win32_OperatingSystem"
. Therefore, one might infer that a similar one-liner could be written thusly:
var arch = GetObject("winmgmts:root\\cimv2:Win32_OperatingSystem='Win32_OperatingSystem'").OSArchitecture
However, that results in an error. My trial-and-error attempts at using other column values have equally all met with failure. Appending .columname
between the classname and =
results in a syntax error as well.
As far as I can tell, there's no way to identify a single instance of the Win32_OperatingSystem
class without enumerating all instances, even if there is only one instance to enumerate.
var wmi = GetObject("winmgmts:");
var os = wmi.ExecQuery("select OSArchitecture from Win32_OperatingSystem");
for (var res = new Enumerator(os); !res.atEnd(); res.moveNext()) {
var arch = res.item().OSArchitecture;
}
These lines can be combined somewhat:
var os = GetObject("winmgmts:").ExecQuery("select OSArchitecture from Win32_OperatingSystem");
var arch = new Enumerator(os).item().OSArchitecture;
... but it'd still be nice to query an instance directly within Win32_OperatingSystem
without having to enumerate an irritatingly vestigial hierarchy.
How can I predict whether a WMI class has a primitive value that can be queried, and which column contains that value?
Upvotes: 3
Views: 376
Reputation: 126842
What you're looking for is the 'Key' property.
http://blogs.msdn.com/b/powershell/archive/2008/04/15/wmi-object-identifiers-and-keys.aspx
Upvotes: 2
Reputation: 24476
In powershell
, the Get-WmiObject cmdlet (or gwmi
alias) provides some insight that isn't obvious or readily available in MSDN. When querying classes via gwmi
there are some differences among classes that are either not well or not at all documented elsewhere (or at least not easily searchable). Take the following powershell
session for example:
You see the Win32_Processor
class has __RELPATH
and __PATH
properties which refer to the class's primitive value of CPU0
; whereas the Win32_OperatingSystem
class has no such properties.
That could be a strong hint to help determine whether the class you wish to query must be fully enumerated before it can be parsed.
Upvotes: 1