mirror of
https://github.com/fleetdm/fleet
synced 2026-05-22 08:28:52 +00:00
Uninstall FMA MSIs by UpgradeCode when available (#30581)
Fixes #27757. # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] Manual QA for all new/changed functionality <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved uninstallation process for MSI-based applications by dynamically detecting and uninstalling all related product codes using the upgrade code, enhancing reliability for machine-wide installs. * **Bug Fixes** * Updated uninstall scripts for BoxDrive, Cloudflare WARP, and Google Chrome to ensure complete removal of all associated components. * **Chores** * Updated installer versions for Cloudflare WARP and Google Chrome to the latest releases. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
22ddb12530
commit
f4a9eabfd9
5 changed files with 47 additions and 14 deletions
|
|
@ -2,6 +2,7 @@ package winget
|
|||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
|
@ -250,6 +251,25 @@ func (i *wingetIngester) ingestOne(ctx context.Context, input inputApp) (*mainta
|
|||
}
|
||||
|
||||
if (input.InstallerType == installerTypeMSI || input.UninstallType == installerTypeMSI) && input.InstallerScope == machineScope {
|
||||
var upgradeCode string
|
||||
for _, fe := range m.AppsAndFeaturesEntries {
|
||||
if fe.UpgradeCode != "" {
|
||||
upgradeCode = fe.UpgradeCode
|
||||
break
|
||||
}
|
||||
}
|
||||
if upgradeCode == "" {
|
||||
for _, fe := range selectedInstaller.AppsAndFeaturesEntries {
|
||||
if fe.UpgradeCode != "" {
|
||||
upgradeCode = fe.UpgradeCode
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if uninstallScript == "" && upgradeCode != "" {
|
||||
uninstallScript = buildUpgradeCodeBasedUninstallScript(upgradeCode)
|
||||
}
|
||||
|
||||
if uninstallScript == "" {
|
||||
uninstallScript = file.GetUninstallScript(installerTypeMSI)
|
||||
}
|
||||
|
|
@ -266,7 +286,6 @@ func (i *wingetIngester) ingestOne(ctx context.Context, input inputApp) (*mainta
|
|||
if productCode == "" {
|
||||
productCode = selectedInstaller.ProductCode
|
||||
}
|
||||
|
||||
productCode = strings.Split(productCode, ".")[0]
|
||||
|
||||
out.Name = input.Name
|
||||
|
|
@ -303,6 +322,13 @@ func (i *wingetIngester) ingestOne(ctx context.Context, input inputApp) (*mainta
|
|||
return &out, nil
|
||||
}
|
||||
|
||||
//go:embed uninstall_with_upgrade_code.ps1
|
||||
var uninstallWithUpgradeCode string
|
||||
|
||||
func buildUpgradeCodeBasedUninstallScript(upgradeCode string) string {
|
||||
return regexp.MustCompile(`\$UPGRADE_CODE`).ReplaceAllString(uninstallWithUpgradeCode, upgradeCode)
|
||||
}
|
||||
|
||||
var packageIDRegex = regexp.MustCompile(`((("\$PACKAGE_ID")|(\$PACKAGE_ID))(?P<suffix>\W|$))|(("\${PACKAGE_ID}")|(\${PACKAGE_ID}))`)
|
||||
|
||||
func preProcessUninstallScript(uninstallScript, productCode string) string {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# Fleet uninstalls app by finding all related product codes for the specified upgrade code
|
||||
$inst = New-Object -ComObject "WindowsInstaller.Installer"
|
||||
foreach ($product_code in $inst.RelatedProducts('$UPGRADE_CODE')) {
|
||||
msiexec /quiet /x $product_code
|
||||
}
|
||||
|
||||
Exit $LASTEXITCODE
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
},
|
||||
"installer_url": "https://e3.boxcdn.net/desktop/releases/win/BoxDrive-2.45.187.msi",
|
||||
"install_script_ref": "8959087b",
|
||||
"uninstall_script_ref": "5999db54",
|
||||
"uninstall_script_ref": "eeaecda2",
|
||||
"sha256": "7c3bce4aa53e99fd153542aef4d17beba2a54b4d3d67fdfd260c53cf6f0fbc14",
|
||||
"default_categories": [
|
||||
"Productivity"
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
}
|
||||
],
|
||||
"refs": {
|
||||
"5999db54": "$product_code = \"{EA004022-FC5E-4588-A7EC-EED710BFD9E6}\"\n\n# Fleet uninstalls app using product code that's extracted on upload\nmsiexec /quiet /x $product_code\nExit $LASTEXITCODE\n",
|
||||
"8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n"
|
||||
"8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n",
|
||||
"eeaecda2": "# Fleet uninstalls app by finding all related product codes for the specified upgrade code\n$inst = New-Object -ComObject \"WindowsInstaller.Installer\"\nforeach ($product_code in $inst.RelatedProducts('{46AF5B38-D258-487A-92BD-792911248CCD}')) {\n msiexec /quiet /x $product_code\n}\n\nExit $LASTEXITCODE\n"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
{
|
||||
"versions": [
|
||||
{
|
||||
"version": "25.4.943.0",
|
||||
"version": "25.5.893.0",
|
||||
"queries": {
|
||||
"exists": "SELECT 1 FROM programs WHERE name = 'Cloudflare WARP' AND publisher = 'Cloudflare, Inc.';"
|
||||
},
|
||||
"installer_url": "https://downloads.cloudflareclient.com/v1/download/windows/version/2025.4.943.0",
|
||||
"installer_url": "https://downloads.cloudflareclient.com/v1/download/windows/version/2025.5.893.0",
|
||||
"install_script_ref": "8959087b",
|
||||
"uninstall_script_ref": "fad0c0ce",
|
||||
"sha256": "04108b020b545f778d6bb7ea996a896d5e30f722a1fdf056fe74001228c1fee5",
|
||||
"uninstall_script_ref": "1d523e72",
|
||||
"sha256": "ff77a76288adf412e819614795476b9b834b79e5a036aaa554c6e2eabd45c623",
|
||||
"default_categories": [
|
||||
"Productivity"
|
||||
]
|
||||
}
|
||||
],
|
||||
"refs": {
|
||||
"8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n",
|
||||
"fad0c0ce": "$product_code = \"{FB9B5C2D-D406-48A5-A9A0-F490DD1ED60C}\"\n\n# Fleet uninstalls app using product code that's extracted on upload\nmsiexec /quiet /x $product_code\nExit $LASTEXITCODE\n"
|
||||
"1d523e72": "# Fleet uninstalls app by finding all related product codes for the specified upgrade code\n$inst = New-Object -ComObject \"WindowsInstaller.Installer\"\nforeach ($product_code in $inst.RelatedProducts('{1BF42825-7B65-4CA9-AFFF-B7B5E1CE27B4}')) {\n msiexec /quiet /x $product_code\n}\n\nExit $LASTEXITCODE\n",
|
||||
"8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"versions": [
|
||||
{
|
||||
"version": "138.0.7204.50",
|
||||
"version": "138.0.7204.97",
|
||||
"queries": {
|
||||
"exists": "SELECT 1 FROM programs WHERE name = 'Google Chrome' AND publisher = 'Google LLC';"
|
||||
},
|
||||
"installer_url": "https://dl.google.com/dl/chrome/install/googlechromestandaloneenterprise64.msi",
|
||||
"install_script_ref": "8959087b",
|
||||
"uninstall_script_ref": "ddbf0e7f",
|
||||
"uninstall_script_ref": "4836150f",
|
||||
"sha256": "no_check",
|
||||
"default_categories": [
|
||||
"Browsers"
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
}
|
||||
],
|
||||
"refs": {
|
||||
"8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n",
|
||||
"ddbf0e7f": "$product_code = \"{630C6D4E-5144-3E8C-A7B1-4B3BC607535E}\"\n\n# Fleet uninstalls app using product code that's extracted on upload\nmsiexec /quiet /x $product_code\nExit $LASTEXITCODE\n"
|
||||
"4836150f": "# Fleet uninstalls app by finding all related product codes for the specified upgrade code\n$inst = New-Object -ComObject \"WindowsInstaller.Installer\"\nforeach ($product_code in $inst.RelatedProducts('{C1DFDF69-5945-32F2-A35E-EE94C99C7CF4}')) {\n msiexec /quiet /x $product_code\n}\n\nExit $LASTEXITCODE\n",
|
||||
"8959087b": "$logFile = \"${env:TEMP}/fleet-install-software.log\"\n\ntry {\n\n$installProcess = Start-Process msiexec.exe `\n -ArgumentList \"/quiet /norestart /lv ${logFile} /i `\"${env:INSTALLER_PATH}`\"\" `\n -PassThru -Verb RunAs -Wait\n\nGet-Content $logFile -Tail 500\n\nExit $installProcess.ExitCode\n\n} catch {\n Write-Host \"Error: $_\"\n Exit 1\n}\n"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue