A WQL query in WMI using the COM API returns a SWbemObjectSet. From this, we can use the ItemIndex method to iterate over all objects in the set, resulting in many SWbemObjects. These have a Properties_
property, which returns a SWbemPropertySet.
This object has a Count
property, but no ItemIndex
method, instead only an Item
method, which takes a string name of the property to fetch. I'd like to iterate over all available properties, thus I don't have the name available. I've tried calling an ItemIndex
method, but (as per the documentation) it does not exist on this object. There are many VBScript documents around that do something like For Each prop in object.Properties_
, so I assume this is somehow possible.
How can I find all properties?
First, the ItemIndex
property only exist in some versions of the Microsoft WMI Scripting Library
you can find more info about this topic on this article which I wrote some time ago
Be careful when you import the Microsoft WMI Scripting Library
(The code uses Delphi but the same applies to any language using this Library).
Now to iterate over the elements of an SWbemPropertySet
you must get a instance to the enumerator accessing the _NewEnum
property which provides a method for enumerating a collection of variants using the IEnumVARIANT
interface. This is done automagically by vbscript, but in others languages like Delphi or C++ must be done manually.
Try this Delphi sample
{$APPTYPE CONSOLE}
uses
SysUtils,
ActiveX,
ComObj,
Variants,
WbemScripting_TLB in 'WbemScripting_TLB.pas';
procedure ShowProperties(const WMINameSpace, WMIClass : string);
var
WMIServices : ISWbemServices;
SWbemObjectSet : ISWbemObjectSet;
SObject : ISWbemObject;
LProperty : ISWbemProperty;
Enum, Enum2 : IEnumVariant;
TempObj, TempObj2: OleVariant;
Value : Cardinal;
SWbemPropertySet: ISWbemPropertySet;
begin
WMIServices := CoSWbemLocator.Create.ConnectServer('.', WMINameSpace,'', '', '', '', 0, nil);
SWbemObjectSet := WMIServices.ExecQuery(Format('Select * FROM %s',[WMIClass]), 'WQL', 0, nil);
Enum := (SWbemObjectSet._NewEnum) as IEnumVariant;
if (Enum.Next(1, TempObj, Value) = S_OK) then
begin
SObject := IUnknown(TempObj) as ISWBemObject;
SWbemPropertySet := SObject.Properties_;
Enum2 := (SWbemPropertySet._NewEnum) as IEnumVariant;
while (Enum2.Next(1, TempObj2, Value) = S_OK) do
begin
LProperty := IUnknown(TempObj2) as ISWbemProperty;
Writeln(LProperty.Name);
TempObj2:=Unassigned;
end;
TempObj:=Unassigned;
end;
end;
begin
try
CoInitialize(nil);
try
ShowProperties('root\cimv2','Win32_BaseBoard');
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.
I hope which you can translate this sample to the Go language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With