Jump to content
Bilgus

WMI Enumerate all CIMv2 Classes and show a Few Examples of enumerating properties

Recommended Posts

Bilgus
Posted (edited)
#include <Array.Au3>
;WMI EXAMPLE
Local $strComputer = "localhost"
Local $sClass = ""
Local $objClass

Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")

; Display all available Classes in this object

_ArrayDisplay(Get_Classes($objWMIService), "AVAILABLE WMI CLASSES", "", 0, Default, "NAME") ;Split string at \n(@LF) place each into an array

$sClass = "Win32_BIOS" ;<-The Class I've choosen
;Lets Try out one of the classes
Local $objClass = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2:" & $sClass)

ConsoleWrite($sClass & @CRLF & "------------------------------------------" & @CRLF)

_ArrayDisplay(Split_Properties(Get_Properties($objClass)), $sClass & " Properties", "", 0, Default, "NAME|VALUE")

;No methods available for this one but...
ConsoleWrite("Methods:" & @CRLF & @CRLF)
Get_Methods($objClass)

;Lets Do it again for the network adapter Class
$sProperties = ""
$sClass = "Win32_NetworkAdapterConfiguration" ;<-The Class I've choosen
;Lets Try out one of the classes
$objClass = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2:" & $sClass)

ConsoleWrite($sClass & @CRLF & "------------------------------------------" & @CRLF)

_ArrayDisplay(Split_Properties(Get_Properties($objClass)), $sClass & " Properties", "", 0, Default, "NAME|VALUE")

ConsoleWrite("Methods:" & @CRLF & @CRLF)
Get_Methods($objClass)

Func Get_Classes($obj)
    ; Display all available Classes in this object
    If IsObj($obj) Then
        Local $sClasses = ""
        For $objClass In $obj.SubclassesOf() ;<--WMI Method
            $sClasses &= ($objClass.Path_.Class) & @LF ;Build a string seperated by \n(@LF)
        Next
    EndIf
    Return StringSplit($sClasses, @LF)
EndFunc   ;==>Get_Classes

Func Get_Methods($objClass)
    Local $sResults = ""
    If IsObj($objClass) Then
        For $objMethods In $objClass.Methods_
            ConsoleWrite(@TAB & $objMethods.Name & @CRLF)
            $sResults &= $objMethods.Name & @LF
        Next
    EndIf
    Return $sResults
EndFunc   ;==>Get_Methods

Func Get_Properties($objClass)
    Local $sProperties = ""
    If IsObj($objClass) Then
        For $objClassProp In $objClass.Properties_() ;<-Another WMI Method
            For $obj In $objWMIService.ExecQuery("Select * from " & $sClass) ;<-Another WMI Method
                $sProperties &= $objClassProp.Name & @CR
                $sProperties &= Parse_Value($obj.Properties_($objClassProp.Name).Value) ;Use the Properties_ Method to call our desired property
            Next
        Next
    EndIf
    Return $sProperties
EndFunc   ;==>Get_Properties

Func Parse_Value($vValue)

    Local $sRet = ""
    Switch StringLower(VarGetType($vValue))
        Case "keyword" ; Not really sure what this one is probably NULL
            $sRet = Number($vValue) = 0 ? "" : Number($vValue)
        Case "array"
            $sRet = _ArrayToString($vValue, ", ")
        Case "string", "bool", "int32", "int64", "double", "binary"
            $sRet = $vValue
        Case "pointer"
            $sRet = "[PTR]:" & $vValue
        Case Else
            $sRet = "[" & VarGetType($vValue) & "]: " & $vValue
    EndSwitch
    $sRet &= @LF
    Return $sRet
EndFunc   ;==>Parse_Value

