Jump to content
Sign in to follow this  
Irios

How to enumerate all properties in an object variable (wmi) when I don't know their names? [SOLVED!]

Recommended Posts

First post here, please be gentle ;)

 

I've spent hours and hours trying to figure out this puzzle. It's impossible to google for because I don't know the precise terminology to use. All msdn links I find are either dead or has been removed like 10 years ago.

 

Here is a tiny code example:

$objWMIService = ObjGet("winmgmts:")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PerfRawData_Tcpip_NetworkInterface Where Name like '%intel%'")
For $objItem In $colItems
    ConsoleWrite($objItem.PacketsPersec & @CRLF)
Next

In that example I'm using the asterix * and it retrieves all properties in the "Win32_PerfRawData_Tcpip_NetworkInterface" class.  But I'm only utilizing "PacketsPersec" in the example.

How could I enumerate all the properties without defining their names beforehand?

(FYI, I do know their names, but the script doesn't know the names)

In other words; how can I use "SELECT *" on any class and output all properties, one by one? Without having to manually specify each property with $objItem.<propertyname> ?


As comparison, using wmic in a cmd shell ...

    wmic path Win32_PerfRawData_Tcpip_NetworkInterface  Where "Name like '%intel%'" get /value

...and it lists all properties in "Names=Value" manner.

This is sort of the same function I'm looking for. How could I do the same in Autoit?

 

 

EDIT: I cannot run a powershell or cmd  to "solve" the problem.  I need to find a way to do this "internally" in Autoit. I.e. by calling the WMI service directly with ObjGet(winmgmts:) or connect to the WMI system with CreateObject("WbemScripting.SWbemLocator"). Performance is a major factor.

Edited by Irios
Solved! :D

Share this post


Link to post
Share on other sites
Local $strComputer = "."
Local $strNameSpace = "root\cimv2"
Local $strClass = "Win32_PerfRawData_Tcpip_NetworkInterface"

Local $objClass = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\" & $strNameSpace & ":" & $strClass)
For $objClassProperty In $objClass.Properties_
    ConsoleWrite($objClassProperty.Name & @CRLF)
Next

 


Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Share this post


Link to post
Share on other sites

Hi there, Terenz.

I must admit I already had a look into ".Properties_" earlier on, but I don't understand its inner workings, tbh. Or rather, I don't know how to get BOTH the property names AND values... in one go.

In your script example... if you output "$objClass.Value" as well, it is just empty. (I'm guessing it's not really the Value for the property at all)

; ../..
ConsoleWrite($objClassProperty.Value & @CRLF)
; ../..

 

Is it a different object "type" altogether? This is my problem, I'm having a hard time getting a grasp on these objects (where do I start to read about this?), and how are they structured internally? (Do you have any simple examples to illustrate this? Or an info page link?)

I could use your script example combined with my own script to get both property names and their respective values, but it's not very efficient and you're then doing two wmi calls. There must be a way to do this in a single run.

Share this post


Link to post
Share on other sites

Hi @Irios perhaps you can try WMI Explorer. Its a tool for displaying WMI Namespaces, Classes and Properties. WMI Explorer
A Way to get both the property and value written to the console is in the example below.

Local $objWMIService = ObjGet("winmgmts:\\" & "." & "\root\CIMV2")
Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PerfRawData_Tcpip_TCP")

If IsObj($colItems) then
   For $objItem In $colItems
      ConsoleWrite ("Caption: " & $objItem.Caption & @CRLF )
      ConsoleWrite ("ConnectionFailures: " & $objItem.ConnectionFailures & @CRLF )
      ConsoleWrite ("ConnectionsActive: " & $objItem.ConnectionsActive & @CRLF )
      ConsoleWrite ("ConnectionsEstablished: " & $objItem.ConnectionsEstablished & @CRLF )
      ConsoleWrite ("ConnectionsPassive: " & $objItem.ConnectionsPassive & @CRLF )
      ConsoleWrite ("ConnectionsReset: " & $objItem.ConnectionsReset & @CRLF )
      ConsoleWrite ("Description: " & $objItem.Description & @CRLF )
      ConsoleWrite ("Frequency_Object: " & $objItem.Frequency_Object & @CRLF )
      ConsoleWrite ("Frequency_PerfTime: " & $objItem.Frequency_PerfTime & @CRLF )
      ConsoleWrite ("Frequency_Sys100NS: " & $objItem.Frequency_Sys100NS & @CRLF )
      ConsoleWrite ("Name: " & $objItem.Name & @CRLF )
      ConsoleWrite ("SegmentsPersec: " & $objItem.SegmentsPersec & @CRLF )
      ConsoleWrite ("SegmentsReceivedPersec: " & $objItem.SegmentsReceivedPersec & @CRLF )
      ConsoleWrite ("SegmentsRetransmittedPersec: " & $objItem.SegmentsRetransmittedPersec & @CRLF )
      ConsoleWrite ("SegmentsSentPersec: " & $objItem.SegmentsSentPersec & @CRLF )
      ConsoleWrite ("Timestamp_Object: " & $objItem.Timestamp_Object & @CRLF )
      ConsoleWrite ("Timestamp_PerfTime: " & $objItem.Timestamp_PerfTime & @CRLF )
      ConsoleWrite ("Timestamp_Sys100NS: " & $objItem.Timestamp_Sys100NS & @CRLF )
   Next
Else
    Msgbox (48, "WMI Error", "WMI Error")
Endif

 

Share this post


Link to post
Share on other sites

Hi pluto41,

Like I wrote in my initial post, I need a way to do it without having to define all the property names beforehand in the code. (Your example will only output properties you specifically define in the code). I want to gather all properties (SELECT *), no matter the name, and then output the Name and its respective Value.

 

EDIT: You refer to WMI Explorer 2... if you use the PowerShell output there... See how it's done with PS? The script actually parses the WMI data and displays it as "Property : Value"... without having to define each Property first. That's  what I'm looking for in AutoIt.

 

WMI Explorer 2 Powershell example:

$computer = $env:COMPUTERNAME
$namespace = "ROOT\CIMV2"
$classname = "Win32_PerfRawData_Tcpip_NetworkInterface"

 

Get-WmiObject -Class $classname -ComputerName $computer -Namespace $namespace |

    Select-Object * -ExcludeProperty PSComputerName, Scope, Path, Options, ClassPath, Properties, SystemProperties, Qualifiers, Site, Container |
    Format-List -Property [a-z]*

 

 

 

 

WMI Explorer 2 Powershell example output:

BytesReceivedPersec             : 105906295
BytesSentPersec                 : 1472390918
BytesTotalPersec                : 1578297213
Caption                         :
CurrentBandwidth                : 1000000000
Description                     :
Frequency_Object                : 0
Frequency_PerfTime              : 3521210
Frequency_Sys100NS              : 10000000
Name                            : Intel[R] 82579V Gigabit Network Connection
OffloadedConnections            : 0
OutputQueueLength               : 0
PacketsOutboundDiscarded        : 0
PacketsOutboundErrors           : 0
PacketsPersec                   : 1440415
PacketsReceivedDiscarded        : 0
PacketsReceivedErrors           : 0
PacketsReceivedNonUnicastPersec : 23105
PacketsReceivedPersec           : 313482
PacketsReceivedUnicastPersec    : 290377
PacketsReceivedUnknown          : 0
PacketsSentNonUnicastPersec     : 3858
PacketsSentPersec               : 1126933
PacketsSentUnicastPersec        : 1123075
Timestamp_Object                : 0
Timestamp_PerfTime              : 13100603957
Timestamp_Sys100NS              : 131179061249680000

Edited by Irios

Share this post


Link to post
Share on other sites

@Irios if you're looking for both the property name and the value in a single pass I would do something like this:

Local $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Local $oItems = $oWMI.ExecQuery("Select * FROM Win32_PerfRawData_Tcpip_NetworkInterface")
    For $sItem In $oItems
        For $sProperty In $sItem.Properties_
            ConsoleWrite($sProperty.Name & ": " & $sProperty.Value & @CRLF)

        Next
    Next

 Just be aware that some properties may return an array rather than a string. So you might have to code a For loop to gather all the values.


"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Share this post


Link to post
Share on other sites

Oke @Irios I understand what you mean. Very interesting problem. I spend a hour or so to play a bit with the concept but i can't get it to work :( Anyway this is my try.

Local $strComputer = "."
Local $strNameSpace = "root\cimv2"
Local $strClass = "Win32_PerfRawData_Tcpip_NetworkInterface"
Local $objClass = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\" & $strNameSpace & ":" & $strClass)

Local $objWMIService = ObjGet("winmgmts:\\" & "." & "\root\CIMV2")

Local $colItems
For $objProperty In $objClass.Properties_
    ConsoleWrite ( "=========> " & $objProperty.Name & " " )
    $colItems = $objWMIService.ExecQuery("SELECT " & $objProperty.Name & " FROM Win32_PerfRawData_Tcpip_TCP")
    For $objItem in $colItems
        ; Oke does not work but we are in the loop so something is going on here.
        Local $sValue = Execute ($objItem.Name)     ; attempt to retrieve the contents of $objItem.Name rather then the object.property itself.
        ConsoleWrite ( "Value : " & $sValue & @CRLF )
    Next
Next

 

Share this post


Link to post
Share on other sites
28 minutes ago, JLogan3o13 said:

@Irios if you're looking for both the property name and the value in a single pass I would do something like this:

../..

Super thanks, @JLogan3o13

That was exactly what I was looking for!

 

 

 

Share this post


Link to post
Share on other sites

@JLogan3o13 Yup good job! This was exactly where i was after but now i see you use ExecQuery and i used the code posted earlier in the topic.

Local $strComputer = "."
Local $strNameSpace = "root\cimv2"
Local $strClass = "Win32_PerfRawData_Tcpip_NetworkInterface"

Local $objClass = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\" & $strNameSpace & ":" & $strClass)
For $objClassProperty In $objClass.Properties_
    ConsoleWrite($objClassProperty.Name & @CRLF)
    ConsoleWrite($objClassProperty.Value & @CRLF)   ; does not work!!!
Next

In this case there isn't a .Value so i tried to program around it. Which wasn't a succes :P Thanks for sharing your'e code. Excellent! (y)

Share this post


Link to post
Share on other sites

So, now that I have a solution, I still don't understand how to know where to use ".Properties_" and what I might expect find inside it. I do know in regard of WMI Classes and their Properties, of course. That's what this example was about.

Is there some kind of reference where i can learn about this? You have no idea the amount of time I've spent on this little problem now, and I'm not really getting anywhere. Just copying in a solution given by someone else doesn't really provide the basis for expanding and exploring these objects further.

I've had a look at OleView.Exe, but that doesn't help me at all. Just as stuck. I can't even find any wmi classes or namespaces in there :/

 

Share this post


Link to post
Share on other sites

@pluto41

I've more or less already tried those approaches you suggested, in one way or another. And, yeah you can sort of make it do the job, but not in a very efficient way. I really wanted a way do it "in one go". After all, PS and WMIC could do it. I knew it was possible, I just couldn't figure it out myself.

Share this post


Link to post
Share on other sites

@Irios the only way you're going to learn WMI in depth is to do a lot of reading: https://msdn.microsoft.com/en-us/library/aa394582(v=vs.85).aspx


"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Share this post


Link to post
Share on other sites

Yeah, the basics of WMI (retrieving data) isn't something I'm struggling with, to be honest. I've been using WMIC and WQL for quite a while, so I know those things pretty good now.

But using objects to retrieve data from WMI is brand new to me. COM, WBEM, etc. I really don't know where to start. It's quite overwhelming, and I figured if I'd just get a few starters by googling some practical examples, I might figure it out by myself. But no, haha. Like you say, I've obviously got a lot of reading ahead of me :D

Edited by Irios
letters and words

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Colduction
      Hi AutoIt Programmers!

      I've seen a code that gives Name of Group by writing it's group's SID, but this one response very slower than Windows Command-Line WMIC
       
      Func _GetLocalGroupName($sSID = 'S-1-5-18') $objWMIService = ObjGet ("winmgmts:\\" & @ComputerName & "\root\cimv2") $colItems = $objWMIService.ExecQuery('SELECT Name FROM Win32_Group where SID="' & $sSID & '"') For $GroupNames in $colItems MsgBox (0,"",$GroupNames.Name) ExitLoop Next EndFunc I don't want call and use any third-party programs even CMD, i just want use from Windows API, netapi32.dll or AutoIt Functions (Standalone).
      Do you have any idea to improve speed/performance of this code? I'll happy of your comments
       
       
       
      ====================== SOLOUTION by @Subz ======================
       
    • By jresine
      Hello, is it possible to know via a script or command, to have the percentage of disk usage of a process? thank you in advance.
      ps: see image

    • By Dwalfware
      HI
      Another head scratched
      Anyone solve how to get the IPV6 from WMI?
      I followed the usual SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionID='" & GUICtrlRead($cboAdapters) & "'
      get the index 
      port it to 
      Local $query = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = " & _GetSelectedNIC(), "WQL", 0x30 )
      All i can see is IPv4 addresses
      My question is is there another place the IPv6 information is hiding? I configured my LAN with IPV6 and my wireless with IPv4 so I can see what shows.
      Thanks in Advance.
      PS. I did try google
       
    • By Dwalfware
      Hi Folks
      Can not get my head around this one.
      This function gets the DNS object s
      If you have two DNS entries fine. but if you have only one! Trouble
      $objItem.DNSServerSearchOrder[0] = Primary DNS
      $objItem.DNSServerSearchOrder[1] = Secondry DNS not always there. I need a way to return 0 if not there or the IP if its there.
      Or is there a way to tell how many objects there are in the "[?]"
      I'm terrible at WMI errors, thanks for help in advance.
      Func _GETcurrentNICinfo2() $oErrors = ObjEvent("AutoIt.Error", "Error_Handle") Local $DnsSecondry Local $objWMIService = ObjGet( "winmgmts:\\" & @ComputerName & "\root\CIMV2" ) Local $query = $objWMIService.ExecQuery("SELECT DNSServerSearchOrder FROM Win32_NetworkAdapterConfiguration WHERE Index = " & _GetSelectedNIC(), "WQL", 0x30 ) If @error Then Return 0 If NOT IsObj($query) Then Return 0 Else For $objItem In $query Return $objItem.DNSServerSearchOrder[1] next Endif EndFunc  
    • By amin84
      Hello,
      I'm having trouble getting information from Win32_Processor:
      https://docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-processor
      How does this WMI Query work? Let's say I need to query VMMonitorModeExtensions, Level, ProcessorId, and ProcessorType.
      How would this work?
      Thanks.
×
×
  • Create New...