Jump to content

Recommended Posts

Posted

I've been trying to get a new script written that pulls 1 value from WMI and puts it in a variable. I had tons of problems with the whole "not an object thing" but managed to fix it myself via ye olde forum search. I am basing this script off a VBScript I already have and use and it works fine, but running a VBS isn't going to be an option.

Currently, while I can finally connect to WMI, I can't get the value displayed in MsgBox. I am also not sure how to use the FOR. The VBScript uses FOR EACH and then does a bunch of stuff, but I don't need that. I am using MsgBox for now to test, but eventually my program is going to take that info and stick it in a Text file.

My result atm is that I get the debug MsgBox with nothing in it. What am I missing here?

Global $itdid, $date, $strComputer, $objWMIService, $colItems, $sWMIService
$date = (@MON & "-" & @MDAY & "-" & @YEAR)
$strComputer = "."
$sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2"
$objWMIService = ObjGet($sWMIService)
IF IsObj($objWMIService) Then
$colItems = $objWMIService.ExecQuery("SELECT Model FROM Win32_BaseBoard")
    MsgBox (4096, "debug", $colItems )
ELSE 
    MsgBox (4096, "ERROR", "Failed to connect to WMI at: " & $sWMIService)
EndIf

I am also testing out what it pulls. Likely it won't be Model from Win32_BaseBoard, but I can't get any information to show up in the MsgBox. Full WMI information is here:

http://vbnet.mvps.org/code/wmi/win32_baseboard.htm

Posted (edited)

The $colItems is an object itself. A 'collection object' to be specific. It's like an array of objects. So you have to go through the elements in the collection (even if there's only one). Usually with a For/In/Next loop:

Global $objWMIService, $colItems, $sWMIService, $sName, $sModel

$sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2"
$objWMIService = ObjGet($sWMIService)
If IsObj($objWMIService) Then
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard")
    If IsObj($colItems) Then
        For $oItem In $colItems
            $sName = $oItem.name
            $sModel = $oItem.model
            MsgBox(64, "Win32_BaseBoard Item", "Name = " & $sName & @CRLF & _
                    "Model = " & $sModel)
        Next
    Else
        MsgBox(16, "Error", "Faile to get Win32_BaseBoard collection.")
    EndIf
Else
    MsgBox(4096, "ERROR", "Failed to connect to WMI at: " & $sWMIService)
EndIf

Edit: Corrected WQL query per Tripredacus.

:mellow:

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted (edited)

I am also testing out what it pulls. Likely it won't be Model from Win32_BaseBoard, but I can't get any information to show up in the MsgBox.

Maybe this could be useful to you. AutoIt Scriptomatic is a wonderful and "hide" tool that you can use to check and learn from a lot of WMI examples... and if you installed Full Scite4AutoIt version the you have it already.

ShellExecute(@ProgramFilesDir & "\AutoIt3\Examples\COM\Scriptomatic.au3")

And here just a screenshot so you know what I mean:

post-43958-12773305118507_thumb.png

Cheers,

sahsanu

Edited by sahsanu
Posted

The $colItems is an object itself. A 'collection object' to be specific. It's like an array of objects. So you have to go through the elements in the collection (even if there's only one). Usually with a For/In/Next loop:

Global $objWMIService, $colItems, $sWMIService, $sName, $sModel

$sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2"
$objWMIService = ObjGet($sWMIService)
If IsObj($objWMIService) Then
    $colItems = $objWMIService.ExecQuery("SELECT Model FROM Win32_BaseBoard")
    If IsObj($colItems) Then
        For $oItem In $colItems
            $sName = $oItem.name
            $sModel = $oItem.model
            MsgBox(64, "Win32_BaseBoard Item", "Name = " & $sName & @CRLF & _
                    "Model = " & $sModel)
        Next
    Else
        MsgBox(16, "Error", "Faile to get Win32_BaseBoard collection.")
    EndIf
Else
    MsgBox(4096, "ERROR", "Failed to connect to WMI at: " & $sWMIService)
EndIf

