Invoking Registry UninstallString

This topic contains 9 replies, has 4 voices, and was last updated by  Sultan Alkurnas 2 years, 1 month ago.

  • Author
    Posts
  • #25139

    Bill Bigsbee
    Participant

    Goal: leverage powershell to query registry for uninstallstring for specific software. Once uninstallstring is known, invoke uninstallstring to remove application.

    We have a Silverlight Out-Of-Browser application that needs uninstalled on 500+ systems.

    The script:
    #################
    ###Sets location to software file location in user profile
    Set-Location -Path "c:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0"

    ###Sets variable for reg HKCU query, filters for sloobapp, displays displayname, uninstallstring properties
    $apsInst = Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall|
    Get-ItemProperty|Where-Object {$_.DisplayName -match "sloobapp" }|
    Select-Object -Property DisplayName, UninstallString

    ###For each match, run the registry uninstall string
    ForEach ($sloobapp in $apsInst) {

    If ($sloobapp.UninstallString) {

    $uninst = $sloobapp.UninstallString
    }
    ###########

    As for my problem, when ran it just prints the variable on screen. "$uninst" , now I believe my laymaness is being exhibited and I have not properly formatted the "" section above. Any thoughts/Suggestions?

  • #25140

    Bill Bigsbee
    Participant

    Apologies, should read the bulletins, parts of my above message are missing. I've attached a txt.

    As for my problem, when ran it just prints the variable on screen. "$uninst" , now I believe my laymaness is being exhibited and I have not properly formatted lines 14 & 15 .

  • #25143

    Daniel Krebs
    Moderator

    Replace

    & cmd /c {'.$uninst'}
    

    with

    & $uninst
    

    or

    Start-Process -FilePath cmd.exe -ArgumentList '/c', $uninst -Wait
    
  • #25163

    Bill Bigsbee
    Participant

    Daniel,

    Very much appreciated, your recommendation "start-process" worked!

    It seems perhaps the issue is lines 12-14, as when I run the command "Silverlight.Configuration.exe -uninstallApp *sloobapp*" is ran at "C:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0>" it uninstalls the application with no issues.

    But when we call the variable "$uninst" in the script it does not uninstall the application. Now I thought I'd resolve this issue by setting the location to the "C:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0>" , but that did not seem to help.

    Any thoughts?

  • #25171

    Rob Simmers
    Participant

    How are you setting the location and when? Did you use Set-Location (CD) during script execution or change the directory of the Powershell prompt and then run the script? Do you get the expected results if you prepend the path for the EXE?

    $uninst = "C:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0\{0}" -f $uninst
    

    or

    Set-Location "C:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0" 
    Start-Process -FilePath cmd.exe -ArgumentList '/c', $uninst -Wait
    
  • #25191

    Bill Bigsbee
    Participant

    Previously, I've set the location prior to script execution with the "Set-Location" cmdlet. I've since moved the set-location to line 13.
    The script processes, but still $uninst variable is not performing as if I run "Silverlight.Configuration.exe -uninstallApp *sloobapp*" straight at the command line.

    Now I believe this is happening because on line 11 i'm setting "$uninst = ($aps.UninstallString)" which is the registry uninstall string pulled from the key above. I'm attempting to run it in this variable.

    (pre){{###Sets variable for reg HKCU query, filters for SLOOBAPP, displays displayname, uninstallstring properties
    $apsInst = Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall|
    Get-ItemProperty|Where-Object {$_.DisplayName -match "SLOOBAPP"}
    Select-Object -Property DisplayName, UninstallString

    ForEach ($aps in $apsInst) {

    If ($aps.UninstallString) {

    $uninst = $aps.UninstallString

    Set-Location -Path "c:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0"

    Start-Process -FilePath cmd.exe -ArgumentList '/c', $uninst -wait
    }

    }} (/pre)

  • #25210

    Bill Bigsbee
    Participant

    So with everyone's assistance I was able to get this to actually work, as expected, now I need to make this work on 500+ computers

    (pre){#Set variable for registry query, where Any match of "HCI APS", Select property "UninstallString" – Working
    $apsInst = Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall|
    Get-ItemProperty | Where-Object {$_.DisplayName -match "SLOOBAPP"}|
    Select-Object -Property UninstallString

    $uninst = "Silverlight.Configuration.exe -uninstallApp 165905322.SLOOBAPP.somewebsite.com"

    ForEach ($aps in $apsInst) {

    If ($aps.UninstallString){

    Set-Location -Path "c:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0"

    Start-Process -FilePath cmd.exe -ArgumentList '/c', $uninst -wait
    }
    } }(/pre)

  • #25278

    Bill Bigsbee
    Participant

    So continuing from above.
    I believe I'll need to take the "UninstallString" value and plug it in on the fly into the $uninst variable for this to work on any system I'd like to use it on.
    As the number that precedes "xxxxxxxxx.sloobapp.somewebsite.com" is a randomly generated integer that can be any integer 0-9 of any length.

    I'm kind of at a loss how to do this, originally I was thinking I'd have to utilize a regular expression to account for the unique integer string preceding the webclient.

    Thoughts or Suggestions?

  • #25281

    Rob Simmers
    Participant

    I was wondering about this earlier when I looked at it but you said you had it working. You connect to registry, find the uninstall string and then use a manual uninstall string. Take a look at this and see if you understand the logic:

    function Get-InstalledApps {
    param()
        begin{}
        process{
            $apps = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* |
                    Select DisplayName, 
                    DisplayVersion, 
                    UnInstallString,
                    InstallDate,
                    @{Name="VERSION_MAJOR";Expression={($_.DisplayVersion.Split("."))[0]}},
                    @{Name="VERSION_MINOR";Expression={($_.DisplayVersion.Split("."))[1]}},
                    @{Name="VERSION_REVISION";Expression={($_.DisplayVersion.Split("."))[2]}},
                    @{Name="VERSION_BUILD";Expression={($_.DisplayVersion.Split("."))[3]}}, 
                    @{Name="GUID";Expression={$_.PSChildName}},
                    @{Name="AppArchitecture";Expression={"86"}}
            # If it is a 64-bit box, then also include the Wow6432Node
            if((Get-WmiObject Win32_Processor).AddressWidth -eq 64){
                $apps += Get-ItemProperty HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | 
                         Select DisplayName,
                         DisplayVersion, 
                         UnInstallString,
                         InstallDate, 
                         @{Name="VERSION_MAJOR";Expression={($_.DisplayVersion.Split("."))[0]}},
                         @{Name="VERSION_MINOR";Expression={($_.DisplayVersion.Split("."))[1]}},
                         @{Name="VERSION_REVISION";Expression={($_.DisplayVersion.Split("."))[2]}},
                         @{Name="VERSION_BUILD";Expression={($_.DisplayVersion.Split("."))[3]}}, 
                         @{Name="GUID";Expression={$_.PSChildName}}, 
                         @{Name="AppArchitecture";Expression={"64"}}
            }
    
            $apps | Where{ !([string]::IsNullOrEmpty($_.DisplayName)) }
        }
        end{}
    }
    
    # Get all 32\64 bit applications
    $installedApps = Get-InstalledApps
    # Find any application with SLOOBAPP in the name
    $silverLight = $installedApps | Where-Object {$_.DisplayName -match "SLOOBAPP"}
    
    #If an application was found (variable not null)...
    if ($silverLight) {
        foreach ($application in $installedApps) {
            #if the uninstall string is not null...
            If ($application.UninstallString){
                #Here you are specifying (x86) only, so this would fail if there were a 64-bit Silverlight installation
                #You should use similar logic I'm using in the function above to see if it's a 64-bit machine or I'm adding
                #an AppArchitecture param, so you could do if ($application.AppArchitecture -eq 32){"Set location for 32}else{Set Location for 64}
                Set-Location -Path "c:\Program Files (x86)\Microsoft Silverlight\5.1.30514.0"
                #Rather than use a manual string (e.g. $uninst, you would just reference
                "Running command: {0} from {1}" -f $application.UninstallString, (Get-Location)
                Start-Process -FilePath cmd.exe -ArgumentList '/c', $application.UninstallString -wait
            }
            else {
                "There is not uninstall string for {0}" -f $application.DisplayName
            } #if UnInstallString
        } #for each application
    }
    else {
        "Silverlight is not installed."
    } #if $silverlight
    
  • #29725

    Sultan Alkurnas
    Participant

    Thank you both for your time. I was able to enumerate all the applications installed using your methods.

You must be logged in to reply to this topic.