WINGET PATCH MANAGEMENT

Patch the fleet, not one machine at a time.

winget upgrade --all is a per-machine command with no policy, no staging and no record. Third-party patch management needs the version decided per group, the rollout staged so a bad build cannot reach everyone, and evidence that it happened.

THE PART MOST TOOLS GET WRONG

Not everything installs machine-wide.

Brave installs per user with no machine-wide option at all. VS Code’s user setup is the one Microsoft recommends. Chrome and Zoom ship a machine-wide MSI alongside a consumer installer that lands per user. Run a patching tool as SYSTEM — which is how nearly all of them run — and a per-user installer lands in the calling account’s profile, not the user’s. Every report you can produce says it is installed. The person who asked for it still does not have it.

It is a bad failure precisely because it is silent: the fleet looks compliant, the install succeeded, and the gap only surfaces when someone opens a ticket. Worse, the copy under SYSTEM is real software that keeps running and keeps updating itself, out of sight of the user and of your inventory.

Attestree carries scope as an attested property of the package — read from the manifest and corroborated by what the installer actually did in the sandbox — and installs user-scope applications into the real user’s profile. Each copy is attributed to the user who holds it, so inventory counts profiles rather than flattening them into one machine row.

When no user is logged on, it holds and says so instead of running as SYSTEM to make the number go green. And where a machine already carries one of these invisible SYSTEM-profile copies from a previous tool, that debt is surfaced as remediable work rather than left to rot.

DEPLOYMENT RINGS

A bad version should reach four machines, not four thousand.

canary →

A handful of machines that find out first.

pilot →

A representative slice, still small enough to unwind.

broad →

The bulk of the fleet, once the soak floor is met.

all

Everything else, including the machines that were offline.

Each ring holds an exact version, and promotion between them is an explicit, signed act. Rollback makes the ring's previous version current again, in one action rather than a repackaging exercise.

There is also a detector for the failure that rings alone miss: a version that does not spike on a broad push but fails quietly on a handful of machines over days. It is worth being precise about what that does today. It raises a proposal for an operator to accept or decline — it is deliberately not wired to roll anything back on its own, and it ships switched off. Accepting a proposal does not roll anything back yet either: that step is fenced off by default. We would rather tell you it is a signal than imply an automation that is still fenced. Automatic reversal goes furthest on the agent’s own updates: once you switch its health evaluator on, a bad rollout pauses or aborts on its own, and every endpoint keeps a known-good rollback floor on disk.

UPDATE REPORTING

Reporting that counts what is there.

What is outdated, per machine and per user

Inventory is collected from the endpoints themselves, not inferred from what you deployed. A per-user copy of an app is attributed to the person who actually has it, so "twelve machines are behind" does not hide the fact that it is really twenty-two user profiles.

What is installed that you never deployed

Everything the endpoint reports is reconciled against your catalog. Anything that matches nothing is surfaced as foreign — the shadow inventory that arrived by browser download, a vendor updater, or an image you inherited.

What is stuck, and why

A patch that will not converge is a first-class state rather than an absence of good news. Endpoints that stall mid-update raise a fleet alarm instead of quietly falling behind, and a coordinate that loops carries the evidence of why.

FAQ

Straight answers.

Can winget upgrade everything across all my devices?

Running winget upgrade --all on one machine is a per-machine action with no policy, no staging and no record. Fleet patching needs three things it does not have: a decision about which exact version each machine should hold, a staged rollout so a bad version cannot reach everyone at once, and evidence afterwards. Attestree keeps the desired version per group and per ring, converges endpoints toward it continuously, and records each promotion as a signed event.

Does running winget as SYSTEM handle per-user applications?

No, and this is the single most common way a winget-based patching setup quietly fails. A per-user application installed by SYSTEM lands in SYSTEM's own profile, where the person who needs it will never see it — the app is "installed" by every report you can run, and absent from the user's desktop. Attestree treats machine and user scope as an attested property of the package and installs user-scope apps into the real user's profile, attributing each copy to that user in inventory.

What happens when nobody is logged on?

It holds, honestly. A user-scope install with no user session is reported as a pending hold with a reason, and retried, rather than being run as SYSTEM to make the number go green. The same principle covers an upgrade blocked by a running application: it defers and says so, and is excluded from the install-failure rate rather than being logged as a failure that never happened.

How is this different from Intune for third-party patching?

Attestree replaces your third-party app-patching tool and sits beside Intune rather than replacing it. For apps winget or Chocolatey carry, it does the job of Patch My PC, Robopack, Enterprise App Management or a Winget-AutoUpdate script: its own agent installs the version you admitted, ring by ring. Nothing is handed to Intune. Intune's winget support installs from the Microsoft Store source; what it does not do is decide whether a given version should be admitted at all, or leave you signed evidence that it was. Intune keeps Windows Update, drivers, device settings, compliance and enrollment.

Can I roll back a bad patch?

To the ring's previous version, in one action rather than a re-packaging exercise: each ring keeps one armed predecessor, and rolling back makes it current again. Being precise about the automatic case, because it is easy to overstate: the agent's own updates can pause and abort on bad signals without you once you switch that health evaluator on (it ships off), and every endpoint keeps a known-good agent version on disk. For application rollouts there is a slow-burn detector that catches a version failing quietly on a few machines over days, but today it raises a proposal for an operator rather than acting, it ships switched off, and accepting a proposal does not roll anything back yet.

Does this work for applications outside winget?

Chocolatey is managed under the same control plane — inventory and deployment both. Scoop is collected for inventory, but we do not yet count it as a managed manager: deployment is off by default and does not resolve reliably in machine context, so calling it supported would be overselling it. Beyond that, inventory covers what the endpoint reports regardless of how it arrived, so software you cannot yet manage still shows up in reporting and CVE matching rather than being invisible until an auditor asks.