Ah I get to correct the great PSalty! JK anyways, the above code you posted actually failed IF only selecting 1 specific entry instead of using a wildcard. The reason is that .name would not exist if you pulled just model. Luckily I figured it out. Here is the complete (censored) code, presuming we can use the info that is pulled. I initially wanted to get the motherbaord serial number, but it does not appear this is something WMI can read. If you know otherwise, LMK! Thanks PSalty!

#include <file.au3>
Global $var, $objWMIService, $colItems, $sWMIService, $sName, $sModel
$var = RegRead ( "HKEY_LOCAL_MACHINE\SOFTWARE\Generic Registry","Key" )
$sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2"
$objWMIService = ObjGet($sWMIService)
IF IsObj($objWMIService) Then
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard")
If IsObj($colItems) Then
        For $oItem In $colItems
            $sName = $oItem.Product
            $sModel = $oItem.Version
            _FileWriteLog(@ScriptDir & "\my.log", $sName & " " & $sModel & " " & $var)
            MsgBox(64, "Win32_BaseBoard Item", "Product = " & $sName & @CRLF & "Version = " & $sModel & @CRLF & "ITD ID = " & $var & @CRLF & "Log file Updated")
        Next
    Else
        MsgBox(16, "Error", "Failed to get Win32_BaseBoard collection.")
    EndIf
Else
    MsgBox(4096, "ERROR", "Failed to connect to WMI at: " & $sWMIService)
EndIf
Posted

Some WMI elements are provided only if your motherboard's BIOS and the Windows driver provide by the MB manufacturer support it. I get nothing for about half the available Win32_BaseBoard class properties available.

:mellow:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

Yes this is designed specifically for Intel boards in mind. I had to rename the registry key I pulled because I'm pretty sure that information is under NDA for me. But even on Intel boards, a lot is blank also, and some things just return 'Base Board' for some reason. Oh well.

Posted (edited)

I got to the point where I figured I need to make two different WMI queries and output the data to a MsgBox and the log file. But I am not getting the data I need. I am trying to convert a VBS and put it in the script also. And since finding this info is in the public domain I can post the full script.

To start, here is the VBS code, from this page:

http://www.windowsnetworking.com/articles_tutorials/Deploying-Windows-7-Part18.html

'UUID.vbs
'Displays the UUID of a computer
'By Mitch Tulloch (www.mtit.com)
strComputer = "."
strWMINamespace = "\root\CIMV2"
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct")
For Each objSWbemObject In colSWbemObjectSet
   strIdentifyingNumber = objSWbemObject.IdentifyingNumber
   strName = objSWbemObject.Name
   strVersion = objSWbemObject.Version
Next
strWMIQuery = ":Win32_ComputerSystemProduct.IdentifyingNumber='" & strIdentifyingNumber _
   & "',Name='" & strName & "',Version='" & strVersion & chr(39)
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace & strWMIQuery)
For Each objItem in objWMIService.Properties_
    If objItem.name =  "UUID" Then
        Wscript.Echo objItem.name & " = " & objItem.value
    End If
Next

This is to pull the UUID from a bare metal system for use in MDT. I am not using MDT but I need the same info. The reason I am going this route is because in XP, this info is kept in the registry, but in Windows 7 you can only get it from the WMI. I am hoping I can get it from WMI in XP, haven't tested it yet. If I run this VBS, I can get the value back that I need which is great. However, coding it into AutoIT is not working properly. I am able to get the MsgBox up and the Log file is written to, but the value for UUID is null. Here is my modified AutoIT code. It passes SyntaxCheck and builds and "goes" obviously but there is nothing coming back.

#include <file.au3>
Global $itdid, $objWMIService, $colItems, $sWMIService, $sName, $sModel, $uuItem, $objSWbemObject, $strName, $strVersion, $strWMIQuery, $objItem, $uiDitem
;$itdid = RegRead ( "HKEY_LOCAL_MACHINE\SOFTWARE\Intel\PIcon\AMTData", "System UUID" )
$sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2"
$objWMIService = ObjGet($sWMIService)
IF IsObj($objWMIService) Then
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard")
    If IsObj($colItems) Then
        For $oItem In $colItems
            $sName = $oItem.Product
            $sModel = $oItem.SerialNumber
        Next
    EndIf
$uuItem = $objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct")
    If IsObj($uuItem) Then
        For $objSWbemObject IN $uuItem
            $strIdentifyingNumber = $objSWbemObject.IdentifyingNumber
            $strName = $objSWbemObject.Name
            $strVersion = $objSWbemObject.Version
        Next
    EndIf
$strWMIQuery = ":Win32_ComputerSystemProduct.IdentifyingNumber='" & $strIdentifyingNumber & "',Name='" & $strName & "',Version='" & $strVersion & chr(39)
$uiDitem = objGet($sWMIService & $strWMIQuery)
    If IsObj($uiDitem) Then
        For $objItem in $uiDitem.Properties_
            $itdid = $objItem.value
        Next
    _FileWriteLog(@ScriptDir & "\ITD.log", $sModel & " " & $sName & " " & $itdid)
    MsgBox(64, "Win32_BaseBoard Item", "SN = " & $sModel & @CRLF & "MB = " & $sName & @CRLF & "ITD ID = " & $itdid & @CRLF & "Log file Updated")
    EndIf
EndIf

FWIW, I tried asking our other developer to help me, and his response was "why don't you just learn a real programming language" so he's no help. :mellow:

Oh, PS, here is what got written into the log file on the last run:

2010-07-01 11:09:09 : BTLD9310003Q DB43LD

Edited by Tripredacus
Posted

Shouldn't your For/Next loops use "&=" vice just "=" to collect the values? At any rate, you need to add a COM Error handler (see OBJ/COM Reference in help file), and some error checking in your code. For example, everywhere you have "If IsObj() Then", include an "Else" clause to log/display the error when it's NOT an object.

:blink:

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted (edited)

The error handling didn't catch anything because there is no errors occuring. However, there seems to be a problem with the $strWMIQuery being able to read the data kept in $strIdentifyingNumber, $strName and $strVersion. This information is being seen as NULL values, which is why the $itdid is returning a NULL in the MsgBox and the log file.

So I am guessing that I converted the VBScript incorrectly? Or did I do something else wrong?

Also I am not sure what you mean by &= I am not seeing any code like that in any examples.

Edited by Tripredacus
Posted (edited)

I was thinking of places like this:

If IsObj($uuItem) Then
    For $objSWbemObject In $uuItem
        $strIdentifyingNumber = $objSWbemObject.IdentifyingNumber
        $strName = $objSWbemObject.Name
        $strVersion = $objSWbemObject.Version
    Next
EndIf

This only works if you absolutely assume there will only be one and exactly one $objSWbemObject in the $uuItem collection. If there should be more than one, you will only have values from the last time through the loop. You notice in most of the VBScript Scriptomatic examples, the values are displayed by Wscript.Echo from within the loop, so they are all displayed, regardless of how many are there.

But that's not a problem if there really is only one element in the collection. Back to the issue.

When I run this as VBScript:

'UUID.vbs
'Displays the UUID of a computer
'By Mitch Tulloch (www.mtit.com)
strComputer = "."
strWMINamespace = "\root\CIMV2"
Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct")
For Each objSWbemObject In colSWbemObjectSet
   strIdentifyingNumber = objSWbemObject.IdentifyingNumber
   Wscript.Echo "strIdentifyingNumber = " & strIdentifyingNumber
   strName = objSWbemObject.Name
   Wscript.Echo "strName = " & strName
   strVersion = objSWbemObject.Version
   Wscript.Echo "strVersion = " & strVersion
Next
strWMIQuery = ":Win32_ComputerSystemProduct.IdentifyingNumber='" & strIdentifyingNumber _
   & "',Name='" & strName & "',Version='" & strVersion & chr(39)
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace & strWMIQuery)
For Each objItem in objWMIService.Properties_
    If objItem.name =  "UUID" Then
        Wscript.Echo objItem.name & " = " & objItem.value
    End If
Next

I get this:

Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved.

strIdentifyingNumber = 1TZ8009P83
strName = HP xw4600 Workstation
strVersion =
UUID = 10D6E823-C4DC-1EBD-B1D8-7C53DDE00026

And running this in AutoIt:

; UUID.vbs
; Displays the UUID of a computer
; By Mitch Tulloch (www.mtit.com)
$strComputer = "."
$strWMINamespace = "\root\CIMV2"
$objSWbemServices = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")
$colSWbemObjectSet = $objSWbemServices.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct")
For $objSWbemObject In $colSWbemObjectSet
   $strIdentifyingNumber = $objSWbemObject.IdentifyingNumber
   ConsoleWrite("$strIdentifyingNumber = " & $strIdentifyingNumber & @LF)
   $strName = $objSWbemObject.Name
   ConsoleWrite("$strName = " & $strName & @LF)
   $strVersion = $objSWbemObject.Version
   ConsoleWrite("$strVersion = " & $strVersion & @LF)
Next
$strWMIQuery = ":Win32_ComputerSystemProduct.IdentifyingNumber='" & $strIdentifyingNumber _
   & "',Name='" & $strName & "',Version='" & $strVersion & chr(39)
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & $strWMINamespace & $strWMIQuery)
For $objItem in $objWMIService.Properties_
    If $objItem.name =  "UUID" Then
        ConsoleWrite($objItem.name & " = " & $objItem.value & @LF)
    EndIf
Next

I get this:

$strIdentifyingNumber = 1TZ8009P83
$strName = HP xw4600 Workstation
$strVersion =  
UUID = 10D6E823-C4DC-1EBD-B1D8-7C53DDE00026

strVersion doesn't come up in either. Maybe this motherboard/BIOS/OS/driver combo doesn't recognize that property for that object.

:blink:

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Posted

Ah I have figured it out. I probably didn't need to check for the UUID Name being present, but I had to put my log file and MsgBox action within the If statement that looks for the UUID. Even though my var was set for a global, the information seemed to disappear once the Next was called.

Also, you won't get all the same info running it on an HP. This is designed for Intel motherboards. Interesting you still got a UUID, I think this only appears if there is a management component on the board, not sure.

Here is the complete code. I still need to verify it works on XP.

#include <file.au3>
Global $itdid, $objWMIService, $colItems, $sWMIService, $sName, $sModel, $uuItem, $objSWbemObject, $strName, $strVersion, $strWMIQuery, $objItem, $uiDitem
;$itdid = RegRead ( "HKEY_LOCAL_MACHINE\SOFTWARE\Intel\PIcon\AMTData", "System UUID" )
$sWMIService = "winmgmts:\\" & @ComputerName & "\root\CIMV2"
$objWMIService = ObjGet($sWMIService)
IF IsObj($objWMIService) Then
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BaseBoard")
    If IsObj($colItems) Then
        For $oItem In $colItems
            $sName = $oItem.Product
            $sModel = $oItem.SerialNumber
        Next
    EndIf
$uuItem = $objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct")
    If IsObj($uuItem) Then
        For $objSWbemObject IN $uuItem
            $strIdentifyingNumber = $objSWbemObject.IdentifyingNumber
            $strName = $objSWbemObject.Name
            $strVersion = $objSWbemObject.Version
        Next
    Else
    MsgBox(4096, "ERROR", "Failed to connect to WMI at: " & $uiDitem)
    EndIf
$strWMIQuery = ":Win32_ComputerSystemProduct.IdentifyingNumber='" & $strIdentifyingNumber & "',Name='" & $strName & "',Version='" & $strVersion & chr(39)
$uiDitem = objGet($sWMIService & $strWMIQuery)
        For $objItem in $uiDitem.Properties_
If $objItem.name =  "UUID" Then 
    $itdid = $objItem.value
    _FileWriteLog(@ScriptDir & "\ITD.log", $sModel & " " & $sName & " " & $itdid)
    MsgBox(64, "Win32_BaseBoard Item", "SN = " & $sModel & @CRLF & "MB = " & $sName & @CRLF & "ITD ID = " & $itdid & @CRLF & "Log file Updated")
EndIf
        Next
EndIf
  • 2 years later...
Posted

Maybe this could be useful to you. AutoIt Scriptomatic is a wonderful and "hide" tool that you can use to check and learn from a lot of WMI examples... and if you installed Full Scite4AutoIt version the you have it already.

 

ShellExecute(@ProgramFilesDir & "\AutoIt3\Examples\COM\Scriptomatic.au3")

And here just a screenshot so you know what I mean:

attachicon.gifscriptomatic.png

Cheers,

sahsanu

 

Just what I'm looking for...

Thanks a bunch!

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...