This pull request adds support for several new Windows applications to the maintained apps catalog, along with robust PowerShell install and uninstall scripts for each. The main focus is on enabling automated, silent deployment and removal of these apps using Winget, with careful handling of installer quirks and registry lookups to ensure reliability in enterprise environments. **New application support:** * Added `Citrix Workspace`, `Evernote`, `ExpressVPN`, `Front`, `Hyper`, `Jabra Direct`, `Microsoft Teams`, `OneDrive`, `Opera`, `Podman Desktop`, and `REAPER` to the `ee/maintained-apps/inputs/winget` catalog with appropriate metadata for each app. [[1]](diffhunk://#diff-3ba331a553f359a02dd3d824d3edab85292e2d1d9c1a6a739e313a9b63d5a88fR1-R13) [[2]](diffhunk://#diff-917d3e25bae801c48ae70f70bf43e8540d962046bb773dbeed633eb52323e084R1-R12) [[3]](diffhunk://#diff-b8f4026fc2a89254c0bdeb905120761ee78c6a76101deaf3dadd814ce3cafa94R1-R12) [[4]](diffhunk://#diff-72a2bcc2c2b9fadcf09505f8caefb681e79679ee99fb068a84698c783e81f17dR1-R12) [[5]](diffhunk://#diff-5bdb4220ac0cc23ff96963f975a55ef081493ee797545e0a1f65f9f4c50ef982R1-R12) [[6]](diffhunk://#diff-941487a1c1f2ba4d2da50e47f47bbab46478f2bb7c7e009fdd21bf2b68090413R1-R12) [[7]](diffhunk://#diff-9b5681ffd0b55fd89ce4f69e07668fa23df9582a921bf2000d9d2230429e16c9R1-R12) [[8]](diffhunk://#diff-b69363f34d224c471ec183bf7a2d6bab13d776c8905e499cac0e39f31868fd19R1-R12) [[9]](diffhunk://#diff-c8b49c5881565261369d37c862e055087cc65819900f961841c7dc76a83a879dR1-R13) [[10]](diffhunk://#diff-88ceb0a6b8de6484bfcb3f0d19264e307d3166a34f992eba11fcc9d60facb052R1-R13) [[11]](diffhunk://#diff-2557d37d79e9889f60f30557f28efb327e02bf33d4b255deefa912f855111412R1-R14) **Install script implementations:** * Added PowerShell install scripts for each new app, ensuring silent, machine- or user-scoped installs as appropriate, with correct handling of installer arguments and exit codes (including treating reboot-required codes as success for Citrix Workspace and ExpressVPN). [[1]](diffhunk://#diff-ccd33aec25bdbda547e3c4c9b4bcc32d923dcacfe6ebda1a80256d3388bb9003R1-R41) [[2]](diffhunk://#diff-2b0d909e843c3c8265f67dd0e69843c4b59cea7d33741c5be8662ad464f39832R1-R34) [[3]](diffhunk://#diff-fa9d859aa98e8240b9882363a62dc7c69a61186d186cf07c8065a8e11547a3c7R1-R37) [[4]](diffhunk://#diff-9baf7c34c008963410a30fec1e6949023d03d3c400ec0166c029dd5eebcfaefeR1-R27) **Uninstall script implementations:** * Added PowerShell uninstall scripts for each new app, using registry lookups to locate the correct uninstaller and applying silent uninstall arguments. Scripts handle argument parsing defensively and ensure correct removal in both per-user and per-machine contexts. [[1]](diffhunk://#diff-ab38143c2c6f191c4f57aff0adb35e8c7a67cd95522da13da25febc8f65cc73eR1-R92) [[2]](diffhunk://#diff-4657653f749298d4ae84fb467023108a273c8e621c8cc711d5821fbeacfa03cdR1-R91) [[3]](diffhunk://#diff-1280127be173a1bdce9e7f18343fa6aae26fc3d15e1935e196669131deb484bdR1-R89) These additions significantly expand the catalog's Windows app coverage and improve reliability and automation for enterprise deployments.
98 lines
3.2 KiB
PowerShell
98 lines
3.2 KiB
PowerShell
# Fleet runs this uninstall script as SYSTEM (machine scope).
|
|
# Match against the registry DisplayName for OneDrive.
|
|
$softwareName = "Microsoft OneDrive"
|
|
|
|
# It is recommended to use exact software name here if possible to avoid
|
|
# uninstalling unintended software.
|
|
$softwareNameLike = "$softwareName"
|
|
|
|
# OneDriveSetup.exe uninstalls with /uninstall (and /allusers for machine-wide
|
|
# installs). Used only if the registered UninstallString carries no flags.
|
|
$defaultArgs = "/uninstall /allusers"
|
|
|
|
# A machine-wide OneDrive registers under HKLM; also check WOW6432Node since the
|
|
# installer is 32-bit.
|
|
$paths = @(
|
|
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
|
|
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
|
|
)
|
|
|
|
$exitCode = 0
|
|
|
|
try {
|
|
|
|
[array]$uninstallKeys = Get-ChildItem `
|
|
-Path $paths `
|
|
-ErrorAction SilentlyContinue |
|
|
ForEach-Object { Get-ItemProperty $_.PSPath }
|
|
|
|
$foundUninstaller = $false
|
|
foreach ($key in $uninstallKeys) {
|
|
if ($key.DisplayName -like $softwareNameLike) {
|
|
$foundUninstaller = $true
|
|
|
|
# Prefer QuietUninstallString when present; it already includes silent flags.
|
|
$useQuiet = [bool]$key.QuietUninstallString
|
|
$uninstallCommand = if ($useQuiet) {
|
|
$key.QuietUninstallString
|
|
} else {
|
|
$key.UninstallString
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($uninstallCommand)) {
|
|
Throw "No UninstallString found for '$($key.DisplayName)'."
|
|
}
|
|
|
|
# Parse the UninstallString defensively. It comes in three shapes:
|
|
# 1. "C:\Program Files\Microsoft OneDrive\...\OneDriveSetup.exe" /uninstall (quoted)
|
|
# 2. C:\Program Files\Microsoft OneDrive\...\OneDriveSetup.exe /uninstall (unquoted, may contain spaces)
|
|
# 3. MsiExec.exe /X{GUID} (bare token)
|
|
if ($uninstallCommand -match '^\s*"([^"]+)"\s*(.*)$') {
|
|
$exe = $matches[1]
|
|
$args = $matches[2].Trim()
|
|
} elseif ($uninstallCommand -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
|
|
$exe = $matches[1]
|
|
$args = $matches[2].Trim()
|
|
} else {
|
|
$uninstallCommand -match '^\s*(\S+)\s*(.*)$' | Out-Null
|
|
$exe = $matches[1]
|
|
$args = $matches[2].Trim()
|
|
}
|
|
|
|
# If we fell back to the raw UninstallString (no quiet variant), ensure the
|
|
# uninstall runs unattended and all-users.
|
|
if (-not $useQuiet -and ($args -notmatch '(?i)/uninstall')) {
|
|
$args = "$args $defaultArgs".Trim()
|
|
}
|
|
|
|
Write-Host "Uninstall command: $exe"
|
|
Write-Host "Uninstall args: $args"
|
|
|
|
$processOptions = @{
|
|
FilePath = $exe
|
|
PassThru = $true
|
|
Wait = $true
|
|
}
|
|
if ($args -ne '') {
|
|
$processOptions.ArgumentList = $args
|
|
}
|
|
|
|
$process = Start-Process @processOptions
|
|
$exitCode = $process.ExitCode
|
|
Write-Host "Uninstall exit code: $exitCode"
|
|
break
|
|
}
|
|
}
|
|
|
|
if (-not $foundUninstaller) {
|
|
Write-Host "Uninstaller for '$softwareName' not found."
|
|
$exitCode = 1
|
|
}
|
|
|
|
} catch {
|
|
Write-Host "Error: $_"
|
|
$exitCode = 1
|
|
}
|
|
|
|
Exit $exitCode
|