Uninstalling Application Based on UpgradeCode

I recently had the need to uninstall an (MSI-based) application that has a different ProductCode for each release but doesn’t update the ProductCode when it self-updates. However, each version uses the same UpgradeCode. I knew that I could determine the ProductCode that was used to install the application by looking up the UpgradeCode in the registry.  This script will locate and expand the ProductCode, verify that it is listed in the Uninstall table, and run the uninstall command.  Unfortunately, I don’t see any information in the registry to state if a code is for a 32-bit or 64-bit install, so it checks both locations.

Save the Uninstall Code as a .ps1 and use the following sample as an example of running the script from within PowerShell.

.\uninstall.ps1 -UpgradeCode "{C1DFDF69-5945-32F2-A35E-EE94C99C7CF4}"

 

Uninstall Code:

param (
 [parameter(Mandatory=$true)]
 [string]$UpgradeCode
)
$guidOrder = @(7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 15, 14, 13, 12, 17, 16, 19, 18, 21, 20, 23, 22, 25, 24, 27, 26, 29, 28, 31, 30);

$UpgradeCodeStripped = $UpgradeCode -replace "[-{}]", "";
$UpgradeCodeCompressed = "";
for ($i = 0; $i -lt $UpgradeCodeStripped.Length; $i++) {
 $UpgradeCodeCompressed += $UpgradeCodeStripped.Substring($guidOrder[$i], 1);
}

if (Test-Path -Path "HKLM:\Software\Classes\Installer\UpgradeCodes\$UpgradeCodeCompressed") {
 $ProductCodeCompresssed = (Get-Item -Path "HKLM:\Software\Classes\Installer\UpgradeCodes\$UpgradeCodeCompressed").Property[0];
 $ProductCode = "{";
 for ($i = 0; $i -lt $ProductCodeCompresssed.Length; $i++) {
 $ProductCode += $ProductCodeCompresssed.Substring($guidOrder[$i], 1);
 }
 $ProductCode = $ProductCode.Insert(9, '-').Insert(14, '-').Insert(19, '-').Insert(24, '-').Insert(37, '}');
}

if ((Test-Path -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\$ProductCode") -or (Test-Path -Path "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$ProductCode")) {
 $proc = Start-Process -FilePath "msiexec.exe" -ArgumentList "/x", "$ProductCode", "/q", "RESTART=ReallySuppress" -PassThru -Wait;
 exit $proc.ExitCode;
} else {
 exit 0;
}

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s