Skip to content
11 · Patching & UpdatesPart 3 of 4Foundation

Patching third-party apps on Windows with winget

Inventory, prioritise and patch third-party apps on Windows: browsers and runtimes first, winget as SYSTEM, App Installer policy, removing what you can't patch.

Florian Amette7 min read

The patching pillar ends with a warning: much of what attackers exploit on Windows endpoints is not Windows. Browsers, PDF readers, Java and .NET runtimes, archive tools, VPN clients and remote-access software have their own update mechanisms, their own release cadences and, often, no central management at all. Windows Update client policies don't touch them.

This guide is a practical starting point for small and mid-sized estates: find what is installed, decide what matters most, and patch it with tools you already have, mainly the Windows Package Manager (winget) and vendor auto-update policies.

Step 1: inventory what is installed

You can't patch what you don't know about. If you have Microsoft Defender for Endpoint, its software inventory (in Defender Vulnerability Management) is the best source, because it maps installed versions to CVEs. Intune's Discovered apps report and Configuration Manager hardware inventory are good alternatives.

Without those, read the uninstall keys, which is what Programs and Features does. Avoid Get-CimInstance Win32_Product: querying that class triggers a consistency check of every MSI package and can start repairs.

PowerShell
$paths = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
         'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
Get-ItemProperty $paths -ErrorAction SilentlyContinue |
  Where-Object DisplayName |
  Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
  Sort-Object DisplayName |
  Export-Csv "C:\Temp\apps-$env:COMPUTERNAME.csv" -NoTypeInformation

Per-user installs (many browsers, collaboration clients and developer tools) register under HKCU instead, and land in %LOCALAPPDATA%. They escape machine-wide inventories and are often the oldest versions on the device. Check them too, or block per-user installers with App Control.

winget can also show what it recognises and what has an update:

PowerShell
winget upgrade --include-unknown

Step 2: prioritise by exposure

Not every application deserves the same speed. A simple three-tier model works:

TierExamplesTarget
1 - Internet-facing content handlersBrowsers (Edge, Chrome, Firefox), PDF readers, Office add-ins, email clients, Java and .NET runtimes used by browsers or apps, archive tools (7-Zip, WinRAR)Days; within a week for known-exploited
2 - Remote access and network clientsVPN clients, remote-support tools, Zoom/Teams/Webex, SSH/FTP clientsOne to two weeks
3 - Everything elseLine-of-business apps, utilities, developer toolsNormal monthly cycle

Raise any item to the top when it appears in the CISA Known Exploited Vulnerabilities catalog or your vendor's advisory says it is being exploited. Tier 1 apps parse untrusted content all day; that is where exploitation happens.

Step 3: let vendors update where they do it well

The cheapest patching is the one the application does itself. For tier 1, turn the vendor's updater on and enforce a restart window, rather than repackaging every release:

  • Microsoft Edge updates itself through EdgeUpdate. Keep its update policies at the default (updates allowed) and set Notify a user that a browser restart is recommended or required (RelaunchNotification) with a relaunch period. Details are in the Edge hardening guide.
  • Google Chrome has equivalent RelaunchNotification and RelaunchNotificationPeriod policies, and Google Update policies control whether updates are allowed. Use the vendor ADMX templates.
  • Mozilla Firefox is managed through its enterprise policies (policies.json or ADMX); make sure DisableAppUpdate is not set.
  • .NET runtimes receive servicing through Microsoft Update if devices are allowed to get updates for other Microsoft products. In Intune update rings, that is Microsoft product updates; in Group Policy, the "Install updates for other Microsoft products" option of Configure Automatic Updates.

Check what the vendor updater does when the user lacks admin rights. Some updaters install a machine-wide service that works for everyone; others silently fail for standard users, which is exactly what you want everyone to be after removing local admin rights.

Step 4: fill the gaps with winget

For applications without a reliable self-updater, winget can detect and install updates from its repository. Interactive use is simple:

PowerShell
winget upgrade                                  # list available upgrades
winget upgrade --id 7zip.7zip --silent --accept-package-agreements --accept-source-agreements
winget pin add --id Oracle.JavaRuntimeEnvironment   # exclude an app that must stay on a version

For fleet use, run it as SYSTEM from a scheduled task, an Intune remediation or your RMM. winget is part of the App Installer package and not on the SYSTEM account's PATH, so resolve the executable first:

PowerShell
$winget = Resolve-Path "$env:ProgramFiles\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe\winget.exe" |
  Sort-Object Path | Select-Object -Last 1 -ExpandProperty Path

