Moderators JLogan3o13 Posted November 30, 2010 Moderators Posted November 30, 2010 (edited) I had a customer request a way to uninstall applications silently. The customer has a tool for doing a software inventory, and identifying "unapproved" software, but wanted a way to uninstall it silently without user intervention (after an email notice was sent, is my assumption). I provided this, which seems to work well... expandcollapse popup;get remote computer name $sMachine = InputBox("Computer name?", "Uninstall Remote Application") ;get admin credentials Dim $sAdminUser, $sPassword $sAdminUser = ("") ;Admin on remote machine $sPassword = ("") ; Password for Admin on remote machine ;get a WMI Locator Dim $oLocator $oLocator = ObjCreate("WbemScripting.SWbemLocator") ;connect to the remote machine Dim $oService, $oLocator $oService = $oLocator.ConnectServer($sMachine, "root\cimv2", _ $sAdminUser, $sPassword) ;get a list of installed products Dim $sMsg, $sName $cProducts = $oService.ExecQuery("SELECT * " & _ "FROM Win32_Product") For $oProduct in $cProducts ;is this the product we want? $sMsg = MsgBox(4, "Product: " & $oProduct, "Would you like to uninstall: " & $oProduct.Name & "?") If $sMsg = 6 Then $sName = $oProduct.Name ExitLoop EndIf Next ;Get the named package $cProducts = $oService.ExecQuery("SELECT * " & _ "FROM Win32_Product WHERE Name = '" & _ $sName & "'") For $oProduct in $cProducts ;uninstall it $oProduct.Uninstall ;done! MsgBox(0, "Uninstall Complete.", "Uninstalled " & $sName) Next The only drawback is that this does not seem to work on some Installshield, exe based applications that do not support silent uninstalls. Most every other application it works on. I also provided the customer the following, which gives them a graphical array of the applications installed on a remote machine. One of these days I'm going to figure out how to fuse the two, but they're both generally useful. #include <Array.au3> $Computer = InputBox( "Enter Asset Tag", "What machine would you like to connect to?" ) $ret = _SoftwareInfo() _ArrayDisplay($ret, '') Func _SoftwareInfo($s_RemoteComputer = $Computer) Local $Count = 1 If $s_RemoteComputer <> '' Then $s_RemoteComputer = '\\' & StringReplace($s_RemoteComputer, '\', '') & '\' Local Const $regkey = $s_RemoteComputer & 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' While 1 $key = RegEnumKey ($regkey, $Count) If @error <> 0 then ExitLoop $line = RegRead ($regkey & '\' & $key, 'Displayname') $line = StringReplace ($line, ' (remove only)', '') If $line <> '' Then If Not IsDeclared('avArray') Then Dim $avArray[1] ReDim $avArray[UBound($avArray) + 1] $avArray[UBound($avArray) - 1] = $line EndIf $Count = $Count + 1 WEnd If Not IsDeclared('avArray') Or Not IsArray($avArray) Then Return(SetError(1, 0, '')) Else $avArray[0] = UBound($avArray) - 1 Return(SetError(0,0, $avArray)) EndIf EndFunc Edited November 30, 2010 by JLogan3o13 "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!
iamtheky Posted November 30, 2010 Posted November 30, 2010 (edited) One of these days I'm going to figure out how to fuse the two, but they're both generally useful. Cant remember where i picked this up (tho JSPatriot/ripdad piece is inside, so one of their threads would be my guess). It showed the array and I added a string filter and "right-click uninstall" functionality (maybe, that might have already been there, idk). However it has the same limitations where components and some standalone items do not properly uninstall with the string provided in the registry. expandcollapse popup#include <GuiListView.au3> Opt("TrayAutoPause", 0) Opt('GUIOnEventMode', 1) Opt('GUICloseOnEsc' , 1) Global $i Local $sSft Global $sGui = GUICreate('Currently Installed Software', 810, 650, -1, -1) Global $sLvw = GUICtrlCreateListView('#|Installed Software|Display Version|Publisher|Uninstall String', 5, 5, 800, 600) _ComputerGetSoftware($sSft) For $i = 1 To ubound($sSft) - 1 GUICtrlCreateListViewItem($i & '|' & $sSft[$i][0] & '|' & $sSft[$i][1] & '|' & $sSft[$i][2] & '|' & $sSft[$i][3], $sLvw) Next GUICtrlSendMsg($sLvw, 0x101E, 1, 175) GUICtrlSendMsg($sLvw, 0x101E, 2, 65) GUICtrlSendMsg($sLvw, 0x101E, 3, 150) GUICtrlSendMsg($sLvw, 0x101E, 4, 350) Local $mMen = GUICtrlCreateContextMenu($sLvw) Local $CopI = GUICtrlCreateMenuItem('Uninstall Current Selection', $mMen) GUICtrlSetOnEvent($CopI, '_Uninstall') Local $exp = GUICtrlCreateButton(' Expand ', 720, 615) GUICtrlSetOnEvent($exp, '_Expand') GUISetOnEvent(-3, '_AllExit') GUISetState(@SW_SHOW, $sGui) While 1 Sleep(10) WEnd ; Func _AllExit() GUIDelete($sGui) Exit EndFunc ; Func _Uninstall() Local $proc = StringSplit(GUICtrlRead(GUICtrlRead($sLvw)), '|', 1) If $proc[1] == 0 Then Return -1 If $proc[5] Then ShellExecuteWait ($proc[5]) exit EndFunc ; Func _Copy2Clip() Local $proc = StringSplit(GUICtrlRead(GUICtrlRead($sLvw)), '|', 1) If $proc[1] == 0 Then Return -1 If $proc[5] Then ClipPut($proc[5]) EndFunc ; ; Author JSThePatriot - Modified June 20, 2010 by ripdad Func _ComputerGetSoftware(ByRef $aSoftwareInfo) Local Const $UnInstKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" Local $i = 1 Dim $aSoftwareInfo[1][4] $input = inputbox ("Which Software" , "Which Software would you like to view?", 'ALL') If @Error = 1 Then Exit If $input = 'ALL' Then For $j = 1 To 500 $AppKey = RegEnumKey($UnInstKey, $j) If @error <> 0 Then Exitloop If RegRead($UnInstKey & "\" & $AppKey, "DisplayName") = '' Then ContinueLoop ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4] $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3) $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3) $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3) $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3) $i = $i + 1 Next $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1 If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0) Return _ArraySort($aSoftwareInfo) Else For $j = 1 To 500 $AppKey = RegEnumKey($UnInstKey, $j) If @error <> 0 Then Exitloop $Reg = RegRead($UnInstKey & "\" & $AppKey, "DisplayName") $string = stringinstr($Reg, $input) If $string = 0 Then Continueloop ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4] $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3) $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3) $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3) $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3) $i = $i + 1 Next $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1 If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0) Return _ArraySort($aSoftwareInfo) Endif EndFunc ; Func _Expand() _GUICtrlListView_SetColumnWidth($sLvw, 1, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($sLvw, 2, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($sLvw, 3, $LVSCW_AUTOSIZE) _GUICtrlListView_SetColumnWidth($sLvw, 4, $LVSCW_AUTOSIZE) EndFunc Edited November 30, 2010 by iamtheky ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__)
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