darkleton Posted October 2, 2010 Share Posted October 2, 2010 I found a nice little vbs script that polls a remote machine, gets all the software installed and returns it in a csv/txt file. I've tried going through the vbs and altering it to au3 as some instructions from other posts (things like change Set to Dim, etc)I've done as much as I can in the script but can't seem to figure out the last few bits (or if most of it is correct!)I've attached both vbs and au3 (trimmed down from the vbs). If anybody could give any pointers on whats left to do. The script should bring up a message box, ask for machine name or ip, then go off to read the specified keys, work through the list and return only keys that have an uninstall string listed. it should then write them to a file as comma separated values. thanks in advanceMikeexpandcollapse popupOption Explicit Dim sTitle sTitle = "InstalledPrograms.vbs by Bill James" Dim StrComputer strComputer = InputBox("Enter I.P. or name of computer to check for " & _ "installed software (leave blank to check " & _ "local system)." & vbcrlf & vbcrlf & "Remote " & _ "checking only from NT type OS to NT type OS " & _ "with same Admin level UID & PW", sTitle) If IsEmpty(strComputer) Then WScript.Quit strComputer = Trim(strComputer) If strComputer = "" Then strComputer = "." 'Wscript.Echo GetAddRemove(strComputer) Dim sCompName : sCompName = GetProbedID(StrComputer) Dim sFileName sFileName = sCompName & "_Software_" & GetDTFileName & ".csv" Dim s : s = GetAddRemove(strComputer) If WriteFile(s, sFileName) Then 'optional prompt for display MsgBox "Finished Processing" & vbcrlf & vbcrlf & "Results saved to " & sFileName End If Function GetAddRemove(sComp) 'Function credit to Torgeir Bakken Dim cnt, oReg, sBaseKey, iRC, aSubKeys Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ sComp & "/root/default:StdRegProv") sBaseKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" iRC = oReg.EnumKey(HKLM, sBaseKey, aSubKeys) Dim sKey, sValue, sTmp, sUninstall, sDateValue, sYr, sMth, sDay For Each sKey In aSubKeys iRC = oReg.GetStringValue(HKLM, sBaseKey & sKey, "DisplayName", sValue) If iRC <> 0 Then oReg.GetStringValue HKLM, sBaseKey & sKey, "QuietDisplayName", sValue End If If sValue <> "" Then iRC = oReg.GetStringValue(HKLM, sBaseKey & sKey, _ "UninstallString", sUninstall) If sUninstall > "" Then sValue = sValue & "," & "Uninstall String: " & sUninstall End If sTmp = sTmp & sValue & vbcrlf cnt = cnt + 1 End If Next sTmp = BubbleSort(sTmp) GetAddRemove = "INSTALLED SOFTWARE" & "," & "UNINSTALL STRING" & vbcrlf & vbcrlf & sTmp End Function Function BubbleSort(sTmp) 'cheapo bubble sort Dim aTmp, i, j, temp aTmp = Split(sTmp, vbcrlf) For i = UBound(aTmp) - 1 To 0 Step -1 For j = 0 to i - 1 If LCase(aTmp(j)) > LCase(aTmp(j+1)) Then temp = aTmp(j + 1) aTmp(j + 1) = aTmp(j) aTmp(j) = temp End if Next Next BubbleSort = Join(aTmp, vbcrlf) End Function Function GetProbedID(sComp) Dim objWMIService, colItems, objItem Set objWMIService = GetObject("winmgmts:\\" & sComp & "\root\cimv2") Set colItems = objWMIService.ExecQuery("Select SystemName from " & _ "Win32_NetworkAdapter",,48) For Each objItem in colItems GetProbedID = objItem.SystemName Next End Function Function GetDTFileName() dim sNow, sMth, sDay, sYr, sHr, sMin, sSec sNow = Now sMth = Right("0" & Month(sNow), 2) sDay = Right("0" & Day(sNow), 2) sYr = Right("00" & Year(sNow), 4) sHr = Right("0" & Hour(sNow), 2) sMin = Right("0" & Minute(sNow), 2) sSec = Right("0" & Second(sNow), 2) GetDTFileName = sDay & "-" & sMth & "-" & sYr & "_" & sHr & "-" & SMin End Function Function WriteFile(sData, sFileName) Dim fso, OutFile, bWrite bWrite = True Set fso = CreateObject("Scripting.FileSystemObject") On Error Resume Next Set OutFile = fso.OpenTextFile(sFileName, 2, True) 'Possibly need a prompt to close the file and one recursion attempt. If Err = 70 Then Wscript.Echo "Could not write to file " & sFileName & ", results " & _ "not saved." & vbcrlf & vbcrlf & "This is probably " & _ "because the file is already open." bWrite = False ElseIf Err Then WScript.Echo err & vbcrlf & err.description bWrite = False End If On Error GoTo 0 If bWrite Then OutFile.WriteLine(sData) OutFile.Close End If Set fso = Nothing Set OutFile = Nothing WriteFile = bWrite End Functionexpandcollapse popupDim $StrComputer Dim $sCompName Dim $sFileName Dim $s Dim $sKey, $sValue, $sTmp, $sUninstall, $sDateValue, $sYr, $sMth, $sDay Dim $cnt, $oReg, $sBaseKey, $iRC, $aSubKeys Dim $aTmp, $i, $j, $temp Dim $GetDTFileName $strComputer = InputBox("Welcome","Enter I.P. or name of computer to check") If $strComputer = "" Then $strComputer = "." EndIf $sCompName = GetID($StrComputer) $sFileName = $sCompName & "_Software_" & $GetDTFileName & ".csv" $s = GetAddRemove($strComputer) GetAddRemove($strComputer) FileWrite($sFileName, $s) MsgBox (0,"","Finished Processing" & @crlf & @crlf & "Results saved to " & $sFileName) Func GetAddRemove($sComp) Const $HKLM = 'HKEY_LOCAL_MACHINE' $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComp & "/root/default:StdRegProv") $sBaseKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" $iRC = $oReg.EnumKey($HKLM, $sBaseKey, $aSubKeys) For $sKey In $aSubKeys $iRC = $oReg.GetStringValue($HKLM, $sBaseKey & $sKey, "DisplayName", $sValue) If $iRC <> 0 Then $oReg.GetStringValue($HKLM, $sBaseKey & $sKey, "QuietDisplayName", $sValue) EndIf If $sValue <> "" Then $iRC = $oReg.GetStringValue($HKLM, $sBaseKey & $sKey, "UninstallString", $sUninstall) If $sUninstall <> "" Then $sValue = $sValue & "," & "Uninstall String: " & $sUninstall EndIf $sTmp = $sTmp & $sValue & @crlf $cnt = $cnt + 1 EndIf Next $sTmp = BubbleSort($sTmp) $GetAddRemove = "INSTALLED SOFTWARE" & "," & "UNINSTALL STRING" & @crlf & @crlf & $sTmp EndFunc Func BubbleSort($sTmp) $aTmp = Split($sTmp, @crlf) For $i = UBound($aTmp) - 1 To 0 Step -1 For $j = 0 to $i - 1 If LCase($aTmp($j)) > LCase($aTmp($j+1)) Then $temp = $aTmp($j + 1) $aTmp($j + 1) = $aTmp($j) $aTmp($j) = $temp Endif Next Next $BubbleSort = Join($aTmp, @crlf) EndFunc Func GetID($sComp) Dim $objWMIService, $colItems, $objItem Dim $objWMIService = ObjGet("winmgmts:\\" & $sComp & "\root\cimv2") Dim $colItems = $objWMIService.ExecQuery("Select SystemName from Win32_NetworkAdapter",,48) For $objItem in $colItems $GetID = $objItem.SystemName Next EndFunc Func GetDTFileName() dim $sNow, $sMth, $sDay, $sYr, $sHr, $sMin, $sSec $sNow = Now $sMth = Right("0" & Month(sNow), 2) $sDay = Right("0" & Day(sNow), 2) $sYr = Right("00" & Year(sNow), 4) $sHr = Right("0" & Hour(sNow), 2) $sMin = Right("0" & Minute(sNow), 2) $sSec = Right("0" & Second(sNow), 2) $GetDTFileName = $sDay & "-" & $sMth & "-" & $sYr & "_" & $sHr & "-" & $SMin EndFunc Func WriteFile($sData, $sFileName) Dim $fso, $OutFile, $bWrite $bWrite = True Dim $fso = ObjCreate("Scripting.FileSystemObject") On Error Resume Next Dim $OutFile = fso.OpenTextFile($sFileName, 2, True) If $bWrite Then $OutFile.WriteLine($sData) $OutFile.Close EndIf Dim $fso = Nothing Dim $OutFile = Nothing $WriteFile = bWrite EndFunc Link to comment Share on other sites More sharing options...
wakillon Posted October 2, 2010 Share Posted October 2, 2010 Try like this : expandcollapse popupDim $StrComputer Dim $sCompName Dim $sFileName Dim $s Dim $sKey, $sValue, $sTmp, $sUninstall, $sDateValue, $sYr, $sMth, $sDay Dim $cnt, $oReg, $sBaseKey, $iRC, $aSubKeys Dim $aTmp, $i, $j, $temp Dim $GetDTFileName $strComputer = InputBox("Welcome","Enter I.P. or name of computer to check") If $strComputer = "" Then $strComputer = "." EndIf $sCompName = GetID($StrComputer) $sFileName = $sCompName & "_Software_" & $GetDTFileName & ".csv" $s = GetAddRemove($strComputer) GetAddRemove($strComputer) FileWrite($sFileName, $s) MsgBox (0,"","Finished Processing" & @crlf & @crlf & "Results saved to " & $sFileName) Func GetAddRemove($sComp) Const $HKLM = 'HKEY_LOCAL_MACHINE' $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComp & "/root/default:StdRegProv") $sBaseKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" $iRC = $oReg.EnumKey($HKLM, $sBaseKey, $aSubKeys) For $sKey In $aSubKeys $iRC = $oReg.GetStringValue($HKLM, $sBaseKey & $sKey, "DisplayName", $sValue) If $iRC <> 0 Then $oReg.GetStringValue($HKLM, $sBaseKey & $sKey, "QuietDisplayName", $sValue) EndIf If $sValue <> "" Then $iRC = $oReg.GetStringValue($HKLM, $sBaseKey & $sKey, "UninstallString", $sUninstall) If $sUninstall <> "" Then $sValue = $sValue & "," & "Uninstall String: " & $sUninstall EndIf $sTmp = $sTmp & $sValue & @crlf $cnt = $cnt + 1 EndIf Next $sTmp = BubbleSort($sTmp) $GetAddRemove = "INSTALLED SOFTWARE" & "," & "UNINSTALL STRING" & @crlf & @crlf & $sTmp EndFunc Func BubbleSort($sTmp) $aTmp = StringSplit($sTmp, @crlf) For $i = UBound($aTmp) - 1 To 0 Step -1 For $j = 0 to $i - 1 If StringLower ($aTmp[$j]) > StringLower($aTmp[$j+1]) Then $temp = $aTmp[$j + 1] $aTmp[$j + 1] = $aTmp[$j] $aTmp[$j] = $temp Endif Next Next $BubbleSort = $aTmp & @crlf EndFunc Func GetID($sComp) Dim $objWMIService, $colItems, $objItem Dim $objWMIService = ObjGet("winmgmts:\\" & $sComp & "\root\cimv2") Dim $colItems = $objWMIService.ExecQuery("Select SystemName from Win32_NetworkAdapter", '',48 ) For $objItem in $colItems $GetID = $objItem.SystemName Next EndFunc Func GetDTFileName() $GetDTFileName = @WDAY & "-" & @MON & "-" & @YEAR & "_" & @HOUR & "-" & @MIN EndFunc Func WriteFile($sData, $sFileName) Dim $fso, $OutFile, $bWrite $bWrite = True Dim $fso = ObjCreate("Scripting.FileSystemObject") If not @Error Then Dim $OutFile = $fso.OpenTextFile($sFileName, 2, True) If $bWrite Then $OutFile.WriteLine($sData) $OutFile.Close EndIf Dim $fso = '' Dim $OutFile = '' $WriteFile = $bWrite EndIf EndFunc AutoIt 3.3.14.2 X86 - SciTE 3.6.0 - WIN 8.1 X64 - Other Example Scripts Link to comment Share on other sites More sharing options...
darkleton Posted October 2, 2010 Author Share Posted October 2, 2010 (edited) i get the following error when run: Line 63 - The requested action with this object has failed.: Dim $colItems = $objWMIService.ExecQuery("Select SystemName from Win32_NetworkAdapter", '',48 ) Dim $colItems = $objWMIService.ExecQuery("Select SystemName from Win32_NetworkAdapter", '',48 )^ ERROR sorry should have mentioned, this is only when i enter a machine name and press enter Edited October 2, 2010 by darkleton Link to comment Share on other sites More sharing options...
darkleton Posted October 2, 2010 Author Share Posted October 2, 2010 having read around it appears that objWMIService.ExecQuery is a WMI function designed for vbscript. so i'm not sure if there is a way around it, as the other methods for doing what i need with autoit (connecting to remote reg etc) take a lot longer than this way. Link to comment Share on other sites More sharing options...
water Posted October 2, 2010 Share Posted October 2, 2010 To create WMI queries for AutoIt you could try SvenP's "WMI ScriptOMatic tool for Autoit".It creates pure AutoIt code.I think everything that can be done with WMI for VBS can be done for AutoIt as well. My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsOutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiPowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - WikiTask Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs:Excel - Example Scripts - WikiWord - Wiki Tutorials:ADO - WikiWebDriver - Wiki  Link to comment Share on other sites More sharing options...
darkleton Posted October 2, 2010 Author Share Posted October 2, 2010 To create WMI queries for AutoIt you could try SvenP's "WMI ScriptOMatic tool for Autoit".It creates pure AutoIt code.I think everything that can be done with WMI for VBS can be done for AutoIt as well.awesome, thanks water, will check that out now Link to comment Share on other sites More sharing options...
wakillon Posted October 2, 2010 Share Posted October 2, 2010 i get the following error when run:Line 63 - The requested action with this object has failed.:Dim $colItems = $objWMIService.ExecQuery("Select SystemName from Win32_NetworkAdapter", '',48 )Dim $colItems = $objWMIService.ExecQuery("Select SystemName from Win32_NetworkAdapter", '',48 )^ ERRORsorry should have mentioned, this is only when i enter a machine name and press enterTry Dim $colItems = $objWMIService.ExecQuery ( "Select * from Win32_NetworkAdapter", 'WQL', 48 ) AutoIt 3.3.14.2 X86 - SciTE 3.6.0 - WIN 8.1 X64 - Other Example Scripts Link to comment Share on other sites More sharing options...
darkleton Posted October 4, 2010 Author Share Posted October 4, 2010 i have a feeling this is going to be a little more complex than i first thought. it now goes past the execquery and stops on the oreg.enumkey : 29) : ==> The requested action with this object has failed.: $iRC = $oReg.EnumKey($HKLM, $sBaseKey, $aSubKeys) $iRC = $oReg.EnumKey($HKLM, $sBaseKey, $aSubKeys)^ ERROR grrrrrr Link to comment Share on other sites More sharing options...
Mat Posted October 4, 2010 Share Posted October 4, 2010 I would use the Reg* functions instead of the object, you'll get more informative error messages if you do as well.This is great UDF that might be useful. AutoIt Project Listing Link to comment Share on other sites More sharing options...
darkleton Posted October 4, 2010 Author Share Posted October 4, 2010 that udf looks great, the only prob i've had is that it wont run the function on the selected reg key. the two examples it gives, the first works great, the second (the HKLM uninstall) just hangs. Link to comment Share on other sites More sharing options...
darkleton Posted October 4, 2010 Author Share Posted October 4, 2010 actually, it didn't hang, but took nearly 5 mins to get the strings from the local machine, compared to the 25secs the jscript did. i'll have to try and find another way of getting the info. thanks Link to comment Share on other sites More sharing options...
Mat Posted October 4, 2010 Share Posted October 4, 2010 (edited) actually, it didn't hang, but took nearly 5 mins to get the strings from the local machine, compared to the 25secs the jscript did. i'll have to try and find another way of getting the info. thanks Try this then: http://www.autoitscript.com/forum/index.php?showtopic=70108Or maybe this: http://www.autoitscript.com/forum/index.php?showtopic=16529Both will give serious speed improvements...Ultimately, AutoIt should be able to do it at the same speed as anything else, it may be a it more complex though. Edited October 4, 2010 by Mat AutoIt Project Listing Link to comment Share on other sites More sharing options...
darkleton Posted December 7, 2010 Author Share Posted December 7, 2010 sorry for the LONG delay in updating. the two UDFs look good, but both look as though they only work on the local machine, i still cant get it to run on a remote machine as the VBS script did Link to comment Share on other sites More sharing options...
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