$approved = 'Google.Chrome', 'Mozilla.Firefox', '7zip.7zip', 'Adobe.Acrobat.Reader.64-bit'
foreach ($id in $approved) {
  & $winget upgrade --id $id --exact --silent --scope machine `
    --accept-package-agreements --accept-source-agreements --disable-interactivity
}

Use an explicit list of approved IDs rather than winget upgrade --all. --all updates whatever winget happens to recognise, including apps whose new major version you haven't tested. The Microsoft.WinGet.Client PowerShell module (Get-WinGetPackage, Update-WinGetPackage) gives structured output if you prefer objects to parsing text.

Larger estates usually graduate to a dedicated tool: Intune Enterprise App Management (an Intune Suite capability, included in Microsoft 365 E5 since July 2026), Configuration Manager third-party software update catalogs, or a commercial patching product. The prioritisation and verification steps stay the same.

Step 5: lock down App Installer and winget

winget is also an installation channel, so control it with the App Installer policies under Computer Configuration > Policies > Administrative Templates > Windows Components > Desktop App Installer (registry: HKLM\SOFTWARE\Policies\Microsoft\Windows\AppInstaller):

SettingRecommendedWhy
Enable App Installer Hash OverrideDisabledStops users bypassing installer hash verification
Enable App Installer Local Manifest FilesDisabledBlocks installing from arbitrary local manifests
Enable App Installer Additional Sources / Allowed SourcesOnly your approved sourcesPrevents adding untrusted repositories
Enable App Installer Microsoft Store SourcePer policyDisable if the Store is not an approved channel
Enable App Installer ms-appinstaller protocolDisabledThe ms-appinstaller: URI scheme has been abused to deliver malware; Microsoft disabled it by default in late 2023

These names match the current DesktopAppInstaller.admx, and Intune exposes the same settings in the DesktopAppInstaller area of the Policy CSP. Older templates lack some of them, so use the latest one. On devices where standard users should not install software at all, App Control or AppLocker is the real control; winget policy only narrows one path.

Step 6: remove what you can't patch

Every application you remove is one less update stream. Once the inventory is in place, sort it by owner and last use, and challenge anything without both:

  • Unsupported versions: software past its vendor's end of life (old Java 8 builds without a support contract, legacy Adobe Reader versions, Python 2, abandoned plug-ins) gets no fixes at all. Replace or uninstall.
  • Duplicates: three PDF readers or two archive tools on the same device triple the attack surface for no benefit. Standardise on one per function.
  • Remote-access tools that IT didn't install (AnyDesk, TeamViewer, and similar) are both a patching problem and a common attacker persistence method. Remove them and block them with application control.
  • Browser extensions and runtimes bundled with old line-of-business apps. Ask the vendor for a supported version, and isolate the app if none exists.

Uninstall with the vendor's silent uninstaller or winget uninstall --id <id> --silent, and record each removal. Removal is also the answer for software with no silent update path at all.

Verify it

Re-run the inventory and compare versions against the vendor's current release. On a single device:

PowerShell
winget upgrade --include-unknown           # should list nothing from your approved set

Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='MsiInstaller'; Id=1033,11707} -MaxEvents 20 |
  Format-Table TimeCreated, Id, Message -Wrap

MSI-based installs log event 11707 (installation completed successfully) and 1033 (product installed, with its status) in the Application log from source MsiInstaller. winget's own logs are under %LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir for the account that ran it (for SYSTEM, under the systemprofile folder).

At fleet level, track the percentage of devices on the current version of each tier 1 app, and the oldest version still present. The oldest version is the one an attacker will find.

What breaks

  • Updates that need a restart of the app. Browsers download but don't apply until relaunch; without relaunch notifications, "updated" devices run the old binary for weeks.
  • Major version jumps. Java, PDF editors and line-of-business plug-ins can break on major versions. Pin those and test.
  • Per-user and machine installs side by side. A machine-wide update leaves an older per-user copy untouched, and the user keeps launching that one.
  • winget as SYSTEM can't reach Microsoft Store source packages and fails on some per-user installers. Detect those and handle them separately.

Checklist

  • Software inventory covering machine and per-user installs
  • Tier 1 applications identified with patch targets in days
  • Vendor auto-update enabled and relaunch notifications enforced for browsers
  • .NET and other Microsoft products receive updates through Microsoft Update
  • winget (or a patching tool) updating an approved list as SYSTEM
  • App Installer policies: no hash override, no local manifests, approved sources only
  • Unowned and end-of-life software removed
  • Oldest-version report per tier 1 app reviewed monthly

Third-party patching closes the biggest gap left by Windows Update. For the Microsoft side of the process, see Windows Update policies and the rest of the patching and updates area.

Frequently asked questions

Is winget safe to use for enterprise patching?

The community repository is moderated and installers are hash-checked, but you are still trusting a public source. For production, restrict sources with the App Installer policies, disable hash override and local manifests, and consider a private REST source that contains only packages you have reviewed. Use winget for update detection and delivery, not as an unreviewed app store.

Why does winget work for me but not in a SYSTEM scheduled task?

winget is delivered as part of the App Installer package and is registered per user, so it is not on the PATH of the SYSTEM account. Call winget.exe by its full path under Program Files\WindowsApps, run with --scope machine, and accept that Microsoft Store source packages and some per-user installs are not available in that context.

Should I patch or remove old software?

Remove it whenever nobody can name an owner or a need. Every application you remove is one less update stream to track and one less exploitable component. Older Java runtimes, unused PDF tools, abandoned remote-access tools and duplicate browsers are the usual candidates. Patch what the business actually uses and keep an approved list.

Patching third-party apps on Windows with winget

Related guides