When automating software deployments, you'll often need the MSI package's GUID (ProductCode) for silent uninstallation. Here are reliable methods to extract it:
# PowerShell method (Windows 8+)
Get-WmiObject Win32_Product | Select-Object Name,IdentifyingNumber
# Using Windows Installer API
$installer = New-Object -ComObject WindowsInstaller.Installer
$products = $installer.ProductsEx("", "", 7)
$products | ForEach-Object { $_.InstallProperty("ProductName") + " : " + $_.InstallProperty("ProductCode") }
For offline MSI files, use these approaches:
# Using ORCA (Windows SDK tool)
msiinfo exportproperty "path\to\package.msi" Property | findstr /i "ProductCode"
# Via VBScript
Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase("C:\package.msi", 0)
View = database.OpenView("SELECT Value FROM Property WHERE Property='ProductCode'")
View.Execute
Record = View.Fetch
WScript.Echo Record.StringData(1)
While msiexec /x {GUID}
works for most applications, consider these exceptions:
- Per-user installations may require
/qn
instead of/quiet
- Some vendors use custom actions that block silent removal
- 64-bit systems may require checking both HKLM\SOFTWARE and HKLM\SOFTWARE\WOW6432Node
Here's a robust PowerShell implementation:
function Uninstall-MSIApplication {
param(
[Parameter(Mandatory=$true)]
[string]$ApplicationName
)
$application = Get-WmiObject Win32_Product |
Where-Object { $_.Name -match $ApplicationName }
if ($application) {
$uninstallParams = "/x $($application.IdentifyingNumber) /qn /norestart"
Start-Process "msiexec.exe" -ArgumentList $uninstallParams -Wait
} else {
Write-Warning "Application not found in MSI registry"
}
}
# Usage example
Uninstall-MSIApplication -ApplicationName "Adobe Reader"
For systems where WMI is unavailable, scan these registry locations:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
Each subkey contains either a GUID (MSI installation) or non-GUID identifier (EXE installer). MSI entries will have "WindowsInstaller"=dword:1 and "UninstallString" containing "MsiExec.exe /X{GUID}".
Every MSI package contains a unique GUID (Globally Unique Identifier) known as the ProductCode. This identifier is crucial for silent uninstallation operations through Windows Installer. The standard uninstallation command looks like:
msiexec.exe /x {GUID-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
Using PowerShell
The most programmatic approach for modern Windows systems:
# Get all installed MSI products
$products = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*,
HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Where-Object { $_.PSChildName -match '^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$' }
# Display product names with GUIDs
$products | Select-Object DisplayName, PSChildName | Format-Table -AutoSize
Using WMIC Command
For legacy systems without PowerShell:
wmic product get name, identifyingnumber
Direct Registry Query
Manual inspection in Registry Editor:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
Some applications might not appear in standard queries due to:
- Per-user installations (check HKCU instead of HKLM)
- Non-MSI installers (EXE-based installs require different approaches)
- Hidden registry entries (use
ShowUpdates=1
parameter with WMIC)
# PowerShell script for bulk MSI removal
$targetGuid = '{YOUR-GUID-HERE}'
$computers = Get-Content 'C:\path\to\computers.txt'
foreach ($computer in $computers) {
Invoke-Command -ComputerName $computer -ScriptBlock {
Start-Process 'msiexec.exe' -ArgumentList "/x $using:targetGuid /qn" -Wait
}
}
- Always test uninstallation scripts on a small subset first
- Some MSI packages require transform files (.mst) for proper removal
- Use
/norestart
parameter to prevent unexpected reboots - Combine with
msiexec /lvx* uninstall.log
for logging