Func Split_Properties($sProperties)
    Local $aDisp = StringSplit($sProperties, @LF) ;Split string at \n(@LF) place each into an array
    Local $aTmp
    If IsArray($aDisp) Then
        _ArrayColInsert($aDisp, 1)

        For $i = 1 To $aDisp[0][0] ; String Split stores Count in the first element by default
            $aTmp = StringSplit($aDisp[$i][0], @CR) ;Split string at \r(@CR) place each into an array
            If IsArray($aTmp) Then
                $aDisp[$i][0] = $aTmp[0] > 0 ? $aTmp[1] : "?" ;Check if this element exists if not make it "?"
                $aDisp[$i][1] = $aTmp[0] > 1 ? $aTmp[2] : " " ;Check if this element exists if not make it " "
            EndIf
        Next
    EndIf
    Return $aDisp
EndFunc   ;==>Split_Properties

 

Edited by Bilgus

Share this post


Link to post
Share on other sites
JLogan3o13

Just curious, this is great at displaying the classes returned, but to interact with them a user would still need different code. Why not just use Scriptomatic?

  • Like 1
  • Thanks 1

√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
Bilgus
Posted (edited)

I'm not sure What the scriptomatic is??

 

 

We are sorry, the page you requested cannot be found.

The URL may be misspelled or the page you're looking for is no longer available.

 

 

Ok I got it pretty neat little script I put the description of it in the comments for ScriptoMatic

Edited by Bilgus

Share this post


Link to post
Share on other sites
Bilgus

I like having a little easily digestible info that shows a few point I actually made this for a seeker but I put this here for the next one(s)

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

  • Similar Content

    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      I'm working on a little project of mines, and I was trying to use WMI Object.
      The question which I don't find an answer is: 
      Once I do the query with WMI Object, something like "SELECT * FROM Win32_LogonSession", instead of specify the field of the collection returned, ( i.e. $colItems.Caption ), can I loop though each property and each value of the property, writing so one row of code only?
      Hope my question was clear enough.
      Thanks in advance.

      Best Regards.
    • ahmet
      By ahmet
      Hello,
      I am trying to make a program that will uninstall some software, provided by some form of a list. I have this
      ; Generated by AutoIt Scriptomatic June 08, 2010 ;#RequireAdmin $sPartialName="java" $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = "localhost" ;$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") ;$objWMIService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") $objWMIService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Product", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) then For $objItem In $colItems If StringInStr($objItem.Name,$sPartialName)=1 Then ConsoleWrite("Full name:" & $objItem.Name & @CRLF) RunAs("USERNAME",@ComputerName,"PASSWORD",0,@ComSpec & " /c" & ' wmic product where name="Java 9.0.4 (64-bit)" call uninstall /nointeractive',"C:\WINDOWS\system32\wbem",@SW_MAXIMIZE) ;Run('wmic product where name="Java 9.0.4 (64-bit)" call uninstall /nointeractive',"",@SW_MAXIMIZE) ExitLoop EndIf Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Product" ) Endif The script above fails uninstalling software despite providing username and password for admin account. If I run script with admin rights then the software gets uninstalled.
      At the following link there is a script by JLogan3o13 but it does not either uninstall software, unless run as admin..
      Is there some way to uninstall software using wim or wimc by providing user name and password?
       
    • nikink
      By nikink
      Hi all,
      I have a bit of code that works on my old Win10 PC, that fails on my new Win10 PC, and I think the only significant difference is the version of Autoit - old PC has 3.3.12, new has 3.3.14.
      I couldn't find anything mentioned in the change logs though, so perhaps I'm wrong.
      Anyway, the code to replicate my issue is:
      Test('username', 'DOMAIN') ; THIS ERRORS: ;Test('localun', 'DOMAIN') ; THIS ERRORS: ;Test(' ', ' ') ; THIS ERRORS: ;Test('', '') ; THIS ERRORS: ;Test('localun', '') ; THIS ERRORS: ;Test('', 'DOMAIN') Func Test($un, $dom) $compName = 'PCNAME' $FullName = '.' $Description = '.' ; get the WIM object $objWMIService = ObjGet("winmgmts:\\" & $compName & "\root\cimv2") ; get default user full name and description $objAccount = $objWMIService.Get("Win32_UserAccount.Name='" & $un & "',Domain='" & $dom & "'") If IsObj($objAccount) Then $FullName = $objAccount.FullName $Description = $objAccount.Description EndIf ConsoleWrite($FullName & @CRLF) ConsoleWrite($Description & @CRLF) Return EndFunc  
      On my old PC this code will output just . and . for each of those line currently commented out. Which is fine.
      On my new PC any of those commented out lines of code cause an error, and the script won't even compile.
      $objAccount = $objWMIService.Get("Win32_UserAccount.Name='" & $un & "',Domain='" & $dom & "'") $objAccount = $objWMIService^ ERROR I'm very much a newb with the WMI stuff and objects, but it looks like the .Get property is failing when either $un or $dom aren't valid in v3.3.14, whereas in 3.3.12 the .Get would fail to return an object, which is then caught by the If statement.
      Am I on track with this? Is there some new/better way to code the example so that 3.3.14 will compile it?
    • ModemJunki
      By ModemJunki
      Edit: I found out from looking into the post from coffeeturtle that not all motherboards support WMI temperature reading. You have to explore the WMI namespaces for your system!
      I (stupidly) fried a computer. It was an old Zotac small form factor device that was junked at work, so I turned it into a home theater PC.
      But I had put it in my "audio rack", which has glass doors and not very good ventilation. Normally I would open the doors while it was running and I use a media remote which would hibernate the system. At some point, it woke up by itself (probably Windows Update) and did not go to sleep again. Unfortunately this happened during the summer months while I was away on a small holiday and of course the glass doors were closed.
      When I finally noticed the system was on, it was super hot and the fan was at full blast. Dead. No POST, no green light on the mainboard even with a new power supply, old mechanical laptop hard drive gives errors when connected to another device. My next home project will be to make some appropriate ventilation in the audio cabinet.
      For the replacement I bought a used HP ultra small form factor machine and decided to start working on an app to monitor the ambient temperature sensor on the motherboard and shutdown the system if needed. I used some code for smooth label updates from here (needed updating to work with latest AutoIT) and temperature conversion from here (not really needed, only if you want temperatures in something other than C).
      Maybe I will work on this some more and make it configurable with an .INI file or even storing the settings in registry, but since I probably won't I thought I'd put it up as an example of what a non-expert can do with an afternoon of coding and ideas from the community here.
      This uses an ambient temperature sensor populated on HP machines in HP-specific WMI extensions but the WMI query can easily be changed to any available sensor including CPU or GPU.
      The watchdog monitors temperature, warns with S.O.S beeping if the set point is exceeded, and either shuts down if a timeout is reached while the temperatures are high or goes back to monitoring if the temperature goes lower then the set point, and logs events to the Windows application event logs.
      The GUI it puts up is very small at the top center of the screen (very small on a 4k display anyway).
      #requireadmin because of the WMI query.
      A timer for the WMI query because of prior experience using similar functions in WinPE to get model infos from HP WMI bios extensions.
      If you play around with this, please post your fixes/improvements/changes back to this thread.
      Have fun!
      Edit: Updated to show "Unable to query temperature" if the WMI query returns a null
      #AutoIt3Wrapper_Icon=temperature-2-multi-size.ico #RequireAdmin #NoTrayIcon #include <Temperature.au3> #include <FFLabels.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Global $winLogger = "C:\WINDOWS\system32\eventcreate.exe" ; application to use for event logging Global $MessageSource = "HP TempMon" Global $width = 185 Global $height = 15 Global $FontSize = 8 Global $FontFamily = 'Microsoft Sans Serif' Global $normClr = 0xFF000000 Global $warnClr = 0xFF0000 Global $WMInameSpace = "HP_BIOSNumericSensor" ;~ Global $WMIReadSensor = "Chassis Thermal Index" ; HP 8300 Global $WMIReadSensor = "System Ambient Temperature" ; HP Z400 Global $warnTmp = 46.1111111111 ; degrees C ;~ Global $warnTmp = 24 ; degrees C for testing Global $ovrtmpTime = 5 ; in minutes Global $hGUI = GUICreate("Board Temperature", $width, $height, -1, 0, BitOR($WS_SYSMENU, $WS_POPUP), BitOR($WS_EX_TOPMOST, $WS_EX_WINDOWEDGE, $WS_EX_TOOLWINDOW)) Global $lb1 = _GUICtrlFFLabel_Create($hGUI, "", -1, -1, $width, $height, 8, -1, 0, 1, $normClr) GUISetState(@SW_SHOW) _TempSenseLoop() Func _TempSenseLoop() While 1 Sleep(250) $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE GUIDelete($hGUI) Return Case Else $s_ambTempC = _doQueryHPNumSens(5, $WMInameSpace, $WMIReadSensor, "100") ; + 100 Select Case $s_ambTempC = "" _GUICtrlFFLabel_SetTextColor($lb1, $normClr) _GUICtrlFFLabel_SetData($lb1, "Unable to query temperature") Case $s_ambTempC < $warnTmp _GUICtrlFFLabel_SetTextColor($lb1, $normClr) _GUICtrlFFLabel_SetData($lb1, "Board temperature: " & $s_ambTempC & "C" & "/" & Round(_CelsiusToFahrenheit($s_ambTempC), 0) & "F") Case Else _GUICtrlFFLabel_SetTextColor($lb1, $warnClr) _GUICtrlFFLabel_SetData($lb1, "Board temperature: " & $s_ambTempC & "C" & "/" & Round(_CelsiusToFahrenheit($s_ambTempC), 0) & "F") _doLog("System ambient temperature has exceeded " & $warnTmp & "C.", "WARN", $MessageSource) _AlarmMonitor($ovrtmpTime, $warnTmp) EndSelect EndSwitch WEnd EndFunc ;==>_TempSenseLoop Func _AlarmMonitor($min, $tmp) Local $Shutdown = 1 Local $s_ambTemp Local $freq = 3500 Local $shrt = 200 Local $long = 500 Local $timer = TimerInit() Local $wait = 1000 * ($min * 60) While TimerDiff($timer) < $wait $s_ambTemp = _doQueryHPNumSens(5, $WMInameSpace, $WMIReadSensor, "100") ; + 100 If $s_ambTemp >= $tmp Then _GUICtrlFFLabel_SetData($lb1, "WARNING! OVERTEMP!") Beep($freq, $shrt) Beep($freq, $shrt) Beep($freq, $shrt) Sleep(250) Beep($freq, $long) Beep($freq, $long) Beep($freq, $long) Sleep(250) Beep($freq, $shrt) Beep($freq, $shrt) Beep($freq, $shrt) _GUICtrlFFLabel_SetData($lb1, "Board temperature: " & $s_ambTemp & "C" & "/" & _CelsiusToFahrenheit($s_ambTemp) & "F") Sleep(2000) ElseIf $s_ambTemp < $tmp Then $Shutdown = 0 ExitLoop EndIf WEnd If $Shutdown = 1 Then _doLog("The system is shutting down due to overtemperature conditions. The temperature at the time of shutdown was " & $s_ambTemp & "C" & "/" & _CelsiusToFahrenheit($s_ambTemp) & "F", "ERRR", $MessageSource) Shutdown(24) ElseIf $Shutdown = 0 Then _doLog("System ambient temperature has been reduced below " & $warnTmp & "C.", "INFO", $MessageSource) EndIf EndFunc ;==>_AlarmMonitor Func _doQueryHPNumSens($min, $class, $name, $sleep) ; $sleep = milliseconds Local $s_tempReading = "" Local $s_HPBiosWMIService = "winmgmts:\\" & @ComputerName & "\Root\HP\InstrumentedBIOS" Local $objHPBiosWMIService = ObjGet($s_HPBiosWMIService) Local $s_biosQuery = $objHPBiosWMIService.ExecQuery("select * from " & $class & " where Name='" & $name & "'") $timer = TimerInit() ; we may need to wait for the HP WMI extensions to enumerate in WMI, in WinPE this takes some minutes. $wait = 1000 * ($min * 60) If Not IsObj($s_biosQuery) Then ; we do need to wait, put up a splash screen $s_WMISplash = 1 SplashTextOn("WMI", "Probing WMI (up to 10 minutes)...", 300, 50, -1, -1, 1) Sleep(1000) While TimerDiff($timer) < $wait Sleep(500) $objHPBiosWMIService = ObjGet($s_HPBiosWMIService) If IsObj($objHPBiosWMIService) Then Sleep(500) $colProdName = $s_biosQuery If IsObj($colProdName) Then For $oItem In $colProdName $s_tempReading = $oItem.CurrentReading Next EndIf EndIf WEnd ElseIf IsObj($s_biosQuery) Then ConsoleWrite($s_biosQuery & @CRLF) For $oItem In $s_biosQuery $s_tempReading = $oItem.CurrentReading Next Else $s_tempReading = 0 EndIf Sleep($sleep) Return $s_tempReading EndFunc ;==>_doQueryHPNumSens Func _doLog($message, $type, $msgsrc) Select Case $type = "INFO" $logTyp = "INFORMATION" Case $type = "WARN" $logTyp = "WARNING" Case $type = "ERRR" $logTyp = "ERROR" EndSelect If FileExists($winLogger) Then RunWait(@ComSpec & " /c " & $winLogger & " /L Application /T " & $logTyp & " /SO " & Chr(34) & $msgsrc & Chr(34) & " /ID 1000 /D " & Chr(34) & $message & Chr(34), "", @SW_HIDE) EndIf EndFunc ;==>_doLog  
       
       
      Temperature.au3
      FFLabels.au3
      HP_Temp.au3
    • ModemJunki
      By ModemJunki
      Hello,
      In Windows 10 PowerShell, one can do this to change the metric for a NIC in Windows 10:
      Get-NetAdapter | Where-Object -FilterScript {$_.InterfaceAlias -Eq "Ethernet 2"} | Set-NetIPInterface -InterfaceMetric 2 I know I can script the above PowerShell line (and it works!), but I wanted to try something I hadn't done before after looking into jguinch's most excellent Network configuration UDF. I wanted to make use of the SetIPConnectionMetric method in the WMI classes. There is an example VBscript here but this is not for Windows 10. Using AutoIT would also give better control over capturing error return codes than with PowerShell.
      But I cannot get my script to work! The return from SetIPConnectionMetric() is 0, which would indicate success. Yet the change does not happen. I also tried WMI methods using .put_ but this fails.
      Anyone more experienced than I have ideas to make this work?
      #RequireAdmin _SetNicInterfaceMetric2("Ethernet 2", "2") Func _SetNicInterfaceMetric2($NIC_NAME, $METRIC) Local $s_setIndx = 0 $objWMIService = ObjGet("winmgmts:{impersonationLevel = impersonate}!\\" & "." & "\root\cimv2") $colNICItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionID = '" & $NIC_NAME & "'", "WQL") If IsObj($colNICItems) Then For $objItem In $colNICItems $s_nicIndex = $objItem.Index Next ConsoleWrite("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = '" & $s_nicIndex & "'" & @CRLF) $colNAC = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = '" & $s_nicIndex & "'", "WQL") If IsObj($colNAC) Then For $objNetCard In $colNAC If $METRIC <> $objNetCard.IPConnectionMetric Then ConsoleWrite("Metric was set to " & $objNetCard.IPConnectionMetric & ". Setting to " & $METRIC & "." & @CRLF) $s_isSet = $objNetCard.SetIPConnectionMetric($METRIC) ConsoleWrite("SetIPConnectionMetric Result = " & $s_isSet & @CRLF) Else ConsoleWrite("Metric is already set to " & $METRIC & @CRLF) EndIf Next EndIf EndIf EndFunc ;==>_SetNicInterfaceMetric2  
×