Skip to content

Fix Windows FMA per-user vs per-machine install scope (#48248)#48603

Draft
allenhouchins wants to merge 7 commits into
mainfrom
48248-windows-fma-patch-policies-dont-distinguish-per-user-vs-per-machine-install-scope-leaving-duplicatestale-copies
Draft

Fix Windows FMA per-user vs per-machine install scope (#48248)#48603
allenhouchins wants to merge 7 commits into
mainfrom
48248-windows-fma-patch-policies-dont-distinguish-per-user-vs-per-machine-install-scope-leaving-duplicatestale-copies

Conversation

@allenhouchins

@allenhouchins allenhouchins commented Jul 1, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #48248

Fixes the Windows FMA duplicate/stale-copy problem where a patch policy could not distinguish per-user vs per-machine install scope. Covers the foundation work and Pattern A remediation for all dual-variant Windows FMAs.

Root cause

Windows apps can install per-user (HKCU, %LOCALAPPDATA%) or per-machine (HKLM, Program Files). The FMA patch policy is the exists detection query with a version compare appended, and programs reads both scopes — so when a host had the app at one scope and the FMA installed at the other, a second copy was created, the stale copy lingered unmanaged, and the scope-blind policy kept reporting the host not patched.

What changed

Foundation

  • Ingester (ingester.go): trust the input's installer_scope when the winget manifest is silent on scope (scope == input.InstallerScope || scope == ""). Previously, setting a scope on an NSIS/Inno/burn app with no declared winget Scope panicked. Exact matching still disambiguates dual-variant apps.
  • Set installer_scope on the 9 previously-unset inputs, each verified from an authoritative source (installer PE requestedExecutionLevel, MSI ALLUSERS, or winget Scope) — not guessed.
  • Enforcement: TestInputInstallerScopeIsSet fails CI if any winget input lacks a valid machine/user scope; plus ingester tests for the scope-fallback and scope-mismatch paths.
  • Docs: added an "Install scope vs. detection" guardrail section to the FMA authoring guide (README) and the new-fma skill.

Pattern A remediation — all dual-variant apps

Every dual-variant install script now runs a single canonical, best-effort Remove-FmaOtherScopeCopies block before installing the managed copy. It:

  • scans only the opposite scope's uninstall hives — HKEY_USERS\<SID> for machine-target apps (Fleet runs as SYSTEM, where HKCU is SYSTEM's own hive), HKLM for user-target apps — so a broad DisplayName match can't touch the copy Fleet manages;
  • prefers each vendor's QuietUninstallString verbatim (correct silent switches per installer tech: Chromium --force-uninstall, Inno /VERYSILENT, MSI /x /qn, …), with a per-app fallback derived from that app's own uninstall script;
  • is best-effort: never aborts the install, and a copy that survives keeps the (truthful) scope-blind policy red rather than false-green.
Direction Apps
Machine-target (remove per-user) — exe cursor, firefox, firefox@esr, google-drive, onedrive, visual-studio-code, vivaldi, vscodium, windsurf, powertoys, gimp
Machine-target (remove per-user) — msi* 1password, box-drive, dropbox, github-desktop, google-chrome, microsoft-edge, zoom
User-target (remove per-machine) antigravity-ide, brave-browser, kiro, mullvad-browser
MSIX (remove legacy Win32, both scopes) slack, microsoft-teams, arc, claude, affinity, windows-app

* MSI apps get a custom install script (cleanup + msiexec); their uninstall stays upgrade-code based.

Pattern A remediation — MSIX apps (legacy Win32 cleanup)

For an MSIX-managed app there is no "same-scope" Win32 copy to leave for the installer — every leftover exe/MSI copy (e.g. old Squirrel per-user Slack, classic Teams + its Machine-Wide Installer MSI) keeps the scope-blind policy red while the MSIX is current. Each MSIX install script now runs a Remove-FmaWin32Copies block before Add-AppxProvisionedPackage that sweeps both Win32 uninstall hives (HKLM + HKEY_USERS\S-1-5-21-*), with guards the dual-variant block doesn't need:

  • MSIX self-guard: PackageFullName-style keys (*_<13-char publisher hash>) and entries under \WindowsApps\ are never touched, so a re-run can't remove the package the script just installed;
  • exact DisplayName matchers mirroring each app's detection query (+ publisher check), so e.g. Arc can't match ArcGIS and the Teams Meeting Add-in isn't removed;
  • no-quiet-path → skip: entries with no QuietUninstallString and no known silent fallback are left alone (a raw UninstallString run as SYSTEM can hang on UI until the script times out);
  • phantom-key cleanup, verified only: a per-user uninstaller launched by SYSTEM removes its files but can't clean the user's HKEY_USERS uninstall key (it writes to HKCU = SYSTEM's hive), which would keep the policy red forever — so the matched key is deleted only after verifying the uninstaller removed itself from disk; if files remain, the key stays (truthful red, never false-green).
  • Data note: Win32 → MSIX is cross-packaging; local app data does not carry (documented in the README guardrails; for these apps data is account-based/server-synced).

The same-packaging upgrade path (pre-existing older MSIX) needs no script change: provisioning stages the newer version machine-wide and each user's registration upgrades at next sign-in (data preserved), with the console user upgraded immediately via the existing scheduled-task registration.

Detection queries remain scope-blind by design.

⚠️ Reviewer notes / caveats

  • Not validated on a live Windows host — no host was available. Each script is derived from the app's own reviewed uninstall logic and wrapped best-effort, but per-app QA is required before merge (esp. per-user-uninstall-from-SYSTEM, and OneDrive/Chrome/Zoom/GitHub Desktop whose opposite-scope copy uses a different installer tech). This is an open acceptance criterion in Windows FMA patch policies don't distinguish per-user vs per-machine install scope, leaving duplicate/stale copies #48248.
  • Converting the 7 MSI apps to custom install scripts means the auto-update cron no longer regenerates their install step (uninstall still auto-generated). Acceptable tradeoff for Pattern A; flagged for awareness.
  • MSIX live-QA items (in addition to the per-app QA above): (1) confirm a registered MSIX shows up in osquery programs after user sign-in with the name/publisher the detection query expects (the validator's premise, cmd/maintained-apps/validate/windows.go); (2) confirm provisioning a newer version upgrades an existing older per-user registration at next sign-in; (3) confirm Squirrel Update.exe --uninstall -s launched as SYSTEM self-deletes within the 5s settle window so the leftover HKEY_USERS key cleanup fires; (4) confirm a cleanly-failing (not hanging) provision when a host already has a newer MSIX registered.
  • Still open (not Pattern A): the 44 user-scope-as-SYSTEM apps.
  • Validator fix (latent CI flake): cmd/maintained-apps/validate/windows.go now ignores "Microsoft Edge WebView2 Runtime"/"Microsoft Edge Update" when checking Microsoft Edge — the broad LIKE '%Microsoft Edge%' match falsely reported Edge as still installed after uninstall whenever the runner image's WebView2 version coincided with the manifest version (Microsoft version-locks WebView2 to Edge releases; hit on run 28561163533).
  • Firefox ESR install script race fixed: the completion poll exited as soon as firefox.exe appeared on disk, but the NSIS installer writes the registry uninstall entry (what detection reads) last — detection could race the still-running installer (hit on run 28562265782). The poll now waits for both the exe and the Mozilla Firefox*ESR* uninstall entry.
  • OneDrive install script race fixed (same class): the poll accepted binary-OR-registry, but the binary lands before OneDriveSetup's child registers the ARP entry (hit on run 28563420399); it also only checked the WOW6432Node key while modern x64 builds register in the native hive. Success now requires the registry entry (either hive, DisplayName fallback), polling to the deadline even after the setup process exits.

Checklist for submitter

  • Changes file added in changes/.
  • Untrusted data interpolated into shell scripts is validated (scripts run only vendor-registered uninstall strings, gated on Test-Path, best-effort, scope-restricted registry scan).
  • Timeouts/retries: install/uninstall use -Wait; no unbounded loops.

Testing

  • Added/updated automated tests (TestInputInstallerScopeIsSet, ingester scope-fallback/mismatch cases); all 22 apps re-ingest cleanly (outputs differ only by install_script_ref).
  • QA'd all new/changed functionality manually — pending live Windows host (per-app cross-scope cleanup + install).

fleetd/orbit/Fleet Desktop

  • Windows-only change; PowerShell scripts run on Windows hosts.

Windows apps can install per-user (HKCU, %LOCALAPPDATA%) or per-machine
(HKLM, Program Files). The FMA patch policy is scope-blind (osquery's
programs table reads both), so when a host had a copy at one scope and the
FMA installed at the other, a duplicate was created, the stale copy lingered
unmanaged, and the policy never reported patched.

Foundation:
- Ingester now trusts the input's installer_scope when the winget manifest
  is silent on scope (previously panicked). Exact matching still selects the
  right variant for apps that declare per-installer scope (PowerToys, GIMP).
- Set installer_scope on the 9 previously-unset winget inputs, verified from
  each installer's PE requestedExecutionLevel / MSI ALLUSERS / winget Scope.
- Added TestInputInstallerScopeIsSet enforcing scope is set on all inputs,
  plus ingester tests for the scope-fallback and scope-mismatch paths.
- Documented the never-scope-narrow guardrail in the FMA authoring guide
  (README) and the new-fma skill.

Reference remediation (Pattern A):
- PowerToys and GIMP install scripts remove any stale per-user copy before
  installing the per-machine copy. Because Fleet runs scripts as SYSTEM
  (where HKCU is SYSTEM's own hive), they enumerate HKEY_USERS per-user
  hives. Removal is best-effort: it never aborts the machine install and
  never goes false-green.

Detection queries remain scope-blind. Live Windows-host validation of the
Pattern A scripts is still pending (see issue acceptance criteria).
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/gimp/windows.json

=== Install // 7e5269bc -> 72113c10 ===

--- /tmp/old.8rjuJw	2026-07-01 21:57:09.438576928 +0000
+++ /tmp/new.zxCD4b	2026-07-01 21:57:09.438576928 +0000
@@ -1,5 +1,103 @@
-# Learn more about .exe install scripts:
-# http://fleetdm.com/learn-more-about/exe-install-scripts
+# GIMP is managed by Fleet as a PER-MACHINE install (Inno Setup /ALLUSERS).
+# GIMP also offers a per-user install, so a host may already have a stale per-user
+# copy. Fleet's patch policy is scope-blind (osquery's "programs" table reads HKLM
+# + every loaded user hive), so a lingering per-user copy keeps the policy red and
+# leaves two copies on disk.
+#
+# Pattern A (remove-and-replace): before installing the machine copy, remove any
+# per-user copy so the device converges on a single canonical copy. The machine
+# installer upgrades an existing machine copy in place, so same-scope data is
+# preserved; only the cross-scope (per-user) copy is removed.
+# See https://github.com/fleetdm/fleet/issues/48248.
+#
+# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
+# hive — NOT the logged-on user's. Per-user copies must be found under
+# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
+# Removal is best-effort: it never aborts the machine install, and a copy that
+# survives keeps the (truthful) scope-blind policy red rather than false-green.
+
+# Match GIMP 3.x only (the FMA targets GIMP.GIMP.3); avoids touching GIMP 2.
+$displayNameLike = "GIMP 3*"
+
+function Get-UninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
+        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
+    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
+        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
+    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
+        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
+    }
+    return $null
+}
+
+function Remove-OtherScopeCopies {
+    param([Parameter(Mandatory = $true)][string]$DisplayNameLike)
+
+    # Per-user uninstall registrations live in the logged-on users' hives.
+    $roots = @()
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        # Real interactive users only (skip .DEFAULT and service SIDs).
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+
+            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) {
+                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
+                continue
+            }
+
+            $parsed = Get-UninstallExeAndArgs $command
+            if (-not $parsed) {
+                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
+                continue
+            }
+
+            $exe = $parsed.Exe
+            $uninstallArgs = $parsed.Args
+
+            # GIMP uses an Inno Setup uninstaller; ensure a silent uninstall.
+            if ($uninstallArgs -notmatch '(?i)/VERYSILENT') { $uninstallArgs = ("$uninstallArgs /VERYSILENT").Trim() }
+            if ($uninstallArgs -notmatch '(?i)/SUPPRESSMSGBOXES') { $uninstallArgs = ("$uninstallArgs /SUPPRESSMSGBOXES").Trim() }
+            if ($uninstallArgs -notmatch '(?i)/NORESTART') { $uninstallArgs = ("$uninstallArgs /NORESTART").Trim() }
+
+            if (-not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+                continue
+            }
+
+            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uninstallArgs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                $p = Start-Process @opts
+                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+            } catch {
+                # Best effort: never fail the machine install because of other-scope cleanup.
+                Write-Host "  WARNING: failed to remove per-user copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-OtherScopeCopies -DisplayNameLike $displayNameLike
+} catch {
+    # Cleanup is best-effort; proceed to install regardless.
+    Write-Host "Warning during per-user cleanup: $_"
+}
 
 $exeFilePath = "${env:INSTALLER_PATH}"
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/powertoys/windows.json

=== Install // 1a5ce2ca -> 733f8df6 ===

--- /tmp/old.FX7AHO	2026-07-01 21:57:09.494576571 +0000
+++ /tmp/new.gTYeom	2026-07-01 21:57:09.495576564 +0000
@@ -1,6 +1,117 @@
-$exeFilePath = "${env:INSTALLER_PATH}"
+# PowerToys is managed by Fleet as a PER-MACHINE (HKLM) install. Windows also
+# ships a per-user installer (PowerToysUserSetup), so a host may already have a
+# stale per-user copy. Fleet's patch policy is scope-blind (osquery's "programs"
+# table reads HKLM + every loaded user hive), so a lingering per-user copy keeps
+# the policy red and leaves two copies on disk.
+#
+# Pattern A (remove-and-replace): before installing the machine copy, remove any
+# per-user copy so the device converges on a single canonical copy. The machine
+# installer upgrades an existing machine copy in place, so same-scope data is
+# preserved; only the cross-scope (per-user) copy is removed.
+# See https://github.com/fleetdm/fleet/issues/48248.
+#
+# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
+# hive — NOT the logged-on user's. Per-user copies must be found under
+# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
+# Removal is best-effort: it never aborts the machine install, and a copy that
+# survives keeps the (truthful) scope-blind policy red rather than false-green.
+
 $ExpectedExitCodes = @(0, 1641, 3010, 1223)
 
+function Get-UninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
+        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
+    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
+        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
+    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
+        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
+    }
+    return $null
+}
+
+function Remove-OtherScopeCopies {
+    param(
+        [Parameter(Mandatory = $true)][string]$DisplayNameLike,
+        [string]$PublisherLike = ''
+    )
+
+    # Per-user uninstall registrations live in the logged-on users' hives.
+    $roots = @()
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        # Real interactive users only (skip .DEFAULT and service SIDs).
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) {
+                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
+                continue
+            }
+
+            $parsed = Get-UninstallExeAndArgs $command
+            if (-not $parsed) {
+                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
+                continue
+            }
+
+            $exe = $parsed.Exe
+            $uninstallArgs = $parsed.Args
+
+            # PowerToys installers are WiX Burn bundles. Ensure a quiet uninstall.
+            if ($exe -match '(?i)msiexec') {
+                $uninstallArgs = $uninstallArgs -replace '(?i)/i(\{)', '/x$1'
+                if ($uninstallArgs -notmatch '(?i)/x') { $uninstallArgs = ("/x $uninstallArgs").Trim() }
+                if ($uninstallArgs -notmatch '(?i)/qn') { $uninstallArgs = ("$uninstallArgs /qn").Trim() }
+                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            } else {
+                if ($uninstallArgs -notmatch '(?i)/uninstall') { $uninstallArgs = ("$uninstallArgs /uninstall").Trim() }
+                if ($uninstallArgs -notmatch '(?i)/quiet') { $uninstallArgs = ("$uninstallArgs /quiet").Trim() }
+                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            }
+
+            if (-not ($exe -match '(?i)msiexec') -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+                continue
+            }
+
+            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uninstallArgs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                $p = Start-Process @opts
+                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+            } catch {
+                # Best effort: never fail the machine install because of other-scope cleanup.
+                Write-Host "  WARNING: failed to remove per-user copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Stop-Process -Name "PowerToys" -Force -ErrorAction SilentlyContinue
+    Remove-OtherScopeCopies -DisplayNameLike "PowerToys*" -PublisherLike "Microsoft Corporation*"
+} catch {
+    # Cleanup is best-effort; proceed to install regardless.
+    Write-Host "Warning during per-user cleanup: $_"
+}
+
+$exeFilePath = "${env:INSTALLER_PATH}"
+
 try {
 
 $processOptions = @{

=== Uninstall Script (no changes) ===

Extends the per-user vs per-machine fix from PowerToys/GIMP to every
dual-variant Windows Fleet-maintained app. Each install script now removes
the stale opposite-scope copy before installing the managed copy, so the
scope-blind patch policy can truthfully report the host patched.

- Unified all apps onto one canonical, best-effort "Remove-FmaOtherScopeCopies"
  block: it scans ONLY the opposite scope's uninstall hives (HKEY_USERS for
  machine-target apps, since Fleet runs as SYSTEM where HKCU is SYSTEM's own
  hive; HKLM for user-target apps), prefers each vendor's QuietUninstallString
  verbatim, and never aborts the install or goes false-green.
- Machine-target (remove per-user): cursor, firefox, firefox@esr, google-drive,
  onedrive, visual-studio-code, vivaldi, vscodium, windsurf, powertoys, gimp,
  and the MSI apps 1password, box-drive, dropbox, github-desktop, google-chrome,
  microsoft-edge, zoom (MSI apps get a custom install script that runs cleanup
  then msiexec; uninstall stays upgrade-code based).
- User-target (remove per-machine): antigravity-ide, brave-browser, kiro,
  mullvad-browser.
- Per-app DisplayName match + silent-uninstall fallback flags derived from each
  app's own existing uninstall script.

Detection queries remain scope-blind. Not yet validated on a live Windows host;
per-app QA still required before merge.
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/windows.json

=== Install // 8959087b -> b5d4dd9b ===

--- /tmp/old.FSMNT6	2026-07-01 22:13:06.104321395 +0000
+++ /tmp/new.yKb703	2026-07-01 22:13:06.104321395 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "1Password*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/antigravity-ide/windows.json

=== Install // 8b15c4d0 -> c7f687a6 ===

--- /tmp/old.oLhyXc	2026-07-01 22:13:06.166321219 +0000
+++ /tmp/new.mtazzu	2026-07-01 22:13:06.166321219 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Antigravity*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $ExpectedExitCodes = @(0, 3010)

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/box-drive/windows.json

=== Install // 8959087b -> 653463f0 ===

--- /tmp/old.D5tULW	2026-07-01 22:13:06.226321049 +0000
+++ /tmp/new.yO7exU	2026-07-01 22:13:06.226321049 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Box"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/quiet"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/brave-browser/windows.json

=== Install // 9a0c2b15 -> b2a17e99 ===

--- /tmp/old.kUJiG3	2026-07-01 22:13:06.278320902 +0000
+++ /tmp/new.7JYqdW	2026-07-01 22:13:06.279320899 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Brave*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $exitCode = 0

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cursor/windows.json

=== Install // 03589b5e -> 79e083fb ===

--- /tmp/old.sn8s0N	2026-07-01 22:13:06.329320757 +0000
+++ /tmp/new.0hMQHm	2026-07-01 22:13:06.329320757 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Cursor*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dropbox/windows.json

=== Install // 8959087b -> 65bc4efa ===

--- /tmp/old.ujvLpz	2026-07-01 22:13:06.384320602 +0000
+++ /tmp/new.f5MWh8	2026-07-01 22:13:06.385320599 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Dropbox*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox/windows.json

=== Install // 80fb9175 -> d6bc46f1 ===

--- /tmp/old.m4kBrz	2026-07-01 22:13:06.440320443 +0000
+++ /tmp/new.r7ArNM	2026-07-01 22:13:06.440320443 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox (x64*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox@esr/windows.json

=== Install // 36995f4f -> 389738de ===

--- /tmp/old.DYpI66	2026-07-01 22:13:06.497320282 +0000
+++ /tmp/new.C87RWr	2026-07-01 22:13:06.497320282 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox ESR*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gimp/windows.json

=== Install // 72113c10 -> 3816f627 ===

--- /tmp/old.2vaZAB	2026-07-01 22:13:06.547320140 +0000
+++ /tmp/new.xq0Ewq	2026-07-01 22:13:06.547320140 +0000
@@ -1,48 +1,55 @@
-# GIMP is managed by Fleet as a PER-MACHINE install (Inno Setup /ALLUSERS).
-# GIMP also offers a per-user install, so a host may already have a stale per-user
-# copy. Fleet's patch policy is scope-blind (osquery's "programs" table reads HKLM
-# + every loaded user hive), so a lingering per-user copy keeps the policy red and
-# leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GIMP 3*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
 
-# Match GIMP 3.x only (the FMA targets GIMP.GIMP.3); avoids touching GIMP 2.
-$displayNameLike = "GIMP 3*"
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
-    param([Parameter(Mandatory = $true)][string]$DisplayNameLike)
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -50,55 +57,60 @@
             $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
             if (-not $key.DisplayName) { continue }
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # GIMP uses an Inno Setup uninstaller; ensure a silent uninstall.
-            if ($uninstallArgs -notmatch '(?i)/VERYSILENT') { $uninstallArgs = ("$uninstallArgs /VERYSILENT").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/SUPPRESSMSGBOXES') { $uninstallArgs = ("$uninstallArgs /SUPPRESSMSGBOXES").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/NORESTART') { $uninstallArgs = ("$uninstallArgs /NORESTART").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
 
-            if (-not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Remove-OtherScopeCopies -DisplayNameLike $displayNameLike
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
+# Learn more about .exe install scripts:
+# http://fleetdm.com/learn-more-about/exe-install-scripts
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/github-desktop/windows.json

=== Install // 8959087b -> 9fe80ace ===

--- /tmp/old.TrCPjC	2026-07-01 22:13:06.599319993 +0000
+++ /tmp/new.8CLFZq	2026-07-01 22:13:06.599319993 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GitHub Desktop*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "-s"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-chrome/windows.json

=== Install // 8959087b -> 29e7984f ===

--- /tmp/old.jIdJrw	2026-07-01 22:13:06.648319854 +0000
+++ /tmp/new.YNoDRe	2026-07-01 22:13:06.649319851 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Chrome*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-drive/windows.json

=== Install // fa36b892 -> 8e24f67d ===

--- /tmp/old.y4bO7l	2026-07-01 22:13:06.704319695 +0000
+++ /tmp/new.ShP2hB	2026-07-01 22:13:06.704319695 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Drive"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent --force_stop"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/kiro/windows.json

=== Install // c5bc3c21 -> d7705b90 ===

--- /tmp/old.A4j5XV	2026-07-01 22:13:06.761319534 +0000
+++ /tmp/new.wf0tMw	2026-07-01 22:13:06.761319534 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Kiro*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-edge/windows.json

=== Install // 8959087b -> e460919b ===

--- /tmp/old.bNSxYQ	2026-07-01 22:13:06.812319389 +0000
+++ /tmp/new.tj8qST	2026-07-01 22:13:06.812319389 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Edge*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/mullvad-browser/windows.json

=== Install // de703749 -> 00b6fdaa ===

--- /tmp/old.3p5CoI	2026-07-01 22:13:06.868319231 +0000
+++ /tmp/new.x4cj2g	2026-07-01 22:13:06.868319231 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Mullvad Browser*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/onedrive/windows.json

=== Install // ab0b56ab -> 991bcdbd ===

--- /tmp/old.rJJsjF	2026-07-01 22:13:06.924319072 +0000
+++ /tmp/new.7KK4Z4	2026-07-01 22:13:06.924319072 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft OneDrive*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/powertoys/windows.json

=== Install // 733f8df6 -> 47adf288 ===

--- /tmp/old.JWKyEu	2026-07-01 22:13:06.976318925 +0000
+++ /tmp/new.WTrHzI	2026-07-01 22:13:06.976318925 +0000
@@ -1,50 +1,55 @@
-# PowerToys is managed by Fleet as a PER-MACHINE (HKLM) install. Windows also
-# ships a per-user installer (PowerToysUserSetup), so a host may already have a
-# stale per-user copy. Fleet's patch policy is scope-blind (osquery's "programs"
-# table reads HKLM + every loaded user hive), so a lingering per-user copy keeps
-# the policy red and leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "PowerToys*"
+$fmaPublisherLike         = "Microsoft Corporation*"
+$fmaFallbackUninstallArgs = "/uninstall /quiet /norestart"
 
-$ExpectedExitCodes = @(0, 1641, 3010, 1223)
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
+function Remove-FmaOtherScopeCopies {
     param(
-        [Parameter(Mandatory = $true)][string]$DisplayNameLike,
-        [string]$PublisherLike = ''
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
     )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -54,63 +59,57 @@
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
             if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # PowerToys installers are WiX Burn bundles. Ensure a quiet uninstall.
-            if ($exe -match '(?i)msiexec') {
-                $uninstallArgs = $uninstallArgs -replace '(?i)/i(\{)', '/x$1'
-                if ($uninstallArgs -notmatch '(?i)/x') { $uninstallArgs = ("/x $uninstallArgs").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/qn') { $uninstallArgs = ("$uninstallArgs /qn").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
-            } else {
-                if ($uninstallArgs -notmatch '(?i)/uninstall') { $uninstallArgs = ("$uninstallArgs /uninstall").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/quiet') { $uninstallArgs = ("$uninstallArgs /quiet").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
             }
 
-            if (-not ($exe -match '(?i)msiexec') -and -not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Stop-Process -Name "PowerToys" -Force -ErrorAction SilentlyContinue
-    Remove-OtherScopeCopies -DisplayNameLike "PowerToys*" -PublisherLike "Microsoft Corporation*"
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
+$ExpectedExitCodes = @(0, 1641, 3010, 1223)
 
 try {
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/visual-studio-code/windows.json

=== Install // 49122823 -> 2c16ed6d ===

--- /tmp/old.RQ9to4	2026-07-01 22:13:07.031318769 +0000
+++ /tmp/new.1M8WiY	2026-07-01 22:13:07.031318769 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Visual Studio Code*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vivaldi/windows.json

=== Install // d5d49757 -> d9389dbd ===

--- /tmp/old.7SSS6B	2026-07-01 22:13:07.086318613 +0000
+++ /tmp/new.nRo5l8	2026-07-01 22:13:07.086318613 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Vivaldi*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Install Vivaldi silently, machine-wide (Chromium-based browser).
 # Fleet runs installs as SYSTEM, so --system-level is required to install for
 # all users under %ProgramFiles% (and register under HKLM). Without it the

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vscodium/windows.json

=== Install // 38852240 -> 808c2033 ===

--- /tmp/old.gsE2z5	2026-07-01 22:13:07.159318407 +0000
+++ /tmp/new.V15KGO	2026-07-01 22:13:07.160318404 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "VSCodium*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windsurf/windows.json

=== Install // 232abd06 -> 044c2bcd ===

--- /tmp/old.mhF0lj	2026-07-01 22:13:07.232318200 +0000
+++ /tmp/new.NSmrsc	2026-07-01 22:13:07.232318200 +0000
@@ -1,3 +1,112 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Windsurf*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
 
 # install switches:
 #   /VERYSILENT          = no UI at all

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zoom/windows.json

=== Install // 8959087b -> a6f3a656 ===

--- /tmp/old.VYaYBs	2026-07-01 22:13:07.287318044 +0000
+++ /tmp/new.OHe61P	2026-07-01 22:13:07.288318041 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Zoom*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

Ensure Windows Fleet-maintained apps declare an explicit install scope and remove any opposite-scope copy before installation.
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/windows.json

=== Install // 8959087b -> b5d4dd9b ===

--- /tmp/old.9sVOsf	2026-07-01 22:14:56.353230594 +0000
+++ /tmp/new.Ff6YAF	2026-07-01 22:14:56.354230617 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "1Password*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/antigravity-ide/windows.json

=== Install // 8b15c4d0 -> c7f687a6 ===

--- /tmp/old.C1MqV1	2026-07-01 22:14:56.428232329 +0000
+++ /tmp/new.9cxRg3	2026-07-01 22:14:56.429232352 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Antigravity*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $ExpectedExitCodes = @(0, 3010)

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/box-drive/windows.json

=== Install // 8959087b -> 653463f0 ===

--- /tmp/old.rjvKIE	2026-07-01 22:14:56.485233648 +0000
+++ /tmp/new.kQJv3U	2026-07-01 22:14:56.485233648 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Box"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/quiet"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/brave-browser/windows.json

=== Install // 9a0c2b15 -> b2a17e99 ===

--- /tmp/old.QWVEM0	2026-07-01 22:14:56.535234804 +0000
+++ /tmp/new.9JRmVQ	2026-07-01 22:14:56.535234804 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Brave*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $exitCode = 0

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cursor/windows.json

=== Install // 03589b5e -> 79e083fb ===

--- /tmp/old.KLn0Dw	2026-07-01 22:14:56.584235938 +0000
+++ /tmp/new.WRaMoA	2026-07-01 22:14:56.584235938 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Cursor*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dropbox/windows.json

=== Install // 8959087b -> 65bc4efa ===

--- /tmp/old.bSpUW0	2026-07-01 22:14:56.631237025 +0000
+++ /tmp/new.WK34Xv	2026-07-01 22:14:56.632237048 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Dropbox*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox/windows.json

=== Install // 80fb9175 -> d6bc46f1 ===

--- /tmp/old.8yjSpr	2026-07-01 22:14:56.679238135 +0000
+++ /tmp/new.T2hKWG	2026-07-01 22:14:56.679238135 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox (x64*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox@esr/windows.json

=== Install // 36995f4f -> 389738de ===

--- /tmp/old.krxSBe	2026-07-01 22:14:56.735239431 +0000
+++ /tmp/new.HMCcxd	2026-07-01 22:14:56.735239431 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox ESR*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gimp/windows.json

=== Install // 72113c10 -> 3816f627 ===

--- /tmp/old.cOwkhI	2026-07-01 22:14:56.783240541 +0000
+++ /tmp/new.Qr7LDI	2026-07-01 22:14:56.783240541 +0000
@@ -1,48 +1,55 @@
-# GIMP is managed by Fleet as a PER-MACHINE install (Inno Setup /ALLUSERS).
-# GIMP also offers a per-user install, so a host may already have a stale per-user
-# copy. Fleet's patch policy is scope-blind (osquery's "programs" table reads HKLM
-# + every loaded user hive), so a lingering per-user copy keeps the policy red and
-# leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GIMP 3*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
 
-# Match GIMP 3.x only (the FMA targets GIMP.GIMP.3); avoids touching GIMP 2.
-$displayNameLike = "GIMP 3*"
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
-    param([Parameter(Mandatory = $true)][string]$DisplayNameLike)
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -50,55 +57,60 @@
             $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
             if (-not $key.DisplayName) { continue }
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # GIMP uses an Inno Setup uninstaller; ensure a silent uninstall.
-            if ($uninstallArgs -notmatch '(?i)/VERYSILENT') { $uninstallArgs = ("$uninstallArgs /VERYSILENT").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/SUPPRESSMSGBOXES') { $uninstallArgs = ("$uninstallArgs /SUPPRESSMSGBOXES").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/NORESTART') { $uninstallArgs = ("$uninstallArgs /NORESTART").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
 
-            if (-not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Remove-OtherScopeCopies -DisplayNameLike $displayNameLike
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
+# Learn more about .exe install scripts:
+# http://fleetdm.com/learn-more-about/exe-install-scripts
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/github-desktop/windows.json

=== Install // 8959087b -> 9fe80ace ===

--- /tmp/old.00Fi86	2026-07-01 22:14:56.832241674 +0000
+++ /tmp/new.qFy9hM	2026-07-01 22:14:56.833241698 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GitHub Desktop*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "-s"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-chrome/windows.json

=== Install // 8959087b -> 29e7984f ===

--- /tmp/old.mmI12U	2026-07-01 22:14:56.879242762 +0000
+++ /tmp/new.H941Fk	2026-07-01 22:14:56.879242762 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Chrome*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-drive/windows.json

=== Install // fa36b892 -> 8e24f67d ===

--- /tmp/old.yNwn9y	2026-07-01 22:14:56.929243918 +0000
+++ /tmp/new.fPaw4F	2026-07-01 22:14:56.930243941 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Drive"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent --force_stop"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/kiro/windows.json

=== Install // c5bc3c21 -> d7705b90 ===

--- /tmp/old.Q7aw1D	2026-07-01 22:14:56.985245214 +0000
+++ /tmp/new.EzMkix	2026-07-01 22:14:56.985245214 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Kiro*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-edge/windows.json

=== Install // 8959087b -> e460919b ===

--- /tmp/old.HFABa4	2026-07-01 22:14:57.033246324 +0000
+++ /tmp/new.PUUIQb	2026-07-01 22:14:57.034246347 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Edge*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/mullvad-browser/windows.json

=== Install // de703749 -> 00b6fdaa ===

--- /tmp/old.8YkJWL	2026-07-01 22:14:57.086247550 +0000
+++ /tmp/new.aLfE0M	2026-07-01 22:14:57.086247550 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Mullvad Browser*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/onedrive/windows.json

=== Install // ab0b56ab -> 991bcdbd ===

--- /tmp/old.ULGqAa	2026-07-01 22:14:57.139248776 +0000
+++ /tmp/new.I4jwGA	2026-07-01 22:14:57.139248776 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft OneDrive*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/powertoys/windows.json

=== Install // 733f8df6 -> 47adf288 ===

--- /tmp/old.HX3A0y	2026-07-01 22:14:57.188249909 +0000
+++ /tmp/new.A1vCT2	2026-07-01 22:14:57.188249909 +0000
@@ -1,50 +1,55 @@
-# PowerToys is managed by Fleet as a PER-MACHINE (HKLM) install. Windows also
-# ships a per-user installer (PowerToysUserSetup), so a host may already have a
-# stale per-user copy. Fleet's patch policy is scope-blind (osquery's "programs"
-# table reads HKLM + every loaded user hive), so a lingering per-user copy keeps
-# the policy red and leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "PowerToys*"
+$fmaPublisherLike         = "Microsoft Corporation*"
+$fmaFallbackUninstallArgs = "/uninstall /quiet /norestart"
 
-$ExpectedExitCodes = @(0, 1641, 3010, 1223)
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
+function Remove-FmaOtherScopeCopies {
     param(
-        [Parameter(Mandatory = $true)][string]$DisplayNameLike,
-        [string]$PublisherLike = ''
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
     )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -54,63 +59,57 @@
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
             if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # PowerToys installers are WiX Burn bundles. Ensure a quiet uninstall.
-            if ($exe -match '(?i)msiexec') {
-                $uninstallArgs = $uninstallArgs -replace '(?i)/i(\{)', '/x$1'
-                if ($uninstallArgs -notmatch '(?i)/x') { $uninstallArgs = ("/x $uninstallArgs").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/qn') { $uninstallArgs = ("$uninstallArgs /qn").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
-            } else {
-                if ($uninstallArgs -notmatch '(?i)/uninstall') { $uninstallArgs = ("$uninstallArgs /uninstall").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/quiet') { $uninstallArgs = ("$uninstallArgs /quiet").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
             }
 
-            if (-not ($exe -match '(?i)msiexec') -and -not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Stop-Process -Name "PowerToys" -Force -ErrorAction SilentlyContinue
-    Remove-OtherScopeCopies -DisplayNameLike "PowerToys*" -PublisherLike "Microsoft Corporation*"
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
+$ExpectedExitCodes = @(0, 1641, 3010, 1223)
 
 try {
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/visual-studio-code/windows.json

=== Install // 49122823 -> 2c16ed6d ===

--- /tmp/old.2GjGk1	2026-07-01 22:14:57.242251158 +0000
+++ /tmp/new.eKB30T	2026-07-01 22:14:57.242251158 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Visual Studio Code*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vivaldi/windows.json

=== Install // d5d49757 -> d9389dbd ===

--- /tmp/old.Ayrkaq	2026-07-01 22:14:57.294252361 +0000
+++ /tmp/new.6LUNUo	2026-07-01 22:14:57.294252361 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Vivaldi*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Install Vivaldi silently, machine-wide (Chromium-based browser).
 # Fleet runs installs as SYSTEM, so --system-level is required to install for
 # all users under %ProgramFiles% (and register under HKLM). Without it the

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vscodium/windows.json

=== Install // 38852240 -> 808c2033 ===

--- /tmp/old.ekacRe	2026-07-01 22:14:57.361253911 +0000
+++ /tmp/new.BKgM8w	2026-07-01 22:14:57.361253911 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "VSCodium*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windsurf/windows.json

=== Install // 232abd06 -> 044c2bcd ===

--- /tmp/old.Vlq1sf	2026-07-01 22:14:57.429255484 +0000
+++ /tmp/new.OPSRzO	2026-07-01 22:14:57.429255484 +0000
@@ -1,3 +1,112 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Windsurf*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
 
 # install switches:
 #   /VERYSILENT          = no UI at all

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zoom/windows.json

=== Install // 8959087b -> a6f3a656 ===

--- /tmp/old.HU0Mkx	2026-07-01 22:14:57.488256849 +0000
+++ /tmp/new.YM71G8	2026-07-01 22:14:57.488256849 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Zoom*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.01%. Comparing base (4076d13) to head (a76bf7b).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #48603   +/-   ##
=======================================
  Coverage   68.01%   68.01%           
=======================================
  Files        3678     3678           
  Lines      233758   233761    +3     
  Branches    12453    12453           
=======================================
+ Hits       158981   158993   +12     
+ Misses      60475    60472    -3     
+ Partials    14302    14296    -6     
Flag Coverage Δ
backend 69.66% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/windows.json

=== Install // 8959087b -> b5d4dd9b ===

--- /tmp/old.YbH9i1	2026-07-02 02:31:12.567301584 +0000
+++ /tmp/new.L06p4U	2026-07-02 02:31:12.567301584 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "1Password*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/affinity/windows.json

=== Install // 9e9c1496 -> 5d093085 ===

--- /tmp/old.cpS5i7	2026-07-02 02:31:12.630301804 +0000
+++ /tmp/new.2jtdei	2026-07-02 02:31:12.631301807 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Affinity'; Publisher = 'Canva*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/antigravity-ide/windows.json

=== Install // 8b15c4d0 -> c7f687a6 ===

--- /tmp/old.FgtdIe	2026-07-02 02:31:12.680301979 +0000
+++ /tmp/new.Ru2Gyk	2026-07-02 02:31:12.680301979 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Antigravity*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $ExpectedExitCodes = @(0, 3010)

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/arc/windows.json

=== Install // d2d5c7dc -> 9b1928a1 ===

--- /tmp/old.FyVm6A	2026-07-02 02:31:12.728302146 +0000
+++ /tmp/new.nOemLJ	2026-07-02 02:31:12.729302150 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Arc'; Publisher = 'The Browser Company*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/box-drive/windows.json

=== Install // 8959087b -> 653463f0 ===

--- /tmp/old.vju1O0	2026-07-02 02:31:12.783302338 +0000
+++ /tmp/new.xCu4QR	2026-07-02 02:31:12.784302341 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Box"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/quiet"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/brave-browser/windows.json

=== Install // 9a0c2b15 -> b2a17e99 ===

--- /tmp/old.FgB8tK	2026-07-02 02:31:12.831302506 +0000
+++ /tmp/new.AUFY2D	2026-07-02 02:31:12.832302509 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Brave*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $exitCode = 0

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/claude/windows.json

=== Install // 16c020cc -> 5b1e734d ===

--- /tmp/old.ts30A9	2026-07-02 02:31:12.880302676 +0000
+++ /tmp/new.4maJCx	2026-07-02 02:31:12.880302676 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Claude'; Publisher = 'Anthropic*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cursor/windows.json

=== Install // 03589b5e -> 79e083fb ===

--- /tmp/old.NwCJp9	2026-07-02 02:31:12.930302851 +0000
+++ /tmp/new.MnJFv4	2026-07-02 02:31:12.930302851 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Cursor*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dropbox/windows.json

=== Install // 8959087b -> 65bc4efa ===

--- /tmp/old.Jv3eTK	2026-07-02 02:31:12.976303012 +0000
+++ /tmp/new.yHtzXH	2026-07-02 02:31:12.976303012 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Dropbox*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox/windows.json

=== Install // 80fb9175 -> d6bc46f1 ===

--- /tmp/old.Ku5VKl	2026-07-02 02:31:13.021303169 +0000
+++ /tmp/new.98sFaR	2026-07-02 02:31:13.021303169 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox (x64*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox@esr/windows.json

=== Install // 36995f4f -> 389738de ===

--- /tmp/old.Ey5qPy	2026-07-02 02:31:13.073303350 +0000
+++ /tmp/new.NQGjmX	2026-07-02 02:31:13.073303350 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox ESR*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gimp/windows.json

=== Install // 72113c10 -> 3816f627 ===

--- /tmp/old.NFb4cz	2026-07-02 02:31:13.120303514 +0000
+++ /tmp/new.1JiGR1	2026-07-02 02:31:13.120303514 +0000
@@ -1,48 +1,55 @@
-# GIMP is managed by Fleet as a PER-MACHINE install (Inno Setup /ALLUSERS).
-# GIMP also offers a per-user install, so a host may already have a stale per-user
-# copy. Fleet's patch policy is scope-blind (osquery's "programs" table reads HKLM
-# + every loaded user hive), so a lingering per-user copy keeps the policy red and
-# leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GIMP 3*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
 
-# Match GIMP 3.x only (the FMA targets GIMP.GIMP.3); avoids touching GIMP 2.
-$displayNameLike = "GIMP 3*"
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
-    param([Parameter(Mandatory = $true)][string]$DisplayNameLike)
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -50,55 +57,60 @@
             $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
             if (-not $key.DisplayName) { continue }
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # GIMP uses an Inno Setup uninstaller; ensure a silent uninstall.
-            if ($uninstallArgs -notmatch '(?i)/VERYSILENT') { $uninstallArgs = ("$uninstallArgs /VERYSILENT").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/SUPPRESSMSGBOXES') { $uninstallArgs = ("$uninstallArgs /SUPPRESSMSGBOXES").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/NORESTART') { $uninstallArgs = ("$uninstallArgs /NORESTART").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
 
-            if (-not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Remove-OtherScopeCopies -DisplayNameLike $displayNameLike
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
+# Learn more about .exe install scripts:
+# http://fleetdm.com/learn-more-about/exe-install-scripts
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/github-desktop/windows.json

=== Install // 8959087b -> 9fe80ace ===

--- /tmp/old.P7IbNO	2026-07-02 02:31:13.167303678 +0000
+++ /tmp/new.QFhB6d	2026-07-02 02:31:13.168303682 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GitHub Desktop*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "-s"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-chrome/windows.json

=== Install // 8959087b -> 29e7984f ===

--- /tmp/old.K2UGqT	2026-07-02 02:31:13.213303839 +0000
+++ /tmp/new.onqoJW	2026-07-02 02:31:13.213303839 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Chrome*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-drive/windows.json

=== Install // fa36b892 -> 8e24f67d ===

--- /tmp/old.7QUu0B	2026-07-02 02:31:13.262304010 +0000
+++ /tmp/new.lcHlT7	2026-07-02 02:31:13.262304010 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Drive"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent --force_stop"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/kiro/windows.json

=== Install // c5bc3c21 -> d7705b90 ===

--- /tmp/old.IfQLBf	2026-07-02 02:31:13.315304195 +0000
+++ /tmp/new.mRuSVh	2026-07-02 02:31:13.316304198 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Kiro*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-edge/windows.json

=== Install // 8959087b -> e460919b ===

--- /tmp/old.WiEUFr	2026-07-02 02:31:13.361304355 +0000
+++ /tmp/new.Ux1y9W	2026-07-02 02:31:13.362304359 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Edge*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-teams/windows.json

=== Install // d1b37440 -> 83db6f82 ===

--- /tmp/old.WIT6ZC	2026-07-02 02:31:13.415304544 +0000
+++ /tmp/new.mdtpgp	2026-07-02 02:31:13.415304544 +0000
@@ -1,3 +1,150 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Microsoft Teams'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Microsoft Teams classic'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Teams Machine-Wide Installer'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/mullvad-browser/windows.json

=== Install // de703749 -> 00b6fdaa ===

--- /tmp/old.cGxnk2	2026-07-02 02:31:13.469304732 +0000
+++ /tmp/new.JgCmq6	2026-07-02 02:31:13.469304732 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Mullvad Browser*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/onedrive/windows.json

=== Install // ab0b56ab -> 991bcdbd ===

--- /tmp/old.NO0O46	2026-07-02 02:31:13.523304921 +0000
+++ /tmp/new.qb1hIO	2026-07-02 02:31:13.524304924 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft OneDrive*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/powertoys/windows.json

=== Install // 733f8df6 -> 47adf288 ===

--- /tmp/old.9Ad3PD	2026-07-02 02:31:13.571305088 +0000
+++ /tmp/new.k3MUqC	2026-07-02 02:31:13.571305088 +0000
@@ -1,50 +1,55 @@
-# PowerToys is managed by Fleet as a PER-MACHINE (HKLM) install. Windows also
-# ships a per-user installer (PowerToysUserSetup), so a host may already have a
-# stale per-user copy. Fleet's patch policy is scope-blind (osquery's "programs"
-# table reads HKLM + every loaded user hive), so a lingering per-user copy keeps
-# the policy red and leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "PowerToys*"
+$fmaPublisherLike         = "Microsoft Corporation*"
+$fmaFallbackUninstallArgs = "/uninstall /quiet /norestart"
 
-$ExpectedExitCodes = @(0, 1641, 3010, 1223)
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
+function Remove-FmaOtherScopeCopies {
     param(
-        [Parameter(Mandatory = $true)][string]$DisplayNameLike,
-        [string]$PublisherLike = ''
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
     )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -54,63 +59,57 @@
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
             if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # PowerToys installers are WiX Burn bundles. Ensure a quiet uninstall.
-            if ($exe -match '(?i)msiexec') {
-                $uninstallArgs = $uninstallArgs -replace '(?i)/i(\{)', '/x$1'
-                if ($uninstallArgs -notmatch '(?i)/x') { $uninstallArgs = ("/x $uninstallArgs").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/qn') { $uninstallArgs = ("$uninstallArgs /qn").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
-            } else {
-                if ($uninstallArgs -notmatch '(?i)/uninstall') { $uninstallArgs = ("$uninstallArgs /uninstall").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/quiet') { $uninstallArgs = ("$uninstallArgs /quiet").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
             }
 
-            if (-not ($exe -match '(?i)msiexec') -and -not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Stop-Process -Name "PowerToys" -Force -ErrorAction SilentlyContinue
-    Remove-OtherScopeCopies -DisplayNameLike "PowerToys*" -PublisherLike "Microsoft Corporation*"
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
+$ExpectedExitCodes = @(0, 1641, 3010, 1223)
 
 try {
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/slack/windows.json

=== Install // 8b41f934 -> b6e159c4 ===

--- /tmp/old.FFyLm2	2026-07-02 02:31:13.625305276 +0000
+++ /tmp/new.sVveSU	2026-07-02 02:31:13.625305276 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Slack'; Publisher = 'Slack Technologies*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/visual-studio-code/windows.json

=== Install // 49122823 -> 2c16ed6d ===

--- /tmp/old.7SF3kh	2026-07-02 02:31:13.675305451 +0000
+++ /tmp/new.VOIdY1	2026-07-02 02:31:13.675305451 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Visual Studio Code*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vivaldi/windows.json

=== Install // d5d49757 -> d9389dbd ===

--- /tmp/old.iatek7	2026-07-02 02:31:13.725305626 +0000
+++ /tmp/new.ViYVWA	2026-07-02 02:31:13.725305626 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Vivaldi*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Install Vivaldi silently, machine-wide (Chromium-based browser).
 # Fleet runs installs as SYSTEM, so --system-level is required to install for
 # all users under %ProgramFiles% (and register under HKLM). Without it the

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vscodium/windows.json

=== Install // 38852240 -> 808c2033 ===

--- /tmp/old.e3054B	2026-07-02 02:31:13.790305852 +0000
+++ /tmp/new.tZEtln	2026-07-02 02:31:13.791305856 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "VSCodium*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windows-app/windows.json

=== Install // f3fab53b -> 86e2a0dd ===

--- /tmp/old.GJq6pm	2026-07-02 02:31:13.846306048 +0000
+++ /tmp/new.83t0ip	2026-07-02 02:31:13.847306051 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Windows App'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windsurf/windows.json

=== Install // 232abd06 -> 044c2bcd ===

--- /tmp/old.rLwLz7	2026-07-02 02:31:13.913306282 +0000
+++ /tmp/new.nM27Wr	2026-07-02 02:31:13.913306282 +0000
@@ -1,3 +1,112 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Windsurf*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
 
 # install switches:
 #   /VERYSILENT          = no UI at all

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zoom/windows.json

=== Install // 8959087b -> a6f3a656 ===

--- /tmp/old.wOPLlO	2026-07-02 02:31:13.965306463 +0000
+++ /tmp/new.mHKlGq	2026-07-02 02:31:13.965306463 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Zoom*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • :ai

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d6b963aa-fdc2-4150-b3bc-91da2f535c33

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 48248-windows-fma-patch-policies-dont-distinguish-per-user-vs-per-machine-install-scope-leaving-duplicatestale-copies

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The validator's broad LIKE '%Microsoft Edge%' search also matches the
preinstalled 'Microsoft Edge WebView2 Runtime', which Microsoft
version-locks to Edge releases. When the runner image's WebView2 version
coincides with the manifest version, the post-uninstall check falsely
reported Edge as still installed (seen on run 28561163533: WebView2
149.0.4022.98 == Edge target after the image updated from .80).
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/windows.json

=== Install // 8959087b -> b5d4dd9b ===

--- /tmp/old.k6EAJV	2026-07-02 03:02:29.408720912 +0000
+++ /tmp/new.pTIx0t	2026-07-02 03:02:29.409720913 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "1Password*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/affinity/windows.json

=== Install // 9e9c1496 -> 5d093085 ===

--- /tmp/old.RAoz4j	2026-07-02 03:02:29.469720934 +0000
+++ /tmp/new.ybqzdu	2026-07-02 03:02:29.470720934 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Affinity'; Publisher = 'Canva*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/antigravity-ide/windows.json

=== Install // 8b15c4d0 -> c7f687a6 ===

--- /tmp/old.3oSOCd	2026-07-02 03:02:29.528720955 +0000
+++ /tmp/new.7AuaS4	2026-07-02 03:02:29.528720955 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Antigravity*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $ExpectedExitCodes = @(0, 3010)

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/arc/windows.json

=== Install // d2d5c7dc -> 9b1928a1 ===

--- /tmp/old.4BJXPu	2026-07-02 03:02:29.583720974 +0000
+++ /tmp/new.Kvqoww	2026-07-02 03:02:29.584720975 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Arc'; Publisher = 'The Browser Company*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/box-drive/windows.json

=== Install // 8959087b -> 653463f0 ===

--- /tmp/old.Qk4PwD	2026-07-02 03:02:29.648720998 +0000
+++ /tmp/new.VGFtKb	2026-07-02 03:02:29.648720998 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Box"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/quiet"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/brave-browser/windows.json

=== Install // 9a0c2b15 -> b2a17e99 ===

--- /tmp/old.WnPO6s	2026-07-02 03:02:29.704721017 +0000
+++ /tmp/new.NMvWoU	2026-07-02 03:02:29.704721017 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Brave*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $exitCode = 0

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/claude/windows.json

=== Install // 16c020cc -> 5b1e734d ===

--- /tmp/old.8shANC	2026-07-02 03:02:29.760721037 +0000
+++ /tmp/new.Wrd1dE	2026-07-02 03:02:29.761721038 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Claude'; Publisher = 'Anthropic*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cursor/windows.json

=== Install // 03589b5e -> 79e083fb ===

--- /tmp/old.cjbvdO	2026-07-02 03:02:29.817721058 +0000
+++ /tmp/new.Xn6UMw	2026-07-02 03:02:29.817721058 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Cursor*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dropbox/windows.json

=== Install // 8959087b -> 65bc4efa ===

--- /tmp/old.lelvi6	2026-07-02 03:02:29.871721077 +0000
+++ /tmp/new.tWKBWx	2026-07-02 03:02:29.872721077 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Dropbox*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox/windows.json

=== Install // 80fb9175 -> d6bc46f1 ===

--- /tmp/old.ecS4k9	2026-07-02 03:02:29.926721096 +0000
+++ /tmp/new.Ys8EMi	2026-07-02 03:02:29.927721097 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox (x64*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox@esr/windows.json

=== Install // 36995f4f -> 389738de ===

--- /tmp/old.Khj1mq	2026-07-02 03:02:29.988721118 +0000
+++ /tmp/new.9M3MTe	2026-07-02 03:02:29.988721118 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox ESR*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gimp/windows.json

=== Install // 72113c10 -> 3816f627 ===

--- /tmp/old.61m8Fl	2026-07-02 03:02:30.042721137 +0000
+++ /tmp/new.M1qc3R	2026-07-02 03:02:30.042721137 +0000
@@ -1,48 +1,55 @@
-# GIMP is managed by Fleet as a PER-MACHINE install (Inno Setup /ALLUSERS).
-# GIMP also offers a per-user install, so a host may already have a stale per-user
-# copy. Fleet's patch policy is scope-blind (osquery's "programs" table reads HKLM
-# + every loaded user hive), so a lingering per-user copy keeps the policy red and
-# leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GIMP 3*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
 
-# Match GIMP 3.x only (the FMA targets GIMP.GIMP.3); avoids touching GIMP 2.
-$displayNameLike = "GIMP 3*"
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
-    param([Parameter(Mandatory = $true)][string]$DisplayNameLike)
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -50,55 +57,60 @@
             $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
             if (-not $key.DisplayName) { continue }
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # GIMP uses an Inno Setup uninstaller; ensure a silent uninstall.
-            if ($uninstallArgs -notmatch '(?i)/VERYSILENT') { $uninstallArgs = ("$uninstallArgs /VERYSILENT").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/SUPPRESSMSGBOXES') { $uninstallArgs = ("$uninstallArgs /SUPPRESSMSGBOXES").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/NORESTART') { $uninstallArgs = ("$uninstallArgs /NORESTART").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
 
-            if (-not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Remove-OtherScopeCopies -DisplayNameLike $displayNameLike
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
+# Learn more about .exe install scripts:
+# http://fleetdm.com/learn-more-about/exe-install-scripts
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/github-desktop/windows.json

=== Install // 8959087b -> 9fe80ace ===

--- /tmp/old.lUvnrE	2026-07-02 03:02:30.097721157 +0000
+++ /tmp/new.BsRgxb	2026-07-02 03:02:30.097721157 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GitHub Desktop*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "-s"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-chrome/windows.json

=== Install // 8959087b -> 29e7984f ===

--- /tmp/old.DGjLTt	2026-07-02 03:02:30.151721176 +0000
+++ /tmp/new.ce9MdR	2026-07-02 03:02:30.152721176 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Chrome*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-drive/windows.json

=== Install // fa36b892 -> 8e24f67d ===

--- /tmp/old.slQQVG	2026-07-02 03:02:30.207721196 +0000
+++ /tmp/new.gtMyVJ	2026-07-02 03:02:30.208721196 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Drive"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent --force_stop"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/kiro/windows.json

=== Install // c5bc3c21 -> d7705b90 ===

--- /tmp/old.e3i87a	2026-07-02 03:02:30.275721220 +0000
+++ /tmp/new.QiN8Zr	2026-07-02 03:02:30.276721220 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Kiro*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-edge/windows.json

=== Install // 8959087b -> e460919b ===

--- /tmp/old.n9TIK4	2026-07-02 03:02:30.332721240 +0000
+++ /tmp/new.N5oUWi	2026-07-02 03:02:30.333721241 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Edge*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-teams/windows.json

=== Install // d1b37440 -> 83db6f82 ===

--- /tmp/old.QDBbqC	2026-07-02 03:02:30.392721261 +0000
+++ /tmp/new.NOmhks	2026-07-02 03:02:30.392721261 +0000
@@ -1,3 +1,150 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Microsoft Teams'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Microsoft Teams classic'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Teams Machine-Wide Installer'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/mullvad-browser/windows.json

=== Install // de703749 -> 00b6fdaa ===

--- /tmp/old.bZxnI8	2026-07-02 03:02:30.455721284 +0000
+++ /tmp/new.M8xw10	2026-07-02 03:02:30.455721284 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Mullvad Browser*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/onedrive/windows.json

=== Install // ab0b56ab -> 991bcdbd ===

--- /tmp/old.XAsMkj	2026-07-02 03:02:30.515721305 +0000
+++ /tmp/new.vrAzRi	2026-07-02 03:02:30.516721305 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft OneDrive*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/powertoys/windows.json

=== Install // 733f8df6 -> 47adf288 ===

--- /tmp/old.qJcVPl	2026-07-02 03:02:30.568721324 +0000
+++ /tmp/new.0Tgyz4	2026-07-02 03:02:30.569721324 +0000
@@ -1,50 +1,55 @@
-# PowerToys is managed by Fleet as a PER-MACHINE (HKLM) install. Windows also
-# ships a per-user installer (PowerToysUserSetup), so a host may already have a
-# stale per-user copy. Fleet's patch policy is scope-blind (osquery's "programs"
-# table reads HKLM + every loaded user hive), so a lingering per-user copy keeps
-# the policy red and leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "PowerToys*"
+$fmaPublisherLike         = "Microsoft Corporation*"
+$fmaFallbackUninstallArgs = "/uninstall /quiet /norestart"
 
-$ExpectedExitCodes = @(0, 1641, 3010, 1223)
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
+function Remove-FmaOtherScopeCopies {
     param(
-        [Parameter(Mandatory = $true)][string]$DisplayNameLike,
-        [string]$PublisherLike = ''
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
     )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -54,63 +59,57 @@
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
             if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # PowerToys installers are WiX Burn bundles. Ensure a quiet uninstall.
-            if ($exe -match '(?i)msiexec') {
-                $uninstallArgs = $uninstallArgs -replace '(?i)/i(\{)', '/x$1'
-                if ($uninstallArgs -notmatch '(?i)/x') { $uninstallArgs = ("/x $uninstallArgs").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/qn') { $uninstallArgs = ("$uninstallArgs /qn").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
-            } else {
-                if ($uninstallArgs -notmatch '(?i)/uninstall') { $uninstallArgs = ("$uninstallArgs /uninstall").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/quiet') { $uninstallArgs = ("$uninstallArgs /quiet").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
             }
 
-            if (-not ($exe -match '(?i)msiexec') -and -not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Stop-Process -Name "PowerToys" -Force -ErrorAction SilentlyContinue
-    Remove-OtherScopeCopies -DisplayNameLike "PowerToys*" -PublisherLike "Microsoft Corporation*"
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
+$ExpectedExitCodes = @(0, 1641, 3010, 1223)
 
 try {
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/slack/windows.json

=== Install // 8b41f934 -> b6e159c4 ===

--- /tmp/old.A4BBTU	2026-07-02 03:02:30.629721346 +0000
+++ /tmp/new.KbVi09	2026-07-02 03:02:30.629721346 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Slack'; Publisher = 'Slack Technologies*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/visual-studio-code/windows.json

=== Install // 49122823 -> 2c16ed6d ===

--- /tmp/old.uHARvh	2026-07-02 03:02:30.685721365 +0000
+++ /tmp/new.I2qPvM	2026-07-02 03:02:30.686721366 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Visual Studio Code*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vivaldi/windows.json

=== Install // d5d49757 -> d9389dbd ===

--- /tmp/old.EUkOMp	2026-07-02 03:02:30.742721386 +0000
+++ /tmp/new.JH77xl	2026-07-02 03:02:30.742721386 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Vivaldi*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Install Vivaldi silently, machine-wide (Chromium-based browser).
 # Fleet runs installs as SYSTEM, so --system-level is required to install for
 # all users under %ProgramFiles% (and register under HKLM). Without it the

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vscodium/windows.json

=== Install // 38852240 -> 808c2033 ===

--- /tmp/old.ec9RMN	2026-07-02 03:02:30.816721412 +0000
+++ /tmp/new.Doxps3	2026-07-02 03:02:30.817721412 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "VSCodium*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windows-app/windows.json

=== Install // f3fab53b -> 86e2a0dd ===

--- /tmp/old.R7QOwF	2026-07-02 03:02:30.881721435 +0000
+++ /tmp/new.zZcQ5H	2026-07-02 03:02:30.882721435 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Windows App'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windsurf/windows.json

=== Install // 232abd06 -> 044c2bcd ===

--- /tmp/old.IlrhHf	2026-07-02 03:02:30.960721463 +0000
+++ /tmp/new.UZN5uH	2026-07-02 03:02:30.960721463 +0000
@@ -1,3 +1,112 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Windsurf*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
 
 # install switches:
 #   /VERYSILENT          = no UI at all

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zoom/windows.json

=== Install // 8959087b -> a6f3a656 ===

--- /tmp/old.LfCyDk	2026-07-02 03:02:31.019721484 +0000
+++ /tmp/new.R3m9cY	2026-07-02 03:02:31.019721484 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Zoom*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

The poll exited as soon as firefox.exe appeared on disk, but the NSIS
installer writes the registry uninstall entry (what detection reads)
last — so osquery could query programs before the entry existed (seen on
run 28562265782: version 140.12.0 not found 6s after script start while
the installer child was still running). Now waits for both the exe and
the Mozilla Firefox*ESR* uninstall entry.
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/windows.json

=== Install // 8959087b -> b5d4dd9b ===

--- /tmp/old.gUvD5s	2026-07-02 03:34:21.630071454 +0000
+++ /tmp/new.CQ0L5s	2026-07-02 03:34:21.630071454 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "1Password*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/affinity/windows.json

=== Install // 9e9c1496 -> 5d093085 ===

--- /tmp/old.gGtGPR	2026-07-02 03:34:21.684071094 +0000
+++ /tmp/new.8Ii62z	2026-07-02 03:34:21.684071094 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Affinity'; Publisher = 'Canva*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/antigravity-ide/windows.json

=== Install // 8b15c4d0 -> c7f687a6 ===

--- /tmp/old.YyTuD8	2026-07-02 03:34:21.733070755 +0000
+++ /tmp/new.nKz0Wn	2026-07-02 03:34:21.734070747 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Antigravity*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $ExpectedExitCodes = @(0, 3010)

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/arc/windows.json

=== Install // d2d5c7dc -> 9b1928a1 ===

--- /tmp/old.LC3t2S	2026-07-02 03:34:21.781070392 +0000
+++ /tmp/new.LpYMKI	2026-07-02 03:34:21.781070392 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Arc'; Publisher = 'The Browser Company*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/box-drive/windows.json

=== Install // 8959087b -> 653463f0 ===

--- /tmp/old.Jp3wtS	2026-07-02 03:34:21.836069977 +0000
+++ /tmp/new.H6oxhm	2026-07-02 03:34:21.837069969 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Box"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/quiet"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/brave-browser/windows.json

=== Install // 9a0c2b15 -> b2a17e99 ===

--- /tmp/old.Fs8cPX	2026-07-02 03:34:21.892069554 +0000
+++ /tmp/new.3JLtrO	2026-07-02 03:34:21.893069547 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Brave*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $exitCode = 0

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/claude/windows.json

=== Install // 16c020cc -> 5b1e734d ===

--- /tmp/old.tGyeJy	2026-07-02 03:34:21.941069184 +0000
+++ /tmp/new.7ZjY5K	2026-07-02 03:34:21.942069177 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Claude'; Publisher = 'Anthropic*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cursor/windows.json

=== Install // 03589b5e -> 79e083fb ===

--- /tmp/old.ourDma	2026-07-02 03:34:21.990068814 +0000
+++ /tmp/new.YPqWrr	2026-07-02 03:34:21.990068814 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Cursor*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dropbox/windows.json

=== Install // 8959087b -> 65bc4efa ===

--- /tmp/old.SYomdF	2026-07-02 03:34:22.038068452 +0000
+++ /tmp/new.V58UFd	2026-07-02 03:34:22.038068452 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Dropbox*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox/windows.json

=== Install // 80fb9175 -> d6bc46f1 ===

--- /tmp/old.LBYIkK	2026-07-02 03:34:22.083068112 +0000
+++ /tmp/new.txfa4a	2026-07-02 03:34:22.083068112 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox (x64*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox@esr/windows.json

=== Install // 389738de -> 04e4b74e ===

--- /tmp/old.ZHlGI6	2026-07-02 03:34:22.130067757 +0000
+++ /tmp/new.G7wQUN	2026-07-02 03:34:22.130067757 +0000
@@ -121,12 +121,25 @@
 # browser after installing and blocks until it is closed.
 Start-Process -FilePath "$exeFilePath" -ArgumentList "/S"
 
-# Poll for installation to complete
+# Poll for installation to complete. firefox.exe lands on disk before the
+# installer finishes, and the registry uninstall entry -- what Fleet's
+# detection (osquery "programs") reads -- is written last, so wait for both.
+# Exiting on the file alone races detection: the policy/validator can query
+# "programs" before the entry exists.
+$uninstallRoots = @(
+    'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+    'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+)
 $elapsed = 0
 while ($elapsed -lt $maxWaitSeconds) {
     Start-Sleep -Seconds 5
     $elapsed += 5
-    if (Test-Path "$installDir\firefox.exe") {
+    if (-not (Test-Path "$installDir\firefox.exe")) { continue }
+    $entry = Get-ChildItem -Path $uninstallRoots -ErrorAction SilentlyContinue |
+        ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
+        Where-Object { $_.DisplayName -like 'Mozilla Firefox*ESR*' } |
+        Select-Object -First 1
+    if ($entry) {
         Write-Host "Firefox ESR installed successfully after $elapsed seconds"
         Exit 0
     }

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gimp/windows.json

=== Install // 72113c10 -> 3816f627 ===

--- /tmp/old.5EFEH1	2026-07-02 03:34:22.176067409 +0000
+++ /tmp/new.uRI3K6	2026-07-02 03:34:22.176067409 +0000
@@ -1,48 +1,55 @@
-# GIMP is managed by Fleet as a PER-MACHINE install (Inno Setup /ALLUSERS).
-# GIMP also offers a per-user install, so a host may already have a stale per-user
-# copy. Fleet's patch policy is scope-blind (osquery's "programs" table reads HKLM
-# + every loaded user hive), so a lingering per-user copy keeps the policy red and
-# leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GIMP 3*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
 
-# Match GIMP 3.x only (the FMA targets GIMP.GIMP.3); avoids touching GIMP 2.
-$displayNameLike = "GIMP 3*"
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
-    param([Parameter(Mandatory = $true)][string]$DisplayNameLike)
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -50,55 +57,60 @@
             $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
             if (-not $key.DisplayName) { continue }
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # GIMP uses an Inno Setup uninstaller; ensure a silent uninstall.
-            if ($uninstallArgs -notmatch '(?i)/VERYSILENT') { $uninstallArgs = ("$uninstallArgs /VERYSILENT").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/SUPPRESSMSGBOXES') { $uninstallArgs = ("$uninstallArgs /SUPPRESSMSGBOXES").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/NORESTART') { $uninstallArgs = ("$uninstallArgs /NORESTART").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
 
-            if (-not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Remove-OtherScopeCopies -DisplayNameLike $displayNameLike
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
+# Learn more about .exe install scripts:
+# http://fleetdm.com/learn-more-about/exe-install-scripts
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/github-desktop/windows.json

=== Install // 8959087b -> 9fe80ace ===

--- /tmp/old.kHSu4y	2026-07-02 03:34:22.223067055 +0000
+++ /tmp/new.90HLAO	2026-07-02 03:34:22.223067055 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GitHub Desktop*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "-s"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-chrome/windows.json

=== Install // 8959087b -> 29e7984f ===

--- /tmp/old.VRqPQq	2026-07-02 03:34:22.268066715 +0000
+++ /tmp/new.mo9OQH	2026-07-02 03:34:22.268066715 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Chrome*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-drive/windows.json

=== Install // fa36b892 -> 8e24f67d ===

--- /tmp/old.q4STIl	2026-07-02 03:34:22.317066345 +0000
+++ /tmp/new.Ah86xL	2026-07-02 03:34:22.317066345 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Drive"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent --force_stop"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/kiro/windows.json

=== Install // c5bc3c21 -> d7705b90 ===

--- /tmp/old.B0hHJK	2026-07-02 03:34:22.368065960 +0000
+++ /tmp/new.v0vM5v	2026-07-02 03:34:22.369065952 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Kiro*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-edge/windows.json

=== Install // 8959087b -> e460919b ===

--- /tmp/old.imaVv6	2026-07-02 03:34:22.415065605 +0000
+++ /tmp/new.AmQifs	2026-07-02 03:34:22.415065605 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Edge*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-teams/windows.json

=== Install // d1b37440 -> 83db6f82 ===

--- /tmp/old.wDC8Yp	2026-07-02 03:34:22.468065205 +0000
+++ /tmp/new.aCtju9	2026-07-02 03:34:22.469065197 +0000
@@ -1,3 +1,150 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Microsoft Teams'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Microsoft Teams classic'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Teams Machine-Wide Installer'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/mullvad-browser/windows.json

=== Install // de703749 -> 00b6fdaa ===

--- /tmp/old.UMoSWg	2026-07-02 03:34:22.521064805 +0000
+++ /tmp/new.ItfXrC	2026-07-02 03:34:22.521064805 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Mullvad Browser*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/onedrive/windows.json

=== Install // ab0b56ab -> 991bcdbd ===

--- /tmp/old.KfCIux	2026-07-02 03:34:22.573064412 +0000
+++ /tmp/new.5AhDCd	2026-07-02 03:34:22.573064412 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft OneDrive*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/powertoys/windows.json

=== Install // 733f8df6 -> 47adf288 ===

--- /tmp/old.1V3UsR	2026-07-02 03:34:22.620064057 +0000
+++ /tmp/new.Lcgbvi	2026-07-02 03:34:22.620064057 +0000
@@ -1,50 +1,55 @@
-# PowerToys is managed by Fleet as a PER-MACHINE (HKLM) install. Windows also
-# ships a per-user installer (PowerToysUserSetup), so a host may already have a
-# stale per-user copy. Fleet's patch policy is scope-blind (osquery's "programs"
-# table reads HKLM + every loaded user hive), so a lingering per-user copy keeps
-# the policy red and leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "PowerToys*"
+$fmaPublisherLike         = "Microsoft Corporation*"
+$fmaFallbackUninstallArgs = "/uninstall /quiet /norestart"
 
-$ExpectedExitCodes = @(0, 1641, 3010, 1223)
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
+function Remove-FmaOtherScopeCopies {
     param(
-        [Parameter(Mandatory = $true)][string]$DisplayNameLike,
-        [string]$PublisherLike = ''
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
     )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -54,63 +59,57 @@
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
             if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # PowerToys installers are WiX Burn bundles. Ensure a quiet uninstall.
-            if ($exe -match '(?i)msiexec') {
-                $uninstallArgs = $uninstallArgs -replace '(?i)/i(\{)', '/x$1'
-                if ($uninstallArgs -notmatch '(?i)/x') { $uninstallArgs = ("/x $uninstallArgs").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/qn') { $uninstallArgs = ("$uninstallArgs /qn").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
-            } else {
-                if ($uninstallArgs -notmatch '(?i)/uninstall') { $uninstallArgs = ("$uninstallArgs /uninstall").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/quiet') { $uninstallArgs = ("$uninstallArgs /quiet").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
             }
 
-            if (-not ($exe -match '(?i)msiexec') -and -not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Stop-Process -Name "PowerToys" -Force -ErrorAction SilentlyContinue
-    Remove-OtherScopeCopies -DisplayNameLike "PowerToys*" -PublisherLike "Microsoft Corporation*"
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
+$ExpectedExitCodes = @(0, 1641, 3010, 1223)
 
 try {
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/slack/windows.json

=== Install // 8b41f934 -> b6e159c4 ===

--- /tmp/old.UlY90n	2026-07-02 03:34:22.675063642 +0000
+++ /tmp/new.YnFZ7c	2026-07-02 03:34:22.676063634 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Slack'; Publisher = 'Slack Technologies*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/visual-studio-code/windows.json

=== Install // 49122823 -> 2c16ed6d ===

--- /tmp/old.QeUtWh	2026-07-02 03:34:22.728063241 +0000
+++ /tmp/new.vWNcY1	2026-07-02 03:34:22.729063234 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Visual Studio Code*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vivaldi/windows.json

=== Install // d5d49757 -> d9389dbd ===

--- /tmp/old.wTc10h	2026-07-02 03:34:22.779062856 +0000
+++ /tmp/new.wSQHyf	2026-07-02 03:34:22.779062856 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Vivaldi*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Install Vivaldi silently, machine-wide (Chromium-based browser).
 # Fleet runs installs as SYSTEM, so --system-level is required to install for
 # all users under %ProgramFiles% (and register under HKLM). Without it the

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vscodium/windows.json

=== Install // 38852240 -> 808c2033 ===

--- /tmp/old.0SkTXW	2026-07-02 03:34:22.844062366 +0000
+++ /tmp/new.7xn2zj	2026-07-02 03:34:22.845062358 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "VSCodium*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windows-app/windows.json

=== Install // f3fab53b -> 86e2a0dd ===

--- /tmp/old.iwXlpt	2026-07-02 03:34:22.901061935 +0000
+++ /tmp/new.QvXTu1	2026-07-02 03:34:22.901061935 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Windows App'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windsurf/windows.json

=== Install // 232abd06 -> 044c2bcd ===

--- /tmp/old.2mHVYd	2026-07-02 03:34:22.967061437 +0000
+++ /tmp/new.Tcq7Zh	2026-07-02 03:34:22.967061437 +0000
@@ -1,3 +1,112 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Windsurf*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
 
 # install switches:
 #   /VERYSILENT          = no UI at all

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zoom/windows.json

=== Install // 8959087b -> a6f3a656 ===

--- /tmp/old.q2O2FD	2026-07-02 03:34:23.019061044 +0000
+++ /tmp/new.ptu3Nf	2026-07-02 03:34:23.019061044 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Zoom*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

The completion poll accepted the OneDrive.exe binary OR the registry
uninstall entry, but the binary lands before OneDriveSetup's child
registers the ARP entry that detection reads — so the script could exit
while registration was still pending (seen on run 28563420399). Success
now requires the registry entry (native or WOW6432Node hive, with a
DisplayName fallback), polling to the deadline even after the setup
process exits.
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/windows.json

=== Install // 8959087b -> b5d4dd9b ===

--- /tmp/old.Zgq39I	2026-07-02 04:06:42.432743677 +0000
+++ /tmp/new.ZNMUvq	2026-07-02 04:06:42.433743688 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "1Password*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/affinity/windows.json

=== Install // 9e9c1496 -> 5d093085 ===

--- /tmp/old.30WwUx	2026-07-02 04:06:42.487744308 +0000
+++ /tmp/new.t8zQtS	2026-07-02 04:06:42.487744308 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Affinity'; Publisher = 'Canva*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/antigravity-ide/windows.json

=== Install // 8b15c4d0 -> c7f687a6 ===

--- /tmp/old.5X9hRT	2026-07-02 04:06:42.537744882 +0000
+++ /tmp/new.OFqcgr	2026-07-02 04:06:42.537744882 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Antigravity*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $ExpectedExitCodes = @(0, 3010)

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/arc/windows.json

=== Install // d2d5c7dc -> 9b1928a1 ===

--- /tmp/old.DAsevl	2026-07-02 04:06:42.588745467 +0000
+++ /tmp/new.Cy9QsN	2026-07-02 04:06:42.588745467 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Arc'; Publisher = 'The Browser Company*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/box-drive/windows.json

=== Install // 8959087b -> 653463f0 ===

--- /tmp/old.mfPI5l	2026-07-02 04:06:42.644746110 +0000
+++ /tmp/new.YTTlFX	2026-07-02 04:06:42.644746110 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Box"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/quiet"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/brave-browser/windows.json

=== Install // 9a0c2b15 -> b2a17e99 ===

--- /tmp/old.iuYkpx	2026-07-02 04:06:42.693746673 +0000
+++ /tmp/new.8yLHFv	2026-07-02 04:06:42.694746684 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Brave*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 $exitCode = 0

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/claude/windows.json

=== Install // 16c020cc -> 5b1e734d ===

--- /tmp/old.H8FV1O	2026-07-02 04:06:42.744747258 +0000
+++ /tmp/new.HAJDKL	2026-07-02 04:06:42.744747258 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Claude'; Publisher = 'Anthropic*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cursor/windows.json

=== Install // 03589b5e -> 79e083fb ===

--- /tmp/old.dHFvVN	2026-07-02 04:06:42.797747866 +0000
+++ /tmp/new.AH9xUY	2026-07-02 04:06:42.797747866 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Cursor*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dropbox/windows.json

=== Install // 8959087b -> 65bc4efa ===

--- /tmp/old.zJ8Ykq	2026-07-02 04:06:42.845748417 +0000
+++ /tmp/new.uXnMKS	2026-07-02 04:06:42.845748417 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Dropbox*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox/windows.json

=== Install // 80fb9175 -> d6bc46f1 ===

--- /tmp/old.7GG5di	2026-07-02 04:06:42.893748969 +0000
+++ /tmp/new.YaMogS	2026-07-02 04:06:42.894748980 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Mozilla Firefox (x64*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/firefox@esr/windows.json

=== Install // 389738de -> 04e4b74e ===

--- /tmp/old.TQQsLP	2026-07-02 04:06:42.944749554 +0000
+++ /tmp/new.GF2Go2	2026-07-02 04:06:42.944749554 +0000
@@ -121,12 +121,25 @@
 # browser after installing and blocks until it is closed.
 Start-Process -FilePath "$exeFilePath" -ArgumentList "/S"
 
-# Poll for installation to complete
+# Poll for installation to complete. firefox.exe lands on disk before the
+# installer finishes, and the registry uninstall entry -- what Fleet's
+# detection (osquery "programs") reads -- is written last, so wait for both.
+# Exiting on the file alone races detection: the policy/validator can query
+# "programs" before the entry exists.
+$uninstallRoots = @(
+    'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+    'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+)
 $elapsed = 0
 while ($elapsed -lt $maxWaitSeconds) {
     Start-Sleep -Seconds 5
     $elapsed += 5
-    if (Test-Path "$installDir\firefox.exe") {
+    if (-not (Test-Path "$installDir\firefox.exe")) { continue }
+    $entry = Get-ChildItem -Path $uninstallRoots -ErrorAction SilentlyContinue |
+        ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
+        Where-Object { $_.DisplayName -like 'Mozilla Firefox*ESR*' } |
+        Select-Object -First 1
+    if ($entry) {
         Write-Host "Firefox ESR installed successfully after $elapsed seconds"
         Exit 0
     }

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gimp/windows.json

=== Install // 72113c10 -> 3816f627 ===

--- /tmp/old.dyDswu	2026-07-02 04:06:42.994750128 +0000
+++ /tmp/new.2WLzXO	2026-07-02 04:06:42.995750140 +0000
@@ -1,48 +1,55 @@
-# GIMP is managed by Fleet as a PER-MACHINE install (Inno Setup /ALLUSERS).
-# GIMP also offers a per-user install, so a host may already have a stale per-user
-# copy. Fleet's patch policy is scope-blind (osquery's "programs" table reads HKLM
-# + every loaded user hive), so a lingering per-user copy keeps the policy red and
-# leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GIMP 3*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
 
-# Match GIMP 3.x only (the FMA targets GIMP.GIMP.3); avoids touching GIMP 2.
-$displayNameLike = "GIMP 3*"
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
-    param([Parameter(Mandatory = $true)][string]$DisplayNameLike)
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -50,55 +57,60 @@
             $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
             if (-not $key.DisplayName) { continue }
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # GIMP uses an Inno Setup uninstaller; ensure a silent uninstall.
-            if ($uninstallArgs -notmatch '(?i)/VERYSILENT') { $uninstallArgs = ("$uninstallArgs /VERYSILENT").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/SUPPRESSMSGBOXES') { $uninstallArgs = ("$uninstallArgs /SUPPRESSMSGBOXES").Trim() }
-            if ($uninstallArgs -notmatch '(?i)/NORESTART') { $uninstallArgs = ("$uninstallArgs /NORESTART").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
 
-            if (-not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Remove-OtherScopeCopies -DisplayNameLike $displayNameLike
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
+# Learn more about .exe install scripts:
+# http://fleetdm.com/learn-more-about/exe-install-scripts
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/github-desktop/windows.json

=== Install // 8959087b -> 9fe80ace ===

--- /tmp/old.XrXoRQ	2026-07-02 04:06:43.049750760 +0000
+++ /tmp/new.QckKgq	2026-07-02 04:06:43.049750760 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "GitHub Desktop*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "-s"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-chrome/windows.json

=== Install // 8959087b -> 29e7984f ===

--- /tmp/old.kDBnA1	2026-07-02 04:06:43.105751402 +0000
+++ /tmp/new.UXDzv6	2026-07-02 04:06:43.106751414 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Chrome*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/google-drive/windows.json

=== Install // fa36b892 -> 8e24f67d ===

--- /tmp/old.7VrXsW	2026-07-02 04:06:43.156751988 +0000
+++ /tmp/new.gZY9Wy	2026-07-02 04:06:43.156751988 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Google Drive"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--silent --force_stop"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/kiro/windows.json

=== Install // c5bc3c21 -> d7705b90 ===

--- /tmp/old.w1n872	2026-07-02 04:06:43.208752585 +0000
+++ /tmp/new.ugwQ4L	2026-07-02 04:06:43.209752597 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Kiro*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-edge/windows.json

=== Install // 8959087b -> e460919b ===

--- /tmp/old.ehwWcM	2026-07-02 04:06:43.257753147 +0000
+++ /tmp/new.EAUPdY	2026-07-02 04:06:43.257753147 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Edge*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-teams/windows.json

=== Install // d1b37440 -> 83db6f82 ===

--- /tmp/old.ZgJ8ni	2026-07-02 04:06:43.312753779 +0000
+++ /tmp/new.nurQCD	2026-07-02 04:06:43.312753779 +0000
@@ -1,3 +1,150 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Microsoft Teams'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Microsoft Teams classic'; Publisher = 'Microsoft*'; FallbackArgs = '--uninstall -s' }
+    @{ Name = 'Teams Machine-Wide Installer'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/mullvad-browser/windows.json

=== Install // de703749 -> 00b6fdaa ===

--- /tmp/old.82edPJ	2026-07-02 04:06:43.366754399 +0000
+++ /tmp/new.X8lvdq	2026-07-02 04:06:43.367754410 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "user" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "user"
+$fmaDisplayNameLike       = "Mullvad Browser*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/S"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 #

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/onedrive/windows.json

=== Install // 991bcdbd -> fb13c961 ===

--- /tmp/old.cCw3wC	2026-07-02 04:06:43.414754950 +0000
+++ /tmp/new.rsoV8B	2026-07-02 04:06:43.414754950 +0000
@@ -120,48 +120,63 @@
 # silentinstallhq.com). The catch: OneDriveSetup.exe spawns several child
 # processes and starts the resident OneDrive.exe, so a plain Start-Process -Wait
 # can wait indefinitely and hit the CI step timeout. Instead, start the
-# installer, then poll for the per-machine install to land (registry uninstall
-# key + the all-users binary) and return success as soon as it appears.
+# installer, then poll for the per-machine install's registry uninstall entry
+# and return success once it is registered.
 
 $process = Start-Process -FilePath "$exeFilePath" -ArgumentList "/allusers /silent" -PassThru
 
-# Per-machine OneDrive registers an uninstall key and drops OneDrive.exe under
-# Program Files (x86) (or Program Files on x86 OS).
-$uninstallKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\OneDriveSetup.exe"
+# Per-machine OneDrive drops OneDrive.exe under Program Files and registers an
+# uninstall entry -- which is what Fleet's detection (osquery "programs") reads.
+# The binary lands BEFORE the entry is registered, so success requires the
+# registry entry; exiting on the binary alone races detection. Modern x64
+# builds register under the native hive, older ones under WOW6432Node.
+# OneDriveSetup.exe may also exit while a child process finishes the
+# registration, so keep polling until the deadline even after it exits.
+$uninstallKeys = @(
+  "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OneDriveSetup.exe",
+  "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\OneDriveSetup.exe"
+)
+$uninstallRoots = @(
+  "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
+  "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+)
 $exePaths = @(
   "$env:ProgramFiles\Microsoft OneDrive\OneDrive.exe",
   "${env:ProgramFiles(x86)}\Microsoft OneDrive\OneDrive.exe"
 )
 
+function Test-OneDriveRegistered {
+  foreach ($k in $uninstallKeys) {
+    if (Test-Path $k) { return $true }
+  }
+  # Fallback in case the key name drifts across OneDrive builds.
+  $entry = Get-ChildItem -Path $uninstallRoots -ErrorAction SilentlyContinue |
+    ForEach-Object { Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue } |
+    Where-Object { $_.DisplayName -eq 'Microsoft OneDrive' } |
+    Select-Object -First 1
+  return [bool]$entry
+}
+
 $timeoutSeconds = 240
 $deadline = (Get-Date).AddSeconds($timeoutSeconds)
-$installed = $false
+$registered = $false
 
 while ((Get-Date) -lt $deadline) {
-  $exeExists = $false
-  foreach ($p in $exePaths) {
-    if ($p -and (Test-Path $p)) { $exeExists = $true; break }
-  }
-  if ((Test-Path $uninstallKey) -or $exeExists) {
-    $installed = $true
-    break
-  }
-  # If the top-level setup process exited, capture its code and stop polling.
-  if ($process.HasExited) { break }
+  if (Test-OneDriveRegistered) { $registered = $true; break }
   Start-Sleep -Seconds 5
 }
 
-# Final check in case the setup process exited right before the loop bailed.
-if (-not $installed) {
-  $exeExists = $false
-  foreach ($p in $exePaths) {
-    if ($p -and (Test-Path $p)) { $exeExists = $true; break }
-  }
-  if ((Test-Path $uninstallKey) -or $exeExists) { $installed = $true }
+if ($registered) {
+  Write-Host "OneDrive per-machine install registered."
+  Exit 0
 }
 
-if ($installed) {
-  Write-Host "OneDrive per-machine install detected."
+$exeExists = $false
+foreach ($p in $exePaths) {
+  if ($p -and (Test-Path $p)) { $exeExists = $true; break }
+}
+if ($exeExists) {
+  Write-Host "Warning: OneDrive.exe present but uninstall entry not registered within $timeoutSeconds seconds."
   Exit 0
 }
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/powertoys/windows.json

=== Install // 733f8df6 -> 47adf288 ===

--- /tmp/old.NKlGjh	2026-07-02 04:06:43.463755512 +0000
+++ /tmp/new.h4BKmy	2026-07-02 04:06:43.464755524 +0000
@@ -1,50 +1,55 @@
-# PowerToys is managed by Fleet as a PER-MACHINE (HKLM) install. Windows also
-# ships a per-user installer (PowerToysUserSetup), so a host may already have a
-# stale per-user copy. Fleet's patch policy is scope-blind (osquery's "programs"
-# table reads HKLM + every loaded user hive), so a lingering per-user copy keeps
-# the policy red and leaves two copies on disk.
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
 #
-# Pattern A (remove-and-replace): before installing the machine copy, remove any
-# per-user copy so the device converges on a single canonical copy. The machine
-# installer upgrades an existing machine copy in place, so same-scope data is
-# preserved; only the cross-scope (per-user) copy is removed.
-# See https://github.com/fleetdm/fleet/issues/48248.
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
 #
-# NOTE: Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own
-# hive — NOT the logged-on user's. Per-user copies must be found under
-# HKEY_USERS\<user SID>, which is what Remove-OtherScopeCopies does below.
-# Removal is best-effort: it never aborts the machine install, and a copy that
-# survives keeps the (truthful) scope-blind policy red rather than false-green.
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "PowerToys*"
+$fmaPublisherLike         = "Microsoft Corporation*"
+$fmaFallbackUninstallArgs = "/uninstall /quiet /norestart"
 
-$ExpectedExitCodes = @(0, 1641, 3010, 1223)
-
-function Get-UninstallExeAndArgs {
+function Get-FmaUninstallExeAndArgs {
     param([string]$Command)
     # Registry uninstall strings come in three shapes; parse defensively.
-    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    } elseif ($Command -match '^\s*(\S+)\s*(.*)$') {
-        return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() }
-    }
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
     return $null
 }
 
-function Remove-OtherScopeCopies {
+function Remove-FmaOtherScopeCopies {
     param(
-        [Parameter(Mandatory = $true)][string]$DisplayNameLike,
-        [string]$PublisherLike = ''
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
     )
 
-    # Per-user uninstall registrations live in the logged-on users' hives.
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
     $roots = @()
-    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
-        if ($hive.Name -match '_Classes$') { continue }
-        # Real interactive users only (skip .DEFAULT and service SIDs).
-        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
-        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
     }
 
     foreach ($root in $roots) {
@@ -54,63 +59,57 @@
             if ($key.DisplayName -notlike $DisplayNameLike) { continue }
             if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
 
-            $command = if ($key.QuietUninstallString) { $key.QuietUninstallString } else { $key.UninstallString }
-            if (-not $command) {
-                Write-Host "Per-user copy '$($key.DisplayName)' has no uninstall string; skipping."
-                continue
-            }
-
-            $parsed = Get-UninstallExeAndArgs $command
-            if (-not $parsed) {
-                Write-Host "Could not parse uninstall string for '$($key.DisplayName)': $command"
-                continue
-            }
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
 
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
             $exe = $parsed.Exe
-            $uninstallArgs = $parsed.Args
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
 
-            # PowerToys installers are WiX Burn bundles. Ensure a quiet uninstall.
-            if ($exe -match '(?i)msiexec') {
-                $uninstallArgs = $uninstallArgs -replace '(?i)/i(\{)', '/x$1'
-                if ($uninstallArgs -notmatch '(?i)/x') { $uninstallArgs = ("/x $uninstallArgs").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/qn') { $uninstallArgs = ("$uninstallArgs /qn").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
-            } else {
-                if ($uninstallArgs -notmatch '(?i)/uninstall') { $uninstallArgs = ("$uninstallArgs /uninstall").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/quiet') { $uninstallArgs = ("$uninstallArgs /quiet").Trim() }
-                if ($uninstallArgs -notmatch '(?i)/norestart') { $uninstallArgs = ("$uninstallArgs /norestart").Trim() }
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
             }
 
-            if (-not ($exe -match '(?i)msiexec') -and -not (Test-Path -LiteralPath $exe)) {
-                Write-Host "Per-user uninstaller missing on disk for '$($key.DisplayName)': $exe"
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
                 continue
             }
 
-            Write-Host "Removing per-user copy: '$($key.DisplayName)'"
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
             Write-Host "  Command: $exe"
-            Write-Host "  Args: $uninstallArgs"
+            Write-Host "  Args: $uargs"
             try {
                 $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
-                if ($uninstallArgs -ne '') { $opts.ArgumentList = $uninstallArgs }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
                 $p = Start-Process @opts
-                Write-Host "  Per-user uninstall exit code: $($p.ExitCode)"
+                Write-Host "  Exit code: $($p.ExitCode)"
             } catch {
-                # Best effort: never fail the machine install because of other-scope cleanup.
-                Write-Host "  WARNING: failed to remove per-user copy: $_"
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
             }
         }
     }
 }
 
 try {
-    Stop-Process -Name "PowerToys" -Force -ErrorAction SilentlyContinue
-    Remove-OtherScopeCopies -DisplayNameLike "PowerToys*" -PublisherLike "Microsoft Corporation*"
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
 } catch {
-    # Cleanup is best-effort; proceed to install regardless.
-    Write-Host "Warning during per-user cleanup: $_"
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
 }
 
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
+$ExpectedExitCodes = @(0, 1641, 3010, 1223)
 
 try {
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/slack/windows.json

=== Install // 8b41f934 -> b6e159c4 ===

--- /tmp/old.Un8u8D	2026-07-02 04:06:43.517756132 +0000
+++ /tmp/new.UUkKh8	2026-07-02 04:06:43.518756143 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Slack'; Publisher = 'Slack Technologies*'; FallbackArgs = '--uninstall -s' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/visual-studio-code/windows.json

=== Install // 49122823 -> 2c16ed6d ===

--- /tmp/old.Mww1wu	2026-07-02 04:06:43.569756729 +0000
+++ /tmp/new.CKSPjO	2026-07-02 04:06:43.569756729 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Microsoft Visual Studio Code*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Learn more about .exe install scripts:
 # http://fleetdm.com/learn-more-about/exe-install-scripts
 

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vivaldi/windows.json

=== Install // d5d49757 -> d9389dbd ===

--- /tmp/old.3ePG0D	2026-07-02 04:06:43.621757325 +0000
+++ /tmp/new.fta5p5	2026-07-02 04:06:43.621757325 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Vivaldi*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "--uninstall --force-uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 # Install Vivaldi silently, machine-wide (Chromium-based browser).
 # Fleet runs installs as SYSTEM, so --system-level is required to install for
 # all users under %ProgramFiles% (and register under HKLM). Without it the

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/vscodium/windows.json

=== Install // 38852240 -> 808c2033 ===

--- /tmp/old.Q7UWqW	2026-07-02 04:06:43.688758095 +0000
+++ /tmp/new.tfdxnV	2026-07-02 04:06:43.690758118 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "VSCodium*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $exeFilePath = "${env:INSTALLER_PATH}"
 
 try {

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windows-app/windows.json

=== Install // f3fab53b -> 86e2a0dd ===

--- /tmp/old.E8AYOq	2026-07-02 04:06:43.745758749 +0000
+++ /tmp/new.N9Jbcy	2026-07-02 04:06:43.746758760 +0000
@@ -1,3 +1,148 @@
+# Fleet Pattern A (MSIX): converge this app on the MSIX package
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app as an MSIX package, but the app also shipped (or still
+# ships) as a Win32 installer (exe/MSI). A leftover Win32 copy at ANY scope keeps
+# the scope-blind patch policy (osquery's "programs" table) red while the MSIX is
+# current, and leaves a stale, unmanaged copy on disk. Unlike the dual-variant
+# Win32 apps -- where only the opposite scope is swept -- every Win32 copy of an
+# MSIX-managed app is legacy, so BOTH Win32 uninstall hives are swept: HKLM, and
+# HKEY_USERS for per-user installs (Fleet runs as SYSTEM, where HKCU maps to
+# SYSTEM's own hive, so per-user copies are found under HKEY_USERS).
+#
+# Guards:
+# - DisplayName matching is exact, mirrors the detection query's names, and
+#   requires a publisher match, so unrelated software can't match.
+# - MSIX registrations are never touched: PackageFullName-style keys and entries
+#   under \WindowsApps\ are skipped, so a re-run can't remove the package this
+#   script just installed.
+# - Entries with no quiet uninstall path are skipped: a raw UninstallString run
+#   as SYSTEM can hang on UI until Fleet's script timeout kills the install.
+# - A per-user uninstaller launched by SYSTEM removes its files but cannot clean
+#   the user's HKEY_USERS uninstall key (it writes to HKCU, which is SYSTEM's
+#   hive). That phantom entry would keep the policy red forever, so the matched
+#   key is deleted -- but ONLY after verifying the uninstaller removed itself
+#   from disk. If files remain, the key stays and the policy stays truthfully red.
+# - Best-effort: cleanup never aborts the MSIX install below.
+#
+# Data note: Win32 -> MSIX is a cross-packaging move; local app data does not
+# carry into the MSIX container (account-based/server-synced data survives).
+
+$fmaWin32Matchers = @(
+    @{ Name = 'Windows App'; Publisher = 'Microsoft*'; FallbackArgs = '' }
+)
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaWin32Copies {
+    param([array]$Matchers)
+
+    # Every Win32 scope is legacy for an MSIX-managed app: sweep HKLM and all
+    # real interactive users' hives (skip .DEFAULT, service SIDs, _Classes).
+    $roots = @(
+        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
+        'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    )
+    foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+        if ($hive.Name -match '_Classes$') { continue }
+        if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+        $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            # MSIX self-guard: a PackageFullName-style key name means an MSIX
+            # registration, never a legacy Win32 copy.
+            if ($sub.PSChildName -match '_[a-z0-9]{13}$') { continue }
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ("$($key.UninstallString)$($key.InstallLocation)" -match '(?i)\\WindowsApps\\') { continue }
+
+            $matcher = $null
+            foreach ($m in $Matchers) {
+                if ($key.DisplayName -like $m.Name -and ($m.Publisher -eq '' -or $key.Publisher -like $m.Publisher)) {
+                    $matcher = $m
+                    break
+                }
+            }
+            if (-not $matcher) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim) {
+                if ($matcher.FallbackArgs -eq '') {
+                    Write-Host "Fleet: no quiet uninstall path for legacy copy '$($key.DisplayName)', leaving it (policy stays red)"
+                    continue
+                }
+                $uargs = ("$uargs $($matcher.FallbackArgs)").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: legacy Win32 uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing legacy Win32 copy '$($key.DisplayName)' from $root"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove legacy Win32 copy: $_"
+                continue
+            }
+
+            # Per-user uninstallers can't clean their HKEY_USERS key when run as
+            # SYSTEM. Remove the matched key only after the uninstaller is
+            # verifiably gone from disk (Squirrel-style uninstallers self-delete
+            # with a short delay, hence the settle time).
+            if ($root -like 'Registry::HKEY_USERS*' -and -not $isMsi) {
+                Start-Sleep -Seconds 5
+                if (-not (Test-Path -LiteralPath $exe)) {
+                    Remove-Item -Path $sub.PSPath -Recurse -Force -ErrorAction SilentlyContinue
+                    Write-Host "  Removed leftover per-user uninstall registry entry"
+                } else {
+                    Write-Host "  Uninstaller still on disk; leaving registry entry (policy stays red)"
+                }
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaWin32Copies -Matchers $fmaWin32Matchers
+} catch {
+    Write-Host "Fleet: warning during legacy Win32 cleanup: $_"
+}
+
+# ---- MSIX install ----
+
 # MSIX: provision machine-wide so the app is available to all users at sign-in, then
 # opportunistically register for the currently logged-on console user (via a scheduled
 # task in their session) so the app is immediately visible without requiring sign-out.

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/windsurf/windows.json

=== Install // 232abd06 -> 044c2bcd ===

--- /tmp/old.glBy4S	2026-07-02 04:06:43.815759553 +0000
+++ /tmp/new.C2Evzb	2026-07-02 04:06:43.815759553 +0000
@@ -1,3 +1,112 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Windsurf*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
 
 # install switches:
 #   /VERYSILENT          = no UI at all

=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zoom/windows.json

=== Install // 8959087b -> a6f3a656 ===

--- /tmp/old.8o9Qmv	2026-07-02 04:06:43.869760173 +0000
+++ /tmp/new.HGKInO	2026-07-02 04:06:43.869760173 +0000
@@ -1,3 +1,113 @@
+# Fleet Pattern A: converge this app on a single install scope
+# (https://github.com/fleetdm/fleet/issues/48248).
+#
+# Fleet manages this app at "machine" scope. Windows also offers the opposite
+# scope, so a host may already have a stale copy there. The patch policy is
+# scope-blind (osquery's "programs" table reads HKLM + every loaded user hive),
+# so a lingering opposite-scope copy keeps the policy red and leaves two copies
+# on disk. Remove the opposite-scope copy before installing the managed copy so
+# the device converges on one canonical copy; a same-scope upgrade is left to the
+# installer below (preserves data).
+#
+# Fleet runs install scripts as SYSTEM, where HKCU maps to SYSTEM's own hive --
+# NOT the logged-on user's -- so per-user copies are found under HKEY_USERS.
+# Removal is best-effort: it never aborts the install, and a copy that survives
+# keeps the (truthful) scope-blind policy red rather than false-green.
+
+$fmaTargetScope           = "machine"
+$fmaDisplayNameLike       = "Zoom*"
+$fmaPublisherLike         = ""
+$fmaFallbackUninstallArgs = "/uninstall"
+
+function Get-FmaUninstallExeAndArgs {
+    param([string]$Command)
+    # Registry uninstall strings come in three shapes; parse defensively.
+    if ($Command -match '^\s*"([^"]+)"\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '(?i)^\s*(.+?\.exe)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    elseif ($Command -match '^\s*(\S+)\s*(.*)$') { return @{ Exe = $Matches[1]; Args = $Matches[2].Trim() } }
+    return $null
+}
+
+function Remove-FmaOtherScopeCopies {
+    param(
+        [string]$TargetScope,
+        [string]$DisplayNameLike,
+        [string]$PublisherLike,
+        [string]$FallbackArgs
+    )
+
+    # Scan ONLY the opposite scope's uninstall hives, so a broad DisplayName match
+    # can't touch the copy Fleet manages.
+    $roots = @()
+    if ($TargetScope -eq 'machine') {
+        foreach ($hive in (Get-ChildItem 'Registry::HKEY_USERS' -ErrorAction SilentlyContinue)) {
+            if ($hive.Name -match '_Classes$') { continue }
+            # Real interactive users only (skip .DEFAULT and service SIDs).
+            if ($hive.PSChildName -notmatch '^S-1-5-21-') { continue }
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
+            $roots += "Registry::$($hive.Name)\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
+        }
+    } else {
+        $roots += 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
+        $roots += 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
+    }
+
+    foreach ($root in $roots) {
+        foreach ($sub in (Get-ChildItem -Path $root -ErrorAction SilentlyContinue)) {
+            $key = Get-ItemProperty $sub.PSPath -ErrorAction SilentlyContinue
+            if (-not $key.DisplayName) { continue }
+            if ($key.DisplayName -notlike $DisplayNameLike) { continue }
+            if ($PublisherLike -ne '' -and $key.Publisher -notlike $PublisherLike) { continue }
+
+            # Prefer the vendor's QuietUninstallString verbatim; it already carries
+            # the correct silent switches for that installer technology.
+            $useVerbatim = [bool]$key.QuietUninstallString
+            $command = if ($useVerbatim) { $key.QuietUninstallString } else { $key.UninstallString }
+            if (-not $command) { continue }
+
+            $parsed = Get-FmaUninstallExeAndArgs $command
+            if (-not $parsed) { Write-Host "Fleet: could not parse uninstall string: $command"; continue }
+            $exe = $parsed.Exe
+            $uargs = $parsed.Args
+            $isMsi = $exe -match '(?i)msiexec'
+
+            if ($isMsi) {
+                $uargs = $uargs -replace '(?i)/i(\{)', '/x$1'
+                if ($uargs -notmatch '(?i)/x') { $uargs = ("/x $uargs").Trim() }
+                if ($uargs -notmatch '(?i)/qn') { $uargs = ("$uargs /qn").Trim() }
+                if ($uargs -notmatch '(?i)/norestart') { $uargs = ("$uargs /norestart").Trim() }
+            } elseif (-not $useVerbatim -and $FallbackArgs -ne '') {
+                $uargs = ("$uargs $FallbackArgs").Trim()
+            }
+
+            if (-not $isMsi -and -not (Test-Path -LiteralPath $exe)) {
+                Write-Host "Fleet: opposite-scope uninstaller missing on disk: $exe"
+                continue
+            }
+
+            Write-Host "Fleet: removing opposite-scope copy '$($key.DisplayName)'"
+            Write-Host "  Command: $exe"
+            Write-Host "  Args: $uargs"
+            try {
+                $opts = @{ FilePath = $exe; PassThru = $true; Wait = $true; NoNewWindow = $true }
+                if ($uargs -ne '') { $opts.ArgumentList = $uargs }
+                $p = Start-Process @opts
+                Write-Host "  Exit code: $($p.ExitCode)"
+            } catch {
+                Write-Host "  WARNING: failed to remove opposite-scope copy: $_"
+            }
+        }
+    }
+}
+
+try {
+    Remove-FmaOtherScopeCopies -TargetScope $fmaTargetScope -DisplayNameLike $fmaDisplayNameLike -PublisherLike $fmaPublisherLike -FallbackArgs $fmaFallbackUninstallArgs
+} catch {
+    Write-Host "Fleet: warning during opposite-scope cleanup: $_"
+}
+
+# ---- App install ----
+
 $logFile = "${env:TEMP}/fleet-install-software.log"
 
 try {

=== Uninstall Script (no changes) ===

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows FMA patch policies don't distinguish per-user vs per-machine install scope, leaving duplicate/stale copies

1 participant