fix: force standard MSI removal by GUID to prevent reinstallation issues
This commit is contained in:
@@ -87,6 +87,7 @@ function Get-InstalledSoftware {
|
|||||||
UninstallString = $cmd
|
UninstallString = $cmd
|
||||||
QuietUninstallString = $quietCmd
|
QuietUninstallString = $quietCmd
|
||||||
RegPath = $item.PSPath
|
RegPath = $item.PSPath
|
||||||
|
RegistryKeyName = $item.PSChildName
|
||||||
}
|
}
|
||||||
[void]$list.Add($obj)
|
[void]$list.Add($obj)
|
||||||
}
|
}
|
||||||
@@ -274,10 +275,8 @@ function Invoke-UninstallSoftware {
|
|||||||
|
|
||||||
for ($i = 0; $i -lt $foundSoftware.Count; $i++) {
|
for ($i = 0; $i -lt $foundSoftware.Count; $i++) {
|
||||||
Write-Host " [$($i+1)] $($foundSoftware[$i].DisplayName)" -ForegroundColor White
|
Write-Host " [$($i+1)] $($foundSoftware[$i].DisplayName)" -ForegroundColor White
|
||||||
|
Write-Host " ID: $($foundSoftware[$i].RegistryKeyName)" -ForegroundColor DarkGray
|
||||||
Write-Host " UninstallString: $($foundSoftware[$i].UninstallString)" -ForegroundColor DarkGray
|
Write-Host " UninstallString: $($foundSoftware[$i].UninstallString)" -ForegroundColor DarkGray
|
||||||
if (-not [string]::IsNullOrWhiteSpace($foundSoftware[$i].QuietUninstallString)) {
|
|
||||||
Write-Host " QuietUninstallString: $($foundSoftware[$i].QuietUninstallString)" -ForegroundColor DarkGray
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
@@ -305,24 +304,26 @@ function Invoke-UninstallSoftware {
|
|||||||
|
|
||||||
$rawCmd = $app.UninstallString
|
$rawCmd = $app.UninstallString
|
||||||
$quietCmd = $app.QuietUninstallString
|
$quietCmd = $app.QuietUninstallString
|
||||||
|
$keyName = $app.RegistryKeyName
|
||||||
|
|
||||||
# Log Details for Debugging
|
# Log Details for Debugging
|
||||||
Write-Host "`n[$count/$total] $($app.DisplayName)" -ForegroundColor Yellow
|
Write-Host "`n[$count/$total] $($app.DisplayName)" -ForegroundColor Yellow
|
||||||
Write-Host " Path: $($app.RegPath)" -ForegroundColor DarkGray
|
Write-Host " Key: $keyName" -ForegroundColor DarkGray
|
||||||
Write-Host " UninstallString: $($rawCmd)" -ForegroundColor DarkGray
|
Write-Host " Original: $rawCmd" -ForegroundColor DarkGray
|
||||||
if (-not [string]::IsNullOrWhiteSpace($quietCmd)) {
|
|
||||||
Write-Host " QuietString: $($quietCmd)" -ForegroundColor DarkGray
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($rawCmd)) {
|
# STRATEGY 1: GUID Override (The "New Approach")
|
||||||
Write-Host " [!] Skipping: Uninstall string is empty." -ForegroundColor Red
|
# If the Registry Key Name is a GUID (e.g., {A1B2...}), it is an MSI product.
|
||||||
continue
|
# We can FORCE standard MSI uninstall, ignoring the vendor's potentially broken string.
|
||||||
|
if ($keyName -match "^\{[a-fA-F0-9-]+\}$") {
|
||||||
|
Write-Host " [i] MSI Product ID detected ($keyName)." -ForegroundColor Cyan
|
||||||
|
Write-Host " [i] Forcing standard Windows Installer removal..." -ForegroundColor Cyan
|
||||||
|
# /x = Uninstall, /qb = Basic UI (shows progress but no wizard steps)
|
||||||
|
$finalCmd = "msiexec.exe /x $keyName /qb"
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
# STRATEGY: Prefer QuietUninstallString if available.
|
# STRATEGY 2: Fallback to parsed strings
|
||||||
# We strip the "quiet" flags to make it interactive.
|
|
||||||
if (-not [string]::IsNullOrWhiteSpace($quietCmd)) {
|
if (-not [string]::IsNullOrWhiteSpace($quietCmd)) {
|
||||||
Write-Host " [i] Quiet Uninstall String found. Adapting for interactive mode..." -ForegroundColor Cyan
|
Write-Host " [i] Quiet Uninstall String found. Adapting..." -ForegroundColor Cyan
|
||||||
$finalCmd = $quietCmd -replace "(?i)\s*/qn", "" `
|
$finalCmd = $quietCmd -replace "(?i)\s*/qn", "" `
|
||||||
-replace "(?i)\s*/quiet", "" `
|
-replace "(?i)\s*/quiet", "" `
|
||||||
-replace "(?i)\s*/norestart", "" `
|
-replace "(?i)\s*/norestart", "" `
|
||||||
@@ -332,17 +333,16 @@ function Invoke-UninstallSoftware {
|
|||||||
$finalCmd = $rawCmd
|
$finalCmd = $rawCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
# FIX: Some MSI commands use /I (Install/Configure) instead of /X (Uninstall).
|
# Apply MSI Fixes to string path
|
||||||
if ($finalCmd -match "(?i)msiexec.*\/I\s*\{") {
|
if ($finalCmd -match "(?i)msiexec.*\/I\s*\{") {
|
||||||
Write-Host " [!] Detected MSI Install flag (/I). Swapping to Uninstall flag (/X)..." -ForegroundColor Magenta
|
Write-Host " [!] Detected MSI Install flag (/I). Swapping to Uninstall flag (/X)..." -ForegroundColor Magenta
|
||||||
$finalCmd = $finalCmd -replace "(?i)\/I", "/X"
|
$finalCmd = $finalCmd -replace "(?i)\/I", "/X"
|
||||||
}
|
}
|
||||||
|
# Apply Bare Exe Fix
|
||||||
# FIX: If command is just "setup.exe" with no arguments, it often reinstalls.
|
|
||||||
if ($finalCmd -match '^"?.*\.exe"?$') {
|
if ($finalCmd -match '^"?.*\.exe"?$') {
|
||||||
Write-Host " [!] Detected bare executable. Appending /uninstall..." -ForegroundColor Magenta
|
|
||||||
$finalCmd = "$finalCmd /uninstall"
|
$finalCmd = "$finalCmd /uninstall"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host " Executing: $($finalCmd)" -ForegroundColor Cyan
|
Write-Host " Executing: $($finalCmd)" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user