Tripredacus Posted June 23, 2010 Posted June 23, 2010 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 Twitter | MSFN | VGCollect
PsaltyDS Posted June 23, 2010 Posted June 23, 2010 (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. Edited June 24, 2010 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
sahsanu Posted June 23, 2010 Posted June 23, 2010 (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: Cheers, sahsanu Edited June 23, 2010 by sahsanu kristoff1313 1
Tripredacus Posted June 24, 2010 Author Posted June 24, 2010 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 Twitter | MSFN | VGCollect
PsaltyDS Posted June 24, 2010 Posted June 24, 2010 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. 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
Tripredacus Posted June 25, 2010 Author Posted June 25, 2010 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. Twitter | MSFN | VGCollect
Tripredacus Posted July 1, 2010 Author Posted July 1, 2010 (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. Oh, PS, here is what got written into the log file on the last run: 2010-07-01 11:09:09 : BTLD9310003Q DB43LD Edited July 1, 2010 by Tripredacus Twitter | MSFN | VGCollect
PsaltyDS Posted July 1, 2010 Posted July 1, 2010 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. 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
Tripredacus Posted July 2, 2010 Author Posted July 2, 2010 (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 July 2, 2010 by Tripredacus Twitter | MSFN | VGCollect
PsaltyDS Posted July 2, 2010 Posted July 2, 2010 (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. Edited July 2, 2010 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
Tripredacus Posted July 6, 2010 Author Posted July 6, 2010 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 Twitter | MSFN | VGCollect
Queener Posted May 17, 2013 Posted May 17, 2013 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:scriptomatic.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.")
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now