Patching & profiles
Portrait decides which updates apply to which hosts, when, and orchestrates the reboots afterwards. It does not host a single byte of update content.
Managed hosts draw update content from wherever they already do: Microsoft Update, the public WinGet source, or an internal source you run. Portrait’s Windows Update collector reports pending updates with real classification and severity; the profiles below decide what to do with them. Portrait hosts no update binaries itself (why).
The profile types
A profile is a policy that the scheduler evaluates on a cron schedule and enforces by dispatching activities. Each profile targets a set of hosts with a query (below) and carries its own schedule and timezone.
| Profile | What it enforces |
|---|---|
| Upgrade | Which Windows Update classifications (security, critical, definition updates, rollups…) install on the targeted hosts, within a maintenance window, with an autoremove and deferral policy |
| Package | Presence or absence of specific packages. WinGet installs the missing ones; WinGet / WUA / MSI / MSIX removals take out the unwanted ones. There is no source to install MSI/MSIX from, so present is track-only for those providers |
| Reboot | Scheduled or conditional reboots, bounded to a maintenance window, with an optional user-deferral prompt |
| Removal | Decommissioning of stale hosts that have not checked in |
| Script | A library script run on a schedule against the targeted hosts (requires script.execute_as_system) |
Every profile type has full web-UI management (one tab each) and a REST surface.
Targeting with the query language
Profiles - and ad-hoc activity groups - select hosts with a small query language rather than static lists:
hostname:web-* status:active edition:"Windows 11 Pro" build>26100 tag:workstation access-group:root.servers.web
Terms combine, so a profile can target “every active workstation on build 22631 or newer” and pick up new hosts automatically as they are enrolled and tagged.
Maintenance windows
Upgrade, package and reboot profiles each carry a maintenance window - a set of weekdays and a time range (which may wrap past midnight). The scheduler only dispatches a profile’s work to a host while that host is inside the window. “Missed the window → wait for the next one” falls out of this for free: a host that was powered off during its window is simply picked up the next time the window opens, not mid-afternoon.
Reboots
A reboot profile can be conditional (“reboot if an update left the host pending a restart”) or unconditional on a recurrence, and is always bounded to its maintenance window. When configured to, the agent shows the logged-in user a non-modal prompt with a real deadline and snooze options before proceeding; if there is no interactive session, or the prompt fails, the reboot proceeds. A reboot profile will not re-dispatch to a host until it has heard fresh OS state back from that host - so a slow-rebooting machine is not told to reboot again in a loop.
Coordinating with Windows’ own updater
Portrait orchestrates Windows’ Automatic Update rather than trying to own it. Before an upgrade profile dispatches, the agent runs a disk-space preflight; genuine failures retry on a short cadence, and a host that structurally cannot be kept current (for example, chronically low on disk) reports that state honestly rather than showing green because Windows quietly installed the update on its own.