Jump to content

Remote Application Uninstall


JLogan3o13
 Share

Recommended Posts

  • Moderators

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...

;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 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!

Link to comment
Share on other sites

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.

#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 by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
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
 Share

  • Recently Browsing   0 members

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