Patchwork Documentation
Complete reference for Patchwork - Windows Update Manager, version 3.0.0. Use the table of contents on the left to jump to any section. For licensing, installation help or bug reports, visit the support page or contact us.
1 - Introduction
Patchwork is a command-line tool for managing Windows Updates. It talks directly to the Windows Update Agent (WUA) via COM, which means there is no .NET runtime dependency, ensuring the binary is self-contained and compact (just a few megabytes in size). The tool covers the full update lifecycle: searching for available updates, downloading them, installing them, uninstalling them, and generating structured reports of what happened for each stage.
Why Patchwork?
The built-in Windows update management only covers part of the problem. wuauclt.exe and UsoClient.exe trigger background scans and installs but give no feedback and no filtering. PSWindowsUpdate is a capable PowerShell module but requires .NET and PowerShell execution policy consideration on some builds. Patchwork sits in the gap. It runs from a Windows console, script, via remote execution (PSExec etc.), or via a scheduled task under SYSTEM. It is highly featured and accepts fine-grained filtering via the command line, and exits with a code that scripts can branch on. As of V3, Patchwork can now be centrally managed, handling many updates in parallel from a single console interface.
Key Features
- Centralised, parallelised management, reporting, updates and push control from a single console.
- Full search, download, install, uninstall, and history operations for Windows Update, Microsoft Update, or via a WSUS server.
- Classification and severity filtering, KB number allow/deny lists, regex title matching, product filtering, size caps, release date windows, and update ID filtering - combinable in a single invocation.
- XML and JSON report output for downstream processing, SIEM ingestion, or compliance tooling.
- Email (SMTP) and syslog notifications after each run.
- Persistent default options can be stored in the registry for simplicity, with a per-run override capability.
- Pre- and post-operation custom actions (batch, PowerShell, or any other executable).
- Windows Update system health check that probes the environment to confirm the environment is working as required.
Intended Audience
This document is aimed at Windows system administrators, MECM(SCCM)/Intune engineers, and anyone automating patch management via scripts, DevOps or scheduled tasks. A working knowledge of Windows Update concepts (WSUS, WUA, classifications, KB articles) is assumed throughout.
2 - System Requirements and Prerequisites
Operating System
Patchwork runs on Windows 7 and later, including all Windows Server editions from Server 2008 R2 onward. Both 32-bit and 64-bit platforms are supported. We will endeavour to support legacy systems with Extended Support, but official support is only provided for Windows versions that provide Active Support.
Privileges
Most operations - download, install, uninstall, and anything that touches WSUS registry settings - require administrative privileges. Run Patchwork from an elevated Command Prompt, as a scheduled task under the SYSTEM account, or via runas. The --search, --history, --installed, and --healthcheck operations can run without elevation, though certain checks within --healthcheck will report reduced information if admin is unavailable.
Network
For Windows Update and Microsoft Update sources, outbound HTTPS to Microsoft's update endpoints must be reachable. For WSUS, the machine must be able to reach the WSUS server on its configured port (typically 8530 for HTTP, 8531 for HTTPS). SMTP and syslog notification features need outbound access to the configured mail or log server.
Disk Space
There is no fixed disk space requirement for Patchwork itself. The binary is small. Update download and installation however, vary by patch content; use --check-available-disk-space to verify free space before a large run.
3 - Installation and Removal
Installer Package (PatchworkSetup.exe)
The standard way to deploy the full Patchwork product - Patchwork.exe, pwtools.exe, and optionally the GUI - is the signed Inno Setup installer, PatchworkSetup.exe. It always installs to the same fixed location, C:\Program Files\Emerita\Patchwork (not user-configurable through the installer), and offers two Setup Types:
| Setup type | Installs |
|---|---|
| Full installation | Core files only: Patchwork.exe, pwtools.exe, Patchwork.pdf. No further choice is offered. |
| Advanced installation | Shows a Select Components page, so Patchwork GUI (Patchwork-gui.exe plus its required service host, Patchwork-svc.exe) can be added alongside Core files - pre-checked once Advanced installation is chosen. |
Patchwork-gui.exe is only available through Advanced installation - a Full installation never includes it (see Section 18.9).
The installer also offers an optional Product Registration page and a Patchwork Command page (for running an arbitrary Patchwork.exe command silently near the end of install), plus command-line switches for a fully unattended deployment - registering a license, scheduling pwtools.exe's own update task, configuring an update source, and running that custom Patchwork.exe command. See installer/INSTALLER_GUIDE.md in the repository for the full switch-by-switch reference. This installer is a separate mechanism from Patchwork.exe --setup below, which self-installs Patchwork.exe on its own, without the GUI or service-host component and without any of the installer package's automation switches.
Quick Install
Run Patchwork once with --setup from an elevated prompt:
patchwork --setup
This copies the running executable to C:\Program Files\Emerita\Patchwork\, adds that directory to the System PATH environment variable, and writes an installation record to HKLM\SOFTWARE\Emerita\Patchwork. After setup, Patchwork is available from any Command Prompt without specifying the full path (a new shell session, or a refreshenv, is needed for the PATH change to take effect in existing sessions).
Custom Install Path
To install to a different directory, pass the desired path as an argument:
patchwork --setup "D:\Tools\Patchwork"
Recommended Install
We would recommend you both register and provide default settings during install. You can choose a set of default options that work in most cases via --opt-verbose, but you can also provide custom settings that are tailored to your environment via --opt-save. A registered install can be as simple as:
patchwork.exe --setup --register "FirstName LastName/Companyname|XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" --opt-verbose
To provide custom settings that suit your particular environment:
patchwork.exe --setup --register "FirstName LastName/Companyname|XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" --opt-save --autoaccepteula --continue-errors --logfile c:\windows\temp\Patchwork.log --show-progress --color --info --hide-sensitive --wsus-server http://wsusserver.internal.pri
Running Without Installing
Patchwork does not require installation. The executable can be placed anywhere on the file system and run directly. --setup is a convenience that handles the PATH registration; it is not a prerequisite.
Upgrading
Running --setup when Patchwork is already installed performs an upgrade rather than a fresh install. It compares the version of the running binary against the version recorded in the registry and, if the running binary is newer, copies it over the installed copy. The PATH and directory are left unchanged.
patchwork --setup
To upgrade to a specific path, copy the new binary there and run with --setup pointing to the same directory used during the original install.
If --setup relocates the install to a different directory and a Patchwork Install or Patchwork Reboot Cycle scheduled task exists, --setup warns that the task still points at the old path - it does not rewrite the task itself. Re-run --update-schedule to point it at the new location.
Uninstalling
patchwork --remove
This removes the installed executable, deletes the installation directory, removes the PATH entry, deletes Patchwork's own scheduled tasks (Patchwork Install, Patchwork Reboot Cycle, and the legacy Patchwork Update), and deletes HKLM\SOFTWARE\Emerita\Patchwork. Administrator privileges are required.
Any Patchwork Product Update task created by pwtools.exe is deliberately left alone - pwtools.exe is a separate utility with its own lifecycle. Remove it with pwtools.exe --update-schedule remove.
Verifying the Installation
patchwork --version
patchwork --healthcheck
--version prints the version string. --healthcheck probes the environment more thoroughly to determine if the Windows Update Agent API is working as expected (see Section 7 for details).
4 - Licensing and Registration
Interactive Registration
patchwork --register
Prompts for a username and serial number, then stores the license. No other arguments are needed.
Unattended Registration
Pass the credentials on the command line, separated by a pipe character:
patchwork --register "FirstName LastName/Companyname|XXXXX-XXXXX-XXXXX-XXXXX"
The argument must be quoted if it contains spaces. This form is suitable for deployment scripts where interactive input is not available.
Combining Registration with Other Operations
As mentioned above, --register can be combined with --setup and other configuration operations in a single invocation:
patchwork --setup --register "FirstName LastName/Companyname|XXXXX-XXXXX-XXXXX-XXXXX" --opt-save --use-windowsupdate
License Storage
License data is managed by the Obsidium licensing system. If you receive a false positive from your AV solution please exclude Patchwork.exe from scanning, contact your AV vendor directly to ensure the executable is whitelisted, or contact us directly so we can contact the AV vendor on your behalf.
Unlicensed Versions
If you are not a registered customer and are not using an evaluation version of Patchwork, it will report an unlicensed state on startup, will provide limited functionality and exit any operations with code 8 (InvalidVersion). No update operations are performed.
Home Edition
To ensure accurate testing of the Home Edition the switch --home should be used with the trial version of Patchwork to ensure it behaves with the same limitations as the registered Home Edition. --opt-save can be used in conjunction with --home to ensure this setting is applied on each run.
5 - Concepts and Terminology
Update Sources
Patchwork obtains updates from one of three sources, selected by the flags described in Section 7.
Windows Update (WU) - Microsoft's public update service for the Windows operating system. This is the default source when no WSUS server is detected in the registry.
Microsoft Update (MU) - A superset of Windows Update that also distributes updates for other Microsoft products such as Office. To use it, we recommend the Microsoft Update service is first registered with the local WUA instance (--register-microsoftupdate), or you can force it for a single run with --use-microsoftupdate.
WSUS - Windows Server Update Services, the enterprise update proxy. When WSUS is configured on a machine (via Group Policy, MECM(SCCM) or the registry), Patchwork will use it by default. You can override this with --use-windowsupdate or --use-microsoftupdate, or point to a specific/alternative server with --wsus-server.
Update Classifications
The --classification switch accepts a string of single-letter codes, each enabling a category:
| Code | Classification | Typical content |
|---|---|---|
C | Critical | Fixes for severe vulnerabilities and defects |
U | Security | Security bulletins and vulnerability patches |
D | Definition | Antivirus and antimalware signature updates |
I | Update | General improvements and non-security fixes |
R | Rollup | Cumulative rollup packages |
S | Service Pack | Major packaged update collections |
F | Feature Pack | New feature additions |
E | Driver Sets | Driver update collections |
V | Drivers | Individual device driver updates |
G | Upgrades | Major OS version upgrades |
Codes can be combined. --classification CU limits results to Critical and Security updates. --classification CUDISRF covers most software updates while excluding drivers and upgrades.
Update Severities
The --severity switch accepts single-letter codes representing the MSRC severity rating assigned to an update:
| Code | Severity | Meaning |
|---|---|---|
C | Critical | Exploitable remotely without user interaction |
I | Important | Could compromise system integrity or availability |
M | Moderate | Exploitability is mitigated by configuration or authentication |
L | Low | Difficult to exploit; minimal impact |
U | Unknown | No severity rating assigned |
The U code is useful when filtering driver or definition updates, which often carry no severity value.
The Search-Download-Install Lifecycle
Patchwork separates the three stages of update deployment into discrete operations. Running --install performs all three internally (search, then download, then install). Running --search alone lets you review what is available before committing. Running --download stages updates to the local WUA cache without installing; a subsequent --install will use the cached copies.
This separation matters for scenarios where you want to pre-stage updates and then install during a separate maintenance window.
Default Options and Precedence
Patchwork supports a saved set of default options stored in the registry under HKLM\Software\Emerita\Patchwork as the DefaultOptions value. These are automatically prepended to the command line on every run.
CLI arguments always take precedence over saved defaults. If a saved default sets --logfile C:\Logs\default.log and the current command line specifies --logfile C:\Logs\today.log, the value from the command line wins.
Use --opt-ignore on any individual run to completely bypass the saved defaults for a particular run without deleting them.
Two switches write these defaults, and they differ in what happens to what is already stored: --opt-save replaces the saved set with the options on the current command line, while --opt-add adds the current command line's options to the saved set. --opt-clear removes them entirely.
Exit Codes
Patchwork exits with a numeric code that scripts can branch on. The full table is in Section 9. The most commonly used codes are:
- 0 - success, no reboot needed
- 1 - at least one error, no reboot needed
- 3 - no updates matched the filter criteria
- 10 - success, but one or more updates require a reboot
6 - Quick Start
The following examples assume Patchwork is installed and the binary is in PATH. Run from an elevated Command Prompt unless noted otherwise.
Check what updates are available:
patchwork --search --info
Search for Critical and Security updates only:
patchwork --search --classification CU --info
Download Critical and Security updates without installing:
patchwork --download --classification CU
Install Critical and Security updates, reboot automatically if required:
patchwork --install --classification CU --autoaccepteula --reboot-if-needed
Install all updates, log to file, no console output:
patchwork --install --autoaccepteula --silent --logfile C:\Logs\updates.log
Check the environment before running:
patchwork --healthcheck
7 - Command Reference
Options are grouped here as they appear in --help. One operation flag is required per invocation unless the command is a management-only action. The primary six are --search, --download, --install, --uninstall, --history, and --installed (Section 7.1 below); the rest of the invocation is satisfied by any of --register, --setup, --remove, --opt-save, --opt-add, --opt-clear, --opt-show, --opt-verbose, --list-exit-codes, --healthcheck, --download-cache, --install-cache, --donothing, --update-schedule, --register-microsoftupdate, --clear-wsus-server, --unregister, --check-available-disk-space, or --refresh-last-update-timestamps - each documented individually in its own section below.
7.1 - Operations
These flags determine what operation Patchwork performs. Exactly one primary operation (--search, --download, --install, --uninstall, --history, --installed) must be present per invocation, unless the operation is a management-only action listed below.
--search
Search queries the configured update source for available updates without downloading or installing anything. Apply any filter switches alongside --search to narrow the results. Combine with --info to provide full update details, or with --xmlout/--jsonout to produce an output report.
patchwork --search --classification CU --info
patchwork --search --releasedate days:30 --jsonout C:\Reports\pending.json
--download
Searches for updates matching the active filters and downloads them to the Windows Update local cache. The updates are ready to install on a subsequent --install run without downloading again.
patchwork --download --classification CU --severity CI
--install
Searches for matching updates, downloads any that are not already cached, and installs them. This is the most commonly used operation for a standard patching run.
patchwork --install --classification CU --autoaccepteula --reboot-if-needed
--uninstall
Removes previously installed updates. Combine with --kb, --match-id, --match-filter/--matchfile, or --classification to target specific updates. Not all updates support uninstallation. Patchwork will report which ones are uninstallable before proceeding.
patchwork --uninstall --kb KB5012345
A selector is required. --uninstall on its own, with no selector switch, is rejected with a syntax error (exit code 7) rather than silently targeting every installed update:
--uninstall with no selector would target every installed update. Pass a selector
(--kb, --match-id, --match-filter/--matchfile, or --classification) or pass --all
to confirm every installed update should be uninstalled.
To genuinely uninstall everything, pass --all explicitly alongside --uninstall instead of a selector.
--history
Lists the Windows Update installation history for the local machine. This is the equivalent of Settings → Windows Update → Update History. No filtering is applied; all recorded history is shown.
patchwork --history --xmlout C:\Reports\history.xml
--installed
Lists updates currently installed on the system - the equivalent of Settings → Apps → Installed Updates. Combine with --xmlout or --jsonout for a structured inventory.
patchwork --installed --jsonout C:\Reports\installed.json
--download-cache PATH
Like --download, but stages updates into the specified directory instead of the default Windows Update local cache. Hidden from --help; intended for the same pre-stage/central-repository workflows as Section 10's Staged Pilot Rollout example, without relying on xcopy-ing WUA's own cache afterward.
patchwork --download-cache D:\PatchCache --classification CU
--install-cache PATH
Like --install, but installs from the specified directory instead of the default WUA cache - the install-side counterpart to --download-cache. Hidden from --help.
patchwork --install-cache D:\PatchCache --classification CU --autoaccepteula
--redownload
Re-downloads updates that are already installed rather than skipping them, when used with --download-cache. Hidden from --help; useful for rebuilding a cache directory from scratch or capturing updates for offline reuse on other machines even though this machine already has them.
patchwork --download-cache D:\PatchCache --classification CU --redownload
--register ["USER|KEY"]
Registers the product license. Without arguments it will prompt interactively. With the "USER|KEY" argument, it registers unattended. See Section 4.
--unregister
Removes any stored license data from the system, reverting Patchwork to its unlicensed/trial state. Hidden from --help. The counterpart to --register; unlike pwtools.exe --clear (see Section 17), this is run via Patchwork.exe itself.
patchwork --unregister
--setup [PATH]
Installs Patchwork within Windows and adds it to the System PATH. Defaults to C:\Program Files\Emerita\Patchwork if no path is given. Requires administrator privileges. See Section 3.
--remove
Uninstalls Patchwork. Removes the executable, directory, PATH entry, and registry keys. Requires administrator privileges.
7.2 - Update Type Selection
By default, Patchwork searches for software updates only. These switches change that scope.
--driveronly
Restricts the search to driver updates. Mutually exclusive with --includedrivers.
patchwork --search --driveronly --info
--includedrivers
Adds driver updates to the software update search. Mutually exclusive with --driveronly.
patchwork --install --includedrivers --classification CUV
--alltypes
Includes all update types that the WUA supports. Use this when you want to cast the widest possible net, for example when auditing a machine.
patchwork --search --alltypes --info
--preview
Includes preview, optional, and beta updates, which are hidden from the default search. Use with care in production environments; preview updates are not yet fully validated. This option is not available on versions of Windows prior to Windows 10 1903 and Windows Server 2022. We attempt to work around issues using --preview on older builds, but we recommend in those cases the switch is not used at all.
patchwork --search --preview --info
--include-potentially-superseded-updates
Includes updates that a newer update has superseded but which WUA still considers installable (for example, an older cumulative update still offered alongside a newer one during a transition period). Hidden from --help since it is a narrow, rarely-needed case; most environments should rely on WUA's own default superseded-update filtering instead.
patchwork --search --include-potentially-superseded-updates --info
7.3 - Search Criteria and Filtering
These switches control which updates are included or excluded from an operation. When multiple filters are active, an update must satisfy all of them to be processed (AND logic). Within the --kb and --match-id switches, multiple values use OR logic.
--criteria CRITERIA
Passes a raw WUA search criteria string directly to the Windows Update Agent. This overrides Patchwork's default criteria construction. Useful for edge cases not covered by the other filter switches.
Common criteria predicates:
| Predicate | Meaning |
|---|---|
IsInstalled=0 | Not yet installed (Patchwork's default) |
IsInstalled=1 | Already installed |
Type='Software' | Software updates only |
Type='Driver' | Driver updates only |
IsHidden=0 | Not hidden |
patchwork --search --criteria "IsInstalled=0 AND Type='Software' AND IsHidden=0"
--classification FLAGS
Filters updates by classification category. Pass one or more letter codes as a single string without separators. See Section 5 for the full code table.
patchwork --install --classification CU # Critical and Security
patchwork --install --classification CUDISRF # All software, no drivers
patchwork --search --classification CUDISRFEVG # Everything
--severity FLAGS
Filters updates by MSRC severity rating. See Section 5 for codes.
patchwork --install --severity CI # Critical and Important only
patchwork --search --severity CIML # All rated updates
patchwork --search --severity U # Updates with no severity rating
--product PRODUCTS
Includes only updates that belong to a matching product or category. The value is a comma-separated list of substrings; an update passes if any of its WUA category names contains any of the listed strings (case-insensitive substring match).
patchwork --search --product "Windows 10"
patchwork --search --product "Windows 11,Office"
--exclude-product PRODUCTS
Excludes updates that match any of the listed product substrings. Follows the same matching logic as --product.
patchwork --install --exclude-product "Windows Defender"
patchwork --install --exclude-product "Office,Silverlight"
--kb KB_NUMBERS
Filters by KB article number. Accepts a comma-separated list. Prefix a KB number with - to exclude it; all others are treated as inclusions. The KB prefix is optional.
patchwork --install --kb KB5078740 # Include one KB
patchwork --install --kb KB5078740,KB5034441 # Include two KBs
patchwork --install --kb KB5078740,-KB5034441 # Include one, exclude another
patchwork --search --kb -KB5034441 # Exclude one KB, show all others
When include entries are present, only those specific updates pass. When only exclude entries are present, everything except the excluded KBs passes.
--match-filter PATTERN
Applies a regex pattern to update titles and descriptions. Only updates whose title or description matches the pattern are included. Standard .NET-compatible regex syntax applies.
patchwork --search --match-filter "Cumulative Update.*2025"
patchwork --search --match-filter "(?i)security" # Case-insensitive
patchwork --search --match-filter "Windows (10|11)"
--nomatch-filter PATTERN
Excludes updates whose title or description matches the regex pattern.
patchwork --install --nomatch-filter "Preview|Beta"
patchwork --install --nomatch-filter "Defender"
--matchfile FILE
Loads include patterns from a text file instead of specifying them inline. One regex pattern per line. Blank lines and lines beginning with # are treated as comments and ignored. If the file contains multiple patterns, they are combined with OR logic (an update matching any pattern is included).
Example file - critical-kbs.txt:
KB5078740
KB5034441
Security Update.*2025
Cumulative Update for Windows
patchwork --install --matchfile C:\Config\critical-kbs.txt
--matchfile produces an include-only filter. Use --nomatch-filter for excludes.
--nomatchfile FILE
Loads exclude patterns from a text file. The file format is identical to --matchfile - one regex per line, blank lines and # comments are ignored, multiple patterns combined with OR logic. An update matching any pattern in the file is excluded.
Example file - excluded-kbs.txt:
# Preview and beta releases
Preview
Beta
# Specific KBs to hold back
KB5034441
patchwork --install --nomatchfile C:\Config\excluded-kbs.txt
--matchfile and --nomatchfile can be combined with each other and with --match-filter / --nomatch-filter in the same run.
patchwork --install --matchfile C:\Config\approved.txt --nomatchfile C:\Config\excluded.txt
--releasedate DATE
Filters updates by their release date. Several formats are accepted:
| Format | Meaning |
|---|---|
YYYY-MM-DD | Released on or after this date (same as ge:YYYY-MM-DD) |
ge:YYYY-MM-DD | On or after (inclusive) |
gt:YYYY-MM-DD | Strictly after |
le:YYYY-MM-DD | On or before (inclusive) |
lt:YYYY-MM-DD | Strictly before |
eq:YYYY-MM-DD | Exact date match |
days:N | Released within the last N calendar days |
patchwork --search --releasedate days:30
patchwork --search --releasedate ge:2025-01-01
patchwork --install --releasedate gt:2025-03-01
Updates with no release date recorded by WUA are always excluded when this filter is active.
--max-update-count COUNT
Caps the number of updates that will be processed in a single run. Applied after all other filters, so COUNT reflects the final set. Useful for staged rollouts or when you want to limit the scope of a run. Outstanding updates will be picked up on subsequent runs.
patchwork --install --classification CU --max-update-count 10
--max-total-size SIZE
Caps the cumulative size of updates that will be processed. Size is evaluated in the order updates are returned; once adding the next update would exceed the cap, it and all subsequent updates are dropped. Accepts a numeric value with an optional suffix: K, M, G, or T (or two-letter variants KB, MB, GB, TB).
patchwork --download --max-total-size 500M
patchwork --download --max-total-size 2G
--match-id IDS
Filters by update GUID. Accepts a comma-separated list of GUIDs. Prefix a GUID with - to exclude it. Matching is case-insensitive.
patchwork --install --match-id 9fb049d9-8ee3-4913-937f-196648006ca5
patchwork --install --match-id ID1,ID2,-ID3
--only-downloaded
Restricts results to updates that have already been downloaded to the local WUA cache. Useful to run an install pass that uses only pre-staged content.
patchwork --install --only-downloaded --autoaccepteula
--all
Confirms that an operation with no other selector should apply to every eligible update. Currently this only matters for --uninstall, which otherwise refuses to run without a selector (--kb, --match-id, --match-filter/--matchfile, or --classification) - --all is the explicit way to say "yes, every installed update" instead.
patchwork --uninstall --all
--all is saved by --opt-save/--opt-add like any other filtering switch (see Appendix D); think carefully before saving it as a default, since it removes the safety check on every subsequent unattended --uninstall run.
7.4 - Configuration Options
These switches configure the update source and related service settings. Most write temporarily to the registry, overwriting any pre-defined values, and are restored when Patchwork exits. --register-microsoftupdate and --clear-wsus-server will make permanent changes however.
--register-microsoftupdate
Registers the Microsoft Update service with the local Windows Update Agent, enabling updates for all Microsoft products (Office, Visio, etc.) in addition to Windows updates. This change persists after Patchwork exits. Requires administrator privileges.
patchwork --register-microsoftupdate
This only needs to be run once per machine.
--clear-wsus-server
Removes the WSUS server configuration from the registry, causing the machine to fall back to Windows Update for subsequent update operations (by Patchwork or the OS). This is a permanent change. Requires administrator privileges.
patchwork --clear-wsus-server
--use-wsus
Forces the use of WSUS as the update source, even if another source was saved as a default. This has no effect if WSUS is not already configured in the registry or if a WSUS server is not manually specified. It is primarily useful to restore WSUS as the source after a --use-windowsupdate or --use-microsoftupdate default has been saved.
--use-windowsupdate
Bypasses WSUS and queries Windows Update directly. Applied for the duration of the current run only; the WSUS configuration in the registry is not modified.
patchwork --search --use-windowsupdate
--use-microsoftupdate
Queries the Microsoft Update service directly, bypassing WSUS. Includes Office and other Microsoft product updates. Applied for the current run only.
patchwork --search --use-microsoftupdate
--wsus-server SERVER
Temporarily points Patchwork at a specific WSUS server URL for the current run. The machine's existing WSUS registry configuration is restored on exit.
patchwork --install --wsus-server http://wsus.corp.example.com:8530
patchwork --install --wsus-server https://wsus.corp.example.com:8531
--use-mu-on-error
If the WSUS server is unreachable, fall back to Microsoft Update for the current run.
--use-wu-on-error
If the WSUS server is unreachable, fall back to Windows Update for the current run.
--targetgroup GROUP
Sets the WSUS client-side target group for the current run. The group name must match one configured on the WSUS server. The registry is restored to its original state when Patchwork exits.
patchwork --install --targetgroup "Production_Servers"
patchwork --install --wsus-server http://wsus.example.com:8530 --targetgroup "Pilot"
--notargetgroup
Removes the WSUS target group registry entries (TargetGroup and TargetGroupEnabled) before the operation, so the machine is treated as ungrouped for this run. The original values are restored on exit.
patchwork --search --notargetgroup
7.5 - Proxy Configuration
Proxy settings are applied for the duration of the current run and restored on exit. All proxy switches affect how the WUA communicates with the update source. Currently WinHTTP proxies are supported. Socks proxies are NOT supported at this time.
--disable-win-http-proxy
Disables the WinHTTP proxy for this run.
--disable-ie-proxy
Disables the Internet Explorer proxy for this run.
--auto-detect-proxy
Enables WPAD (Web Proxy Auto-Discovery) via IE's AutoDetect setting.
--proxy-address ADDRESS
Specifies a proxy server address manually. Accepts a hostname, FQDN, or IP address.
patchwork --search --proxy-address proxy.corp.example.com --proxy-port 8080
--proxy-port PORT
Specifies the proxy server port. Requires --proxy-address.
--proxy-username USER / --proxy-password PASSWORD
Accepted and validated (both require --proxy-address to also be given) but not currently applied - passing them has no effect on how Patchwork authenticates to a proxy server; this is expected to be implemented in a future release. Hidden from --help for this reason. Both values are redacted by --hide-sensitive the same as --smtp-password and --register.
--proxy-username/--proxy-password for an environment that requires authenticated proxy access today - Patchwork will not actually present these credentials to the proxy.7.6 - Reboot and Shutdown Options
At most, one of --reboot, --reboot-if-needed, --shutdown, or --shutdown-if-needed may be specified per invocation.
--reboot
Initiates a system reboot immediately after the operation completes, regardless of whether the installed updates require one. Returns exit code 5 on success, 6 on failure.
--reboot-if-needed
Initiates a reboot only if one or more installed updates report that a reboot is required. If no reboot is needed, Patchwork exits normally.
patchwork --install --classification CU --autoaccepteula --reboot-if-needed
--shutdown
Shuts the system down after the operation instead of rebooting.
--shutdown-if-needed
Shuts the system down if any installed update requires a reboot; exits normally otherwise.
--force-close
Forces applications to close before the reboot or shutdown proceeds. Use with care: applications will not have an opportunity to save data.
patchwork --install --reboot --force-close
--delay SECONDS
Pauses for the specified number of seconds before initiating a reboot or shutdown. Gives logged-in users time to save work when the reboot/shutdown is forced, rather than conditional.
patchwork --install --reboot-if-needed --delay 300 # 5-minute warning
--reboot-message MESSAGE
Displays the specified message in the Windows shutdown dialog before a reboot or shutdown.
patchwork --install --reboot-if-needed --delay 300 --reboot-message "Rebooting for monthly security updates in 5 minutes."
--rebootcycle COUNT
Enables automatic reboot cycling. After installing updates, if a reboot is required and the cycle count has not been exhausted, Patchwork registers itself to run again on the next startup and then reboots. The cycle counter is stored in the registry and decremented on each resume. When the counter reaches zero, no further automatic restarts are registered.
This switch is intended for scenarios where multiple rounds of dependent updates must be installed, each requiring a reboot before the next batch can be applied.
patchwork --install --classification CU --rebootcycle 3 --max-update-count 20
7.7 - Installation Options
--autoaccepteula
Automatically accepts End User License Agreements without prompting. Required for unattended operation.
patchwork --install --autoaccepteula
--force
Forces re-download and re-installation of updates, including those already installed or already cached.
--disableprompt, --nocachedel, --clear-localcache
All three are accepted and parse successfully but are not yet implemented - passing them has no effect. They are hidden from --help and are deliberately excluded from what --opt-save/--opt-add will persist (see Appendix E), so they can't silently be saved as a default that appears to do something but doesn't.
--disablepromptis intended to suppress any interactive prompt during installation.--nocachedelis intended to preserve the local WUA cache after a run instead of Patchwork's normal cleanup.--clear-localcacheis intended to explicitly purge the local WUA cache.
Do not depend on any of these three switches until a future release documents them as implemented.
--ignore-errors
Continues processing remaining updates if one download or install fails, rather than aborting the run, and always returns a success exit code regardless of any failures encountered. We recommend you use this option where you want patching to proceed unattended and never report a failure (for example, to avoid tripping orchestration that treats a non-zero exit as fatal).
patchwork --install --ignore-errors --logfile C:\Logs\updates.log
If you want the run to continue past failures but still report a non-zero exit code, use --continue-errors instead.
--continue-errors
Behaves like --ignore-errors - it continues past a download or install failure rather than aborting the run - but returns an exit code appropriate to the problem encountered instead of always reporting success. If a reboot is pending the code reflects that (11/ErrorWithReboot); otherwise it returns 1/ErrorNoReboot. Use this when you want patching to proceed as far as possible while still surfacing failures to your monitoring or orchestration.
--continue-errors and --ignore-errors are mutually exclusive.
patchwork --install --continue-errors --logfile C:\Logs\updates.log
--defender-fix
If a Microsoft Defender Antivirus signature update fails during an --install run, automatically attempts a recovery by removing the stale or corrupted definition files and triggering a fresh definition download and install. This can resolve situations where a Defender definition update is blocked by a previous failed or partial update, without requiring a manual intervention or a full system restart.
--defender-fix is a licensed feature and requires a valid registered license. On unlicensed installations the recovery step is skipped and a message is logged instead.patchwork --install --defender-fix
patchwork --install --classification CUD --defender-fix
--parallel-downloads N
Sets the number of concurrent downloads. Accepts a value between 1 and 10. Default is 3. Higher values can improve throughput on fast connections but increase load on the WSUS server, network or proxy servers.
--parallel-downloads is a licensed feature and requires a valid registered license. On unlicensed installations parallel downloads are fixed to 3 concurrent downloads.patchwork --download --parallel-downloads 5
patchwork --download --parallel-downloads 1 # serialise for bandwidth-limited links
7.8 - Logging and Reporting
--quiet
Reduces console output to essential results only. Progress details, per-update listings, and informational banners are suppressed. Error messages and final counts are still shown.
--silent
Suppresses all console output. Use for scheduled tasks where output is not captured. Pair with --logfile to preserve a record of what occurred.
patchwork --install --silent --logfile C:\Logs\nightly.log
--logfile FILE
Writes all output to the specified file in addition to (or instead of, with --silent) the console.
patchwork --install --logfile "C:\Logs\patch-$(date /T).log"
--logmode MODE
Controls log file behaviour when the file already exists. overwrite (default) truncates the file before writing. append adds to the existing content.
patchwork --install --logfile C:\Logs\updates.log --logmode append
--logencoding ENCODING
Sets the character encoding for the log file. Unicode (default) writes UTF-16LE with CRLF line endings, which is readable in Notepad and most Windows tools. ANSI writes plain text with the system code page which may be useful for reading/processing with legacy tools.
patchwork --install --logfile C:\Logs\updates.log --logencoding ANSI
--xmlout FILE
Writes a structured XML report to the specified path on completion. Can be combined with any operation. Compatible with --list-exit-codes and --healthcheck to produce machine-readable output from those commands.
patchwork --search --xmlout C:\Reports\scan.xml
--xmlout-with-bom
Adds a UTF-8 BOM to the XML output file. Required for correct rendering in some spreadsheet applications (Excel, for example, uses the BOM to detect UTF-8 encoding).
patchwork --search --xmlout C:\Reports\scan.xml --xmlout-with-bom
--jsonout FILE
Writes a structured JSON report to the specified path on completion.
patchwork --search --jsonout C:\Reports\scan.json
--info
Prints detailed information about each update - title, KB article, classification, severity, size, release date, and description - to the console. Without --info, only a summary is shown.
patchwork --search --info
--show-progress
Displays per-update download and installation progress on the console. Useful for interactive sessions. You may want to omit this switch for scheduled tasks.
--third-party-progress TAG
Tags progress output with the given identifier so an external tool driving Patchwork (a wrapper script, an orchestration agent) can distinguish Patchwork's own progress lines from other output it's watching for. Hidden from --help; intended for tooling integrations rather than everyday interactive use.
--color
Enables ANSI color output for errors and progress indicators. Requires a terminal that supports VT escape sequences (Windows Terminal, modern ConHost etc.).
--nocolor
Disables ANSI color output. --nocolor always overrides --color, regardless of the order the two appear in and regardless of where each came from: the same command line, saved default options (see --opt-save), or the --color contained in the --opt-verbose preset. It also suppresses color in the startup banner and in --help output.
Use it to get plain text out of an endpoint whose saved defaults turn color on, without changing those defaults:
patchwork.exe --search --nocolor
--no-color is accepted as an alias. When --color and --nocolor are saved together via --opt-save / --opt-add, only --nocolor is written to the registry, since that is the one that takes effect.
--extended-error
Changes exit code semantics to a bitmap combining multiple status flags. See Section 9 for the full flag table.
--simple-error
Collapses exit codes to 0 (success) or 1 (any error). Useful for integration with systems that expect only a pass/fail return.
--debug
Enables structured debug tracing. Writes a full JSON span log to %TEMP%\Patchwork-debug-<pid>.log and mirrors DEBUG-level events to stderr. Also activates per-event forwarding to syslog and email sinks when those are configured. This output is primarily for diagnostics and support bundle generation. Typically the only time you should require this switch is if the output is required by Emerita support.
--hide-sensitive
Redacts sensitive values in console output and log files. Specifically, the values passed to --smtp-user, --smtp-password, --proxy-username, --proxy-password, and --register are replaced with ********. Use when log files may be reviewed by third parties or forwarded to monitoring systems.
--list-exit-codes
Prints a table of all exit codes and their meanings, then exits. Combine with --xmlout or --jsonout to write the table as a report.
patchwork --list-exit-codes
patchwork --list-exit-codes --jsonout C:\Reports\codes.json
--healthcheck
Runs a series of environment checks and reports the result for each. Exits with code 0 if all checks pass, code 1 if any check fails. Checks include: administrator privilege status, WUA service availability, COM class registration, WSUS connectivity (if configured), disk space (warn at < 500 MB free, fail at < 100 MB free), pending reboot state, proxy configuration, and recent update timestamps.
Combine with --xmlout or --jsonout for a machine-readable report suitable for monitoring pipelines.
patchwork --healthcheck
patchwork --healthcheck --xmlout C:\Reports\health.xml
7.9 - Timeout and Runtime
--maxruntime SECONDS
Sets a hard upper limit on total execution time. If the limit is exceeded before the operation completes, Patchwork exits with code 12 (TimeoutReached).
patchwork --install --maxruntime 3600 # Allow up to 1 hour
--retrycount COUNT
Number of retry attempts for failed search, download, or install operations. Retries use an exponential backoff with jitter: initial delay 2 seconds, maximum delay 30 seconds.
patchwork --install --retrycount 5
--noretry
Disables automatic retry entirely. Patchwork will fail immediately on the first error.
7.10 - Custom Actions
Custom actions run synchronously, under the same account token as Patchwork itself. The working directory is inherited from the parent process.
Dispatch logic:
- If the command's first token ends in
.ps1, the script is run as:powershell.exe -ExecutionPolicy Bypass -NonInteractive -File <path> [args] - All other commands (executables, .cmd, .bat, and shell built-ins) are run as:
cmd.exe /C <command>
If a custom action exits with a non-zero code, Patchwork logs the failure but continues - it does not abort the operation. Check the log file to confirm custom actions completed successfully.
--custom-action-before COMMAND
Runs a command before the main operation begins. Use to stop services, snapshot VMs, or check preconditions.
patchwork --install --custom-action-before "net stop MyAppService"
patchwork --install --custom-action-before "C:\Scripts\pre-patch.ps1"
patchwork --install --custom-action-before "net stop Svc1 & net stop Svc2"
To chain multiple commands: use & within a quoted string, or wrap in a .cmd file.
--custom-action-after COMMAND
Runs a command after the main operation completes, regardless of outcome.
patchwork --install --custom-action-after "net start MyAppService"
patchwork --install --custom-action-after "C:\Scripts\post-patch.ps1 -SendReport"
7.11 - System Checks
--check-available-disk-space DRIVE[:SIZE]
Reports the free space on the specified drive. Accepts the drive letter with or without a colon or backslash (C, C:, C:\ are all equivalent; only the first character is used).
An optional minimum free-space requirement can be appended directly after the drive letter. The size format is the same as --max-total-size: a number followed by an optional suffix (K, KB, M, MB, G, GB, T, TB), or a plain number for bytes. If the available free space is less than the specified size, Patchwork logs an error and exits immediately, before carrying out any other operation.
When combined with a primary operation (--search, --download, --install, etc.) and no minimum size is specified, the space is reported first and then the operation continues. When used alone without a minimum size, Patchwork exits after reporting.
patchwork --check-available-disk-space C:
patchwork --check-available-disk-space C:10G
patchwork --install --check-available-disk-space C:500M --classification CU
--refresh-last-update-timestamps
Writes the current date and time to the Windows Update timestamp registry entries (LastSearchTime, LastDownloadTime, LastInstallTime, LastUninstallTime, LastCheckTime). This is occasionally needed to correct misleading "last checked" dates or to unify dates.
patchwork --refresh-last-update-timestamps
7.12 - Default Options Management
Default options are stored as a string in the registry at HKLM\Software\Emerita\Patchwork under the value DefaultOptions. On every run, Patchwork reads this string, prepends it to the actual command line, and parses the combined result. Explicitly supplied command-line arguments always override saved defaults. Certain options, such as reboot/shutdown related switches, default operations and registration/setup related switches will not be saved. If you do require a switch that Patchwork refuses to save, then you can edit the registry manually which may overcome the limitation you are encountering. We may not be able to support you in these instances though.
--opt-save
Replaces the saved defaults with the saveable options from the current command line. Anything saved previously is discarded - after an --opt-save, the stored defaults are exactly what you typed on that command line, nothing more. Use --opt-add when you want to keep the existing defaults and add to them.
Not all switches are saved - operation flags (--search, --install, etc.), reboot flags, and the management flags themselves are excluded. The intent is to save configuration options (source selection, logging, filtering preferences), not one-time actions.
Requires administrator privileges (writes to HKLM).
When combined with a primary operation, --opt-save saves first and then runs the operation.
patchwork --opt-save --use-windowsupdate --autoaccepteula --logfile C:\Logs\Patchwork.log
If the command line contains no saveable options at all (for example patchwork --search --opt-save), nothing is written and the existing defaults are left in place - a replace with nothing to put in its place is treated as a mistake rather than an instruction to wipe. Use --opt-clear to deliberately remove saved defaults.
See Appendix D and Appendix E for options that can and cannot be saved using the --opt-save command.
--opt-add
Adds the saveable options from the current command line to the defaults already saved, keeping both. Where the same option appears in the saved defaults and on the command line, the command-line value replaces it - the option is not stored twice.
This is what --opt-save did in releases before the two were separated. If you have scripts that relied on --opt-save accumulating settings across several invocations, change them to --opt-add.
Requires administrator privileges (writes to HKLM).
patchwork --opt-save --use-windowsupdate --autoaccepteula # defaults are now exactly these two
patchwork --opt-add --logfile C:\Logs\Patchwork.log # ...plus the logfile
patchwork --opt-add --logfile D:\Logs\Patchwork.log # logfile replaced, others kept
patchwork --opt-save --color # defaults are now exactly --color
--opt-save and --opt-add cannot be combined; Patchwork rejects the pair rather than picking one. Unlike --opt-save, --opt-add reads the stored defaults directly, so it adds to them correctly even when --opt-ignore is also present on the command line.
--opt-clear
Removes the saved defaults from the registry.
patchwork --opt-clear
--opt-show
Prints the currently saved default options string without running any operation.
patchwork --opt-show
--opt-ignore
Skips loading the saved defaults for this run. The registry value is not modified; it remains in place for subsequent runs.
patchwork --install --opt-ignore --use-windowsupdate
--opt-verbose
Applies a preset that enables the following useful options by default without requiring a lot of additional effort to determine and understand what might be appropriate:
--autoaccepteula --continue-errors --logfile %TEMP%\Patchwork.log --logmode append --show-progress --color --info --hide-sensitive
Any of these can be individually overridden on the same command line.
When used without a primary operation, --opt-verbose saves the preset as the default options (equivalent to running --opt-save with those flags). Like --opt-save, this replaces any previously saved defaults: afterwards the stored defaults are exactly the preset. Combine it with --opt-add to fold the preset into your existing defaults instead. When combined with a primary operation, the preset is applied for that run without being saved.
patchwork --opt-verbose --install --classification CU # Run with verbose preset
patchwork --opt-verbose # Save verbose preset as the defaults (replaces)
patchwork --opt-add --opt-verbose # Add the verbose preset to existing defaults
patchwork --opt-verbose --install --logfile D:\log.log # Verbose, but override logfile
7.13 - Scheduling
--update-schedule [CADENCE]
Creates, inspects, or removes a recurring Windows scheduled task named Patchwork Install that runs patchwork --install as SYSTEM. Creating and removing require administrator privileges (the task runs at the highest run level); show does not.
The value is a cadence or a subcommand, and defaults to daily when the switch is given on its own:
| Value | Meaning |
|---|---|
daily | Every day at --time (the default) |
weekly:<Mon..Sun> | Once a week on that day. Three-letter or full day names, case-insensitive (weekly:Sun, weekly:Sunday) |
once | A single run. If the requested time has already passed today, the task is dated tomorrow |
remove | Delete the task |
show | Report the task's schedule, status, last run and last result |
patchwork --update-schedule daily --time 03:00 --use-windowsupdate --autoaccepteula --reboot-if-needed
patchwork --update-schedule weekly:Sun --time 03:00 --wsus-server http://wsus:8530 --classification CU
patchwork --update-schedule once --time 22:00 --use-windowsupdate --reboot
patchwork --update-schedule daily --time 03:00 --time-variance 30 --use-windowsupdate
patchwork --update-schedule show
patchwork --update-schedule remove
Creating a schedule requires --time, and requires an update source - --wsus-server <URL>, --use-windowsupdate, or --use-microsoftupdate - either on the command line or in saved defaults. --time-variance is optional and spreads the fleet across a window either side of --time.
Two layers, two lifetimes. This is the part worth understanding before you use it:
- Saved defaults (
--opt-save/--opt-add) are not baked into the task. They are read from the registry and applied on every run, including scheduled ones. Change them later and the scheduled install changes with them, with no need to recreate the task. This is the live layer. - Everything else typed on the schedule command line - reboot switches, filters,
--autoaccepteula,--logfile, and so on - is written into the task's command and fixed until the task is recreated. This is the frozen layer.
Put bulky or sensitive configuration in the live layer. The task command is capped at 261 characters by Windows, and it is readable by any local user via schtasks /Query /V. Patchwork enforces both of those: an over-long command is refused with a message naming the remedy, and --smtp-password / --proxy-password on a schedule command line are refused outright.
A few switches are never forwarded into the task even though they are accepted alongside it, because they describe a one-off administrative act rather than what the task should do every night: --opt-save, --opt-add, --opt-clear, --opt-show, and --setup. So this is a normal, useful command - install, save the live layer, then register the task, all at once:
patchwork --setup --opt-save --use-windowsupdate --classification CU --autoaccepteula --logfile C:\Logs\patch.log --update-schedule weekly:Sun --time 03:00 --reboot-if-needed
--update-schedule cannot be combined with another operation (--search, --download, --uninstall, --remove, ...), including --install - the task always runs --install, and accepting it would leave it unclear whether an install had just happened.
Re-running --update-schedule replaces the existing task rather than failing, so it is safe to run from a deployment script repeatedly. --update-schedule remove is likewise idempotent, and patchwork --remove deletes the task as part of uninstalling.
--update-schedule show translates the scheduled run's exit code into words, so Result : 3 (no updates matching filter criteria) answers the usual question without a trip to Section 9.
--update-schedule schedules Windows updates. Each binary schedules its own core job; the cadence, --time and --time-variance grammars are identical between the two.Replaces --schedule HH:MM. The old hidden one-shot switch has been removed. Its behaviour is --update-schedule once --time HH:MM, which also fixes a defect it had: with no start date, a time that had already passed produced a task that reported success and never fired.
--time HH:MM
The local time a created schedule fires, in 24-hour form with both fields zero-padded (03:00, not 3:00). Required with --update-schedule when creating, and rejected with remove/show or on its own.
There is deliberately no default. pwtools.exe --update-schedule picks an overnight time for you when none is given, because a missed poll costs nothing; a Windows-update install may reboot the machine, so the maintenance window has to be a choice.
/ST is local time, so a DST change shifts the wall-clock run time along with the OS - which is normally what a maintenance window should do.
--time-variance MINUTES
The maximum number of minutes either side of --time that a created schedule may be shifted by. Defaults to 0 - the exact time you asked for. Accepted range is 0-720; ±720 already spans a full 24 hours.
Given a value, Patchwork draws one random offset from [-N, +N] when it creates the task and registers that time. --time 03:00 --time-variance 30 therefore produces a task somewhere in 02:30-03:30, inclusive at both ends:
patchwork --update-schedule daily --time 03:00 --time-variance 30 --use-windowsupdate
Patchwork Update Schedule
---------------------------------------------
Task : Patchwork Install
Cadence : daily
Requested : 03:00 local
Variance : ±30 min (02:30 - 03:30 local)
Time : 02:47 local (drawn from the window above)
The point is the estate, not the endpoint. schtasks.exe has no equivalent of Task Scheduler's Delay task for up to random delay, so without this every machine given the same command installs - and potentially reboots - in the same minute, which is how a WSUS server or a virtualisation host gets flattened at 03:00.
The offset is drawn once, at creation, and fixed in the task. It is not re-rolled on each run: the task's start time is a single /ST value, so a nightly wander would need a second task whose job was to rewrite the first. Two consequences worth knowing:
- Re-running
--update-scheduledraws a new offset. Creating the schedule twice is still safe - it replaces the task, as it always has - but the registered time will move within the window. If a deployment script re-runs it on every boot, the time will change on every boot. - The value is not saved with
--opt-save, and is not written into the task's command. What the task records is simply the drawn time.
Both times are always reported, and --update-schedule show will report the drawn one - it reads the task, which knows nothing about the window it came from.
A window that crosses midnight wraps: --time 00:10 --time-variance 30 spans 23:40-00:40. For daily that is just the previous night. For weekly:<day> the day is still the one the cadence names, so a wrapped draw runs late on that day rather than late the evening before - if that matters, name the time from the other side (weekly:Sat --time 23:40 rather than weekly:Sun --time 00:10).
Requires --update-schedule, and rejected with remove/show or on its own, exactly as --time is.
7.14 - Testing and Diagnostics
--donothing CODE
Returns the given exit code immediately without performing any operation. Hidden from --help; exists to let a deployment script or test harness exercise its own exit-code handling (see Section 9 and Section 11) against Patchwork's real command-line surface, without actually touching Windows Update or requiring elevation.
patchwork --donothing 10
echo %ERRORLEVEL%
8 - Output Formats and Reporting
Console Output
The console output level is controlled by the output mode switches:
| Mode | Switch | Description |
|---|---|---|
| Normal | (none) | Standard summaries and results; no per-update detail |
| Info | --info | Full additional per-update detail including descriptions |
| Quiet | --quiet | Counts and errors only; suppresses progress and banners |
| Silent | --silent | No console output at all |
| Color | --color | Adds ANSI color to output, including errors (red), success (green) and progress indicators (blue/orange). It makes output significantly easier to interpret for humans. It has no effect in silent mode. |
| No color | --nocolor | Removes ANSI color from output. Always overrides --color, whether that came from the same command line, from saved default options, or from the --opt-verbose preset. |
Log Files
Log files capture the same content as the console at the selected verbosity level. The encoding defaults to UTF-16LE (Unicode); use --logencoding ANSI for plain text. The mode defaults to overwrite; use --logmode append to accumulate across runs.
XML Output
The XML report generated by --xmlout contains a root <PatchworkReport> element with a <Summary> section and an <Updates> collection. Each <Update> element includes:
<Title>- update title<KBArticleID>- KB number<Classification>- update classification<Severity>- MSRC severity<Size>- download size in bytes<ReleaseDate>- YYYY-MM-DD<Description>- full update description<UpdateID>- WUA GUID
Add --xmlout-with-bom to prefix the file with a UTF-8 BOM for compatibility with Excel and similar tools.
JSON Output
The JSON report generated by --jsonout follows the same logical structure as the XML output, with a top-level summary object and an updates array.
Debug Trace
--debug produces a structured JSON span log at %TEMP%\Patchwork-debug-<pid>.log. The file contains timestamped event records covering every major operation - WUA calls, filter decisions, download progress, and error details. This file is intended for support and diagnostics; send it alongside the regular log file and any potential .dmp file when reporting an issue.
9 - Exit Codes
Standard Exit Codes
| Code | Name | Meaning |
|---|---|---|
| 0 | Success | Operation completed; no reboot required |
| 1 | ErrorNoReboot | One or more errors occurred; no reboot required |
| 2 | NoMoreUpdates | No further updates are available |
| 3 | NoUpdatesMatchingFilter | No updates matched the active filter criteria |
| 4 | InvalidCriteria | The WUA search criteria were rejected as invalid |
| 5 | RebootSuccess | Reboot or shutdown initiated successfully |
| 6 | RebootFailed | Reboot or shutdown could not be initiated |
| 7 | SyntaxError | A command-line argument was invalid or missing |
| 8 | InvalidVersion | The product is unlicensed or the license has expired |
| 10 | SuccessRebootRequired | Operation completed; at least one update requires a reboot |
| 11 | ErrorWithReboot | One or more errors occurred and a reboot is also required |
| 12 | TimeoutReached | The --maxruntime limit was exceeded |
| 77 | PrivilegeRequired | The operation needs administrator privileges and does not have them; nothing was changed |
Code 77 sits outside the 0-12 block deliberately. Those codes describe the outcome of an update run; 77 says the run never started, so nothing on the machine was touched. It is the same value pwtools.exe returns for PRIVILEGE_REQUIRED, so a script driving both binaries can test for it once.
It is returned both by the up-front privilege checks (--setup, --remove, --update-schedule, --register-microsoftupdate, --clear-wsus-server, --opt-save/--opt-add/--opt-clear) and by a registry write that Windows refuses mid-operation - for example applying --wsus-server or --targetgroup without elevation. A registry failure that is not access-denied remains a general error (exit 1) and reports the raw Windows status code.
Extended Exit Codes (--extended-error)
When --extended-error is active, the exit code is a bitmap combining the following flags:
| Bit | Hex mask | Meaning |
|---|---|---|
| 0 | 0x001 | A Windows Update error occurred |
| 1 | 0x002 | More updates match the filter than were processed |
| 2 | 0x004 | More updates are available overall (beyond the filter) |
| 3 | 0x008 | The --max-update-count limit was reached |
| 4 | 0x010 | A reboot is required |
| 5 | 0x020 | The timeout limit was reached |
| 6 | 0x040 | Invalid search criteria |
| 7 | 0x080 | Syntax error |
| 8 | 0x100 | Invalid license or version |
| 9 | 0x200 | Insufficient disk space |
For example, an exit code of 26 (0x1A = 0b00011010) indicates: more updates matching filter available (bit 1), max update count reached (bit 3), and reboot required (bit 4).
Parsing in PowerShell:
$code = $LASTEXITCODE
if ($code -band 0x10) { Write-Host "Reboot required" }
if ($code -band 0x08) { Write-Host "max-update-count was hit; more updates may remain" }
if ($code -band 0x01) { Write-Host "A Windows Update error occurred" }
Parsing in CMD:
patchwork --install --extended-error --max-update-count 5 --classification CU
set /a REBOOT_REQ=%ERRORLEVEL% ^& 16
if %REBOOT_REQ% GTR 0 echo Reboot required
Simple Error Mode (--simple-error)
All non-zero exit codes collapse to 1. Use when the calling script only needs to know success or failure.
Using Exit Codes in Scripts
A typical pattern in a batch file:
patchwork --install --classification CU --autoaccepteula --reboot-if-needed
if %ERRORLEVEL% EQU 0 echo All done, no reboot needed.
if %ERRORLEVEL% EQU 10 echo Install succeeded - rebooting now.
if %ERRORLEVEL% EQU 3 echo No matching updates found.
if %ERRORLEVEL% EQU 1 echo Install completed with errors.
if %ERRORLEVEL% EQU 12 echo Timed out before all updates were installed.
10 - Deployment Scenarios
Standalone Workstation Using Windows Update
The simplest case: no WSUS in play, direct Windows Update access.
patchwork --install --classification CU --severity CI ^
--autoaccepteula --reboot-if-needed --delay 60 ^
--logfile "C:\Logs\patch-%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%.log"
Run this from a scheduled task under SYSTEM, daily or weekly, during off-hours.
Domain-Joined Client Using WSUS
If the machine is already Group Policy-targeted at a WSUS server, Patchwork will use it automatically. To specify the target group explicitly:
patchwork --install --classification CU --autoaccepteula ^
--targetgroup "Production_Desktops" ^
--reboot-if-needed --logfile C:\Logs\update.log
If the WSUS server is temporarily unreachable, add --use-wu-on-error to fall back to Windows Update rather than failing the run outright.
WSUS Fallback on Server Outage
patchwork --install --classification CU --autoaccepteula --use-wu-on-error ^
--logfile C:\Logs\update.log --xmlout C:\Reports\update.xml
Server Core and Headless Deployments
Headless systems have no interactive session. Run Patchwork silently, log to file, and parse the exit code in the calling script:
patchwork --install --classification CU --autoaccepteula ^
--silent --logfile C:\Logs\update.log ^
--xmlout C:\Reports\update.xml ^
--reboot-if-needed
if %ERRORLEVEL% EQU 10 shutdown /r /t 300
Running Under SYSTEM via Task Scheduler
The simplest route is to let Patchwork create the task (--update-schedule), which registers it as SYSTEM at the highest run level and validates the command it will run:
patchwork --update-schedule weekly:Sun --time 03:00 --classification CU --autoaccepteula --silent --logfile C:\Logs\patch.log --reboot-if-needed
To build the task by hand instead:
- Action:
Patchwork.exe --install --classification CU --autoaccepteula --silent --logfile C:\Logs\patch.log --reboot-if-needed - Run as: SYSTEM
- Run with highest privileges: Yes
- Trigger: Weekly, outside business hours
No interactive login is needed. --silent suppresses any attempted console output.
SCCM/MECM Package or Script Deployment
Deploy as a package or script step. The exit code maps to MECM's success/failure reporting:
patchwork --install --classification CU --autoaccepteula --ignore-errors ^
--quiet --logfile "%TEMP%\Patchwork-mecm.log"
exit /b %ERRORLEVEL%
MECM treats exit code 0 as success and any other code as failure. If updates require a reboot (exit code 10), configure the deployment to handle a soft reboot.
Intune Win32 App Deployment
Package Patchwork as a Win32 app. Set the install command and define custom return codes in Intune:
- Install command:
Patchwork.exe --install --classification CU --autoaccepteula --ignore-errors --quiet - Return codes:
- 0 - Success
- 10 - Success with reboot required (map to Intune's "soft reboot" code 3010)
- 3 - No updates found (map to Success)
- 1 - Failure
Staged Pilot Rollout
Download updates on a representative pilot machine, validate, then deploy to production:
rem Phase 1: Download on pilot machine
patchwork --download --classification CU --logfile C:\Logs\pilot-download.log
xcopy C:\Windows\SoftwareDistribution\Download \\fileserver\Updates\Monthly /E /I
rem Phase 2: Install on pilot
patchwork --install --classification CU --autoaccepteula ^
--logfile C:\Logs\pilot-install.log --xmlout C:\Reports\pilot.xml ^
--reboot-if-needed
rem Phase 3: After validation, deploy broadly
Citrix and RDS Gold Image Patching
Patch the gold image before sealing. On a snapshot-based workflow:
- Boot the gold image.
- Run Patchwork against Windows Update or an approved WSUS group.
- Verify the result via
--xmlout. - Reboot if required.
- Repeat until
--searchreturns code 3 (no updates remaining). - Seal and publish the image.
:loop
patchwork --install --classification CU --autoaccepteula --quiet ^
--xmlout C:\Temp\patch-result.xml
if %ERRORLEVEL% EQU 10 (
shutdown /r /t 0
)
if %ERRORLEVEL% EQU 0 goto done
if %ERRORLEVEL% EQU 3 goto done
echo Errors during patching - review C:\Temp\patch-result.xml
:done
11 - Automation and Scripting Patterns
Parsing JSON Output in PowerShell
patchwork --search --classification CU --jsonout "$env:TEMP\scan.json" | Out-Null
$report = Get-Content "$env:TEMP\scan.json" | ConvertFrom-Json
foreach ($update in $report.updates) {
Write-Host "$($update.title) - $($update.kbArticleId) - $($update.size) bytes"
}
Write-Host "Total: $($report.summary.totalUpdates) updates"
Handling Exit Codes in PowerShell
patchwork --install --classification CU --autoaccepteula --reboot-if-needed
switch ($LASTEXITCODE) {
0 { Write-Host "All updates installed. No reboot needed." }
10 { Write-Host "Updates installed. Rebooting in 5 minutes."; Start-Sleep 300; Restart-Computer -Force }
3 { Write-Host "No updates matching filter." }
1 { Write-Error "Install completed with one or more errors." }
12 { Write-Error "Timed out. Some updates may not have been installed." }
default { Write-Error "Unexpected exit code: $LASTEXITCODE" }
}
Saving Site-Wide Defaults
To configure a standard set of options that apply to every Patchwork invocation on a machine without repeating them on every command line, save them as defaults. Run once from an elevated prompt:
patchwork --opt-save --use-windowsupdate --autoaccepteula ^
--logfile C:\Logs\Patchwork.log --logmode append ^
--xmlout C:\Reports\Patchwork.xml --hide-sensitive
From that point on, a simple patchwork --install --classification CU will automatically include all those options. Override any saved default by specifying it explicitly on the command line.
To check what is currently saved:
patchwork --opt-show
To clear everything:
patchwork --opt-clear
Pre/Post Custom Actions for Service Control
Stop dependent services before patching, restart them after:
patchwork --install --classification CU ^
--custom-action-before "net stop MyAppService & net stop MyDBService" ^
--custom-action-after "net start MyDBService & net start MyAppService" ^
--autoaccepteula --logfile C:\Logs\patch.log
For more complex pre- and post-logic, wrap in scripts:
patchwork --install --classification CU ^
--custom-action-before "C:\Scripts\pre-patch.ps1" ^
--custom-action-after "C:\Scripts\post-patch.ps1" ^
--autoaccepteula
pre-patch.ps1, for example, could be used to snapshot a VM or drain a load balancer. post-patch.ps1 might run smoke tests or send a Teams notification.
Idempotent Reboot Handling
You can easily check for or deploy patches via a scheduler that runs on every startup (e.g., a Group Policy startup script), or a simple Task Scheduler run on login:
patchwork --search --classification CU --severity CI
if %ERRORLEVEL% EQU 3 (
echo No updates pending. Done.
exit /b 0
)
patchwork --install --classification CU --severity CI ^
--autoaccepteula --reboot-if-needed ^
--logfile C:\Logs\startup-patch.log
Banding Pilot Rings with Count and Date Limits
Install only the oldest N updates first, moving to newer ones in subsequent passes:
rem Ring 1: install up to 5 updates released more than 30 days ago
patchwork --install --classification CU ^
--releasedate le:2025-03-01 --max-update-count 5 ^
--autoaccepteula --logfile C:\Logs\ring1.log
12 - Filtering Examples
Security Updates Only, Last 30 Days
patchwork --search --classification U --releasedate days:30 --info
Critical and Security Updates, Critical and Important Severity
patchwork --install --classification CU --severity CI --autoaccepteula
Everything Except a Specific KB
patchwork --install --kb -KB5034441
All Software Updates Except Definitions
patchwork --install --classification CUISRF --autoaccepteula
Cumulative Updates by Regex
patchwork --search --match-filter "Cumulative Update for Windows" --info
Driver Updates from a Specific Vendor
patchwork --search --driveronly --product "Intel" --info
patchwork --install --driveronly --product "NVIDIA" --autoaccepteula
Exclude Drivers from a Broad Install
patchwork --install --classification CUISRF --exclude-product "Realtek,Broadcom"
Load a Curated KB Allow-list from a File
Create approved-kbs.txt:
# Monthly approved patches - approved 2025-05-01
KB5078740
KB5034441
KB5036893
patchwork --install --matchfile C:\Config\approved-kbs.txt --autoaccepteula
Combining Classification, Severity, Regex, and Date
patchwork --install ^
--classification CU ^
--severity CI ^
--match-filter "Windows (10|11|Server 2022)" ^
--releasedate ge:2025-01-01 ^
--nomatch-filter "Preview" ^
--max-update-count 20 ^
--autoaccepteula
How Filters Interact
Filters are applied in this order:
- WUA query (classification scope from update type switches, default IsInstalled=0)
- Classification filter (
--classification) - Severity filter (
--severity) - KB include/exclude list (
--kb) - Update ID include/exclude list (
--match-id) - Regex include (
--match-filteror--matchfile) - Regex exclude (
--nomatch-filteror--nomatchfile) - Product include (
--product) - Product exclude (
--exclude-product) - Only-downloaded filter (
--only-downloaded) - Preview filter (excluded unless
--preview) - Release date filter (
--releasedate) - Size cap (
--max-total-size) - applied cumulatively, in update order - Count cap (
--max-update-count) - truncates the final list
An update must pass all active filters. If no filters are specified for a given dimension, that dimension is not filtered (all values pass).
13 - Notifications
Email Notifications
Patchwork can send an email report after any primary operation. The minimal required configuration is --smtp-server, --email-from, at least one --email-to, and --send-email-on-completion which is required to ensure the email send will be triggered.
Port and Encryption Matrix
| Port | Encryption switch value | Protocol |
|---|---|---|
| 25 | none | Plain SMTP |
| 587 | starttls | SMTP with STARTTLS |
| 465 | ssltls | SMTP over SSL/TLS |
Authenticated SMTP
patchwork --install --classification CU ^
--smtp-server smtp.corp.example.com --smtp-port 587 ^
--smtp-encryption starttls ^
--smtp-user patchwork@corp.example.com ^
--smtp-password "secretpassword" ^
--email-from patchwork@corp.example.com ^
--email-to sysadmin@corp.example.com ^
--email-subject "Patch Run Complete - %COMPUTERNAME%" ^
--send-email-on-completion ^
--hide-sensitive
--hide-sensitive prevents the SMTP password from appearing in the log file and being output to the display.
Multiple Recipients
Specify --email-to more than once:
patchwork --install ... ^
--email-to alice@example.com ^
--email-to bob@example.com ^
--send-email-on-completion
Email Subject
If --email-subject is not specified, Patchwork uses Patchwork <operation> Report - <status> (e.g. Patchwork install Report - Success).
Saving Email Configuration as Defaults
patchwork --opt-save ^
--smtp-server smtp.corp.example.com ^
--smtp-port 587 --smtp-encryption starttls ^
--smtp-user svc-patchwork@corp.example.com ^
--smtp-password "password" ^
--email-from svc-patchwork@corp.example.com ^
--email-to ops-team@corp.example.com ^
--send-email-on-completion --hide-sensitive
Once saved, every subsequent patchwork --install run will send a notification without extra arguments.
Syslog Notifications
Patchwork sends a single RFC-5424 syslog message after each operation. The default transport is UDP.
Basic Syslog Setup
patchwork --install --classification CU ^
--syslog-server siem.corp.example.com ^
--syslog-port 514 ^
--syslog-protocol udp ^
--syslog-facility local0 ^
--syslog-tag Patchwork ^
--send-syslog-on-completion
TCP vs UDP
UDP is the default and is appropriate for most internal networks. Use --syslog-protocol tcp if your SIEM requires reliable delivery or if the syslog server is across a WAN link.
patchwork --install ... --syslog-protocol tcp --syslog-server logs.example.com
Syslog Facility
Patchwork supports local0 through local7. Choose whichever facility your syslog server routes to the correct destination. The default is local0.
Severity Mapping
| Operation outcome | Syslog severity sent |
|---|---|
| Success | Notice |
| Failed | Warning |
| Other | Info |
Saving Syslog Configuration as Defaults
patchwork --opt-save ^
--syslog-server siem.corp.example.com ^
--syslog-port 514 --syslog-protocol udp ^
--syslog-facility local1 --syslog-tag Patchwork ^
--send-syslog-on-completion
14 - Security Considerations
Privilege Model
Patchwork follows the principle of least privilege where possible. --search, --history, --installed, and --healthcheck do not require elevation. All operations that write to the registry or modify the system (download, install, uninstall, setup, remove, target group changes, WSUS configuration) require administrator privileges. Patchwork checks for elevation and exits with an informative error if admin is required but not available.
Credential Handling
- SMTP passwords passed via
--smtp-passwordappear in the command line and may be captured in process listings or audit logs. Use--hide-sensitiveto redact them in Patchwork's own log output. Consider storing the entire SMTP configuration as saved defaults via--opt-saveso the password does not appear in task scheduler or wrapper script command lines. The saved value is stored in the registry underHKLM\Software\Emerita\Patchworkso do not assume security. Ensure that the SMTP account has minimal permissions to allow the sending of reports you require, but no more.--update-scheduleenforces this rather than relying on it being read:--smtp-passwordand--proxy-passwordare refused on a schedule command line, becauseschtasks /Query /Vshows a task's command to any local user. - License keys passed via
--registerare similarly sensitive.--hide-sensitiveredacts the--registerargument in logs. - Proxy credentials:
--proxy-usernameand--proxy-passwordare accepted and validated (both require--proxy-addressto also be given) and are redacted by--hide-sensitivethe same as the other sensitive switches above. They are not currently applied to the WUA proxy configuration - passing them has no effect on how Patchwork authenticates to a proxy. Do not rely on them for an environment that requires authenticated proxy access; this is expected to be implemented in a future release.
What --hide-sensitive Covers
When --hide-sensitive is active, the values for the following switches are replaced with ******** in all console output and log files:
--smtp-user--smtp-password--proxy-username--proxy-password--register
Code Signing
The Patchwork executable is digitally signed with an Authenticode certificate issued to Chad Matthieson. Please verify the signature is present and valid before deploying, especially in sensitive environments. If the signature is not present or invalid, please contact us so we can investigate further. Patchwork contains code to ensure that the digital signature is present and correct prior to operation execution, so in the event of Patchwork not launching correctly, please redownload and replace the problematic executable.
Get-AuthenticodeSignature "C:\Program Files\Emerita\Patchwork\Patchwork.exe"
Registry Keys
Patchwork writes to and reads from the following registry locations:
| Location | Purpose |
|---|---|
HKLM\SOFTWARE\Emerita\Patchwork | Installation record (Installed, Version), default options (DefaultOptions), registration information |
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment | System PATH (written during --setup) |
| WSUS client keys (temporary) | Applied during operations with --wsus-server or --targetgroup; restored on exit |
| WUA proxy configuration (temporary) | Applied during proxy-switching operations; restored on exit |
Hardening on Shared Hosts
HKLM\Software\Emerita\Patchwork. A low-privilege user who can write to DefaultOptions could inject flags (such as --custom-action-before) that execute code with elevated privileges on the next scheduled run.15 - Performance and Tuning
Parallel Downloads
The --parallel-downloads switch controls how many updates are downloaded concurrently. The default of 3 is a reasonable middle ground for most environments. On fast LAN connections with a capable WSUS server, values up to 6 or 8 may improve throughput. On metered or low-bandwidth links, set it to 1 to serialize downloads and avoid saturating the connection. Every environment is different, so please test and tune to your environment to ensure that your network, firewalls, proxy servers and load balancers are not overloaded.
patchwork --download --parallel-downloads 1 --classification CU # Low bandwidth
patchwork --download --parallel-downloads 6 --classification CU # Fast LAN
Bounding Run Time
In scheduled task environments where the task window is fixed, set --maxruntime to prevent Patchwork from running past the end of the maintenance window:
patchwork --install --classification CU --maxruntime 3600 --autoaccepteula
Any updates not reached within the time limit are left for the next run.
Reducing Scope to Improve Speed
Broad filter strings produce larger update sets, which take longer to evaluate and install. Tighten the filters for routine runs, and reserve --alltypes for periodic comprehensive scans:
rem Routine: Critical and Security only
patchwork --install --classification CU --severity CI
rem Monthly audit: everything
patchwork --search --alltypes --classification CUDISRFEVG --xmlout C:\Reports\audit.xml
WSUS Load
High --parallel-downloads values combined with a large --max-update-count can generate significant load on a WSUS server and/or network/firewall/proxy infrastructure, especially when run on a large number of devices in parallel. If you are deploying to many machines simultaneously, consider staggering the start times or reducing parallelism. Patchwork's exponential-backoff retry logic (--retrycount) will handle transient WSUS server busy conditions gracefully.
16 - Troubleshooting
--healthcheck First
Before investigating a failed update run, run --healthcheck. It will identify the most common problems - missing WUA service, insufficient disk space, WSUS unreachable, pending reboot blocking installation - in a single pass.
patchwork --healthcheck
patchwork --healthcheck --xmlout C:\Reports\health.xml
No Updates Found (exit code 3)
The most common causes:
- All matching updates are already installed. Run with
--historyto confirm. - Filter too narrow. Try broadening
--classificationor removing--severity. - Wrong update source. If pointing at WSUS, the WSUS server may not have approved updates for this machine. Try
--use-windowsupdateto compare. - Target group mismatch. If WSUS is configured with client-side targeting, the machine may be in a group with no approved updates.
WUA COM Errors (0x800401F0)
This error means the Windows Update Agent COM class is not registered. The WUA service may be corrupted or disabled. Fix:
net stop wuauserv
regsvr32 /s %windir%\system32\wuapi.dll
regsvr32 /s %windir%\system32\wuaueng.dll
net start wuauserv
WSUS Connectivity Issues
Verify the WSUS server URL and port. Check that the machine can reach the server:
Test-NetConnection -ComputerName wsus.corp.example.com -Port 8530
Use --use-windowsupdate as a diagnostic bypass. If updates succeed via Windows Update but fail via WSUS, the issue is WSUS-side (approval, targeting, or connectivity).
Proxy Issues
If updates fail in environments with a proxy:
- Try
--disable-win-http-proxyor--disable-ie-proxyto check whether the proxy is the cause. - Try
--auto-detect-proxyto see if WPAD resolves correctly. - Use
--debugto capture proxy negotiation detail in the trace log.
Operation Timeout (exit code 12)
Increase --maxruntime or reduce the scope of the run (fewer updates per pass, lower --parallel-downloads). On slow or distant WSUS servers, search and download operations take longer; leave extra margin.
Reading the Debug Trace
Enable --debug, if requested, to get a full JSON span log at %TEMP%\Patchwork-debug-<pid>.log. This file records:
- The parsed command line after default options are applied
- Every WUA COM call and its HRESULT
- Filter decisions (which updates passed or failed each filter)
- Download progress per update
- Install progress per update
- Error stack traces with context
Common WUA HRESULT Codes
| HRESULT | Meaning |
|---|---|
0x80240001 | WU_E_NO_SERVICE - WUA not found or disabled |
0x80240003 | WU_E_UNKNOWN_ID - Update ID not recognised |
0x8024000B | WU_E_CALL_CANCELLED - Operation was cancelled |
0x80070005 | Access denied - administrator privileges required |
0x800401F0 | CLASS_E_CLASSNOTAVAILABLE - WUA COM class not registered |
Collecting a Support Bundle
To assist with a support request, collect the following:
- The regular log file (
--logfileoutput). - The debug trace (
--debugoutput from%TEMP%\Patchwork-debug-<pid>.log). - The XML or JSON report from the failing run.
- The output of
patchwork --healthcheck --xmlout C:\Reports\health.xml. - The output of
patchwork --opt-show(to confirm the active defaults). - The .dmp if automatically generated.
If requested, please send any resulting output to support@emerita.dev.
17 - pwtools.exe
New in v3.0.0
17.1 - Overview
pwtools.exe is a standalone companion utility to Patchwork.exe, installed alongside it (see Section 3). It handles two things Patchwork.exe itself does not: product registration when Patchwork's own trial state blocks registration, and the Patchwork product update mechanism that keeps Patchwork itself current - as distinct from Patchwork.exe --update-schedule, which keeps Windows current (see the note at the end of Section 7.13 and 17.4 below).
Running pwtools.exe with no arguments (or with --help/-h) prints a short Obsidium license/trial status banner followed by a full usage summary, then exits 0. Every registration and update command prints that same banner first, before doing anything else.
-r, -c, -s, and -h are short aliases for --register, --clear, --show, and --help respectively. None of the update-management switches below have short aliases.
17.2 - Registration Commands
--register ["Username|Serial"]
Without an argument, prompts interactively for a Username and Serial Number. With "Username|Serial" (pipe-separated, quoted if it contains spaces), registers unattended:
pwtools.exe --register
pwtools.exe --register "FirstName LastName/Companyname|XXXXX-XXXXX-XXXXX-XXXXX"
This remains available even when Patchwork's own trial has expired - an expired trial also blocks registering via Patchwork.exe --register directly, so pwtools.exe --register is the way back in.
Passing both halves empty (--register "|") clears the stored license instead of registering - the same effect as --clear below.
--clear
Removes any existing registration information from the device, reverting to the unlicensed/trial state.
pwtools.exe --clear
--show
Displays the currently stored registration information (or trial status) and exits - this is simply the banner every pwtools.exe invocation prints, with no further action.
pwtools.exe --show
--version
Prints only pwtools.exe <version> and exits immediately - no banner, no license lookup. Useful for confirming which build is on disk after an update, or as a scripted smoke test.
pwtools.exe --version
--help
Prints the full usage summary (every switch in this section) and exits 0. Also shown when pwtools.exe is run with no arguments at all.
17.3 - Update Management
pwtools.exe's update commands keep Patchwork itself (both Patchwork.exe and pwtools.exe) current from Emerita's release feed or a configured mirror - distinct from Patchwork.exe, which updates Windows.
--update [--source <s>] [--debug]
End to end: fetches the current release manifest, verifies its signature, and - if a newer version is available and not held back - downloads, verifies, and applies it. The manifest fetch is conditional (an HTTP ETag is cached from the previous check), so a poll that finds nothing new is cheap - a 304 response short-circuits the whole run. If the manifest carries a maintenance-serial update (used to renew support entitlement without a full re-registration - see --set-new-serial below), that is reconciled into the local license before the version comparison. The installed and available versions are then compared; if the release is newer, a maintenance-expiry gate checks whether its build date falls within this endpoint's current support window - a release built after support has lapsed is deliberately not applied (exit MAINT_EXPIRED, see 17.7), and this repeats on every subsequent poll until support is renewed; it is a steady state, not a fault. If the release passes both checks, every payload file is staged into a temporary directory and verified again (SHA-256, and Authenticode where the manifest marks a file as signed), then swapped into place under a global lock. A post-swap health check runs Patchwork.exe --version and pwtools.exe --version against the newly-written files; a failure there triggers an automatic rollback to the previous copy.
pwtools.exe --update
pwtools.exe --update --source https://updates.example.com/Patchwork
--source overrides the configured update source for this run only (see 17.5), without changing what is saved in the registry.
--debug is narrowly scoped to the maintenance-serial reconciliation step, not the whole update run - with it, pwtools.exe prints exactly what it passes to (and gets back from) the Obsidium licensing calls involved, including the full username/serial pair unmasked. It exists for troubleshooting a specific endpoint's own licensing state, not for routine logging - do not forward --update --debug output off-box without reviewing it first.
pwtools.exe --update --debug
Requires Administrator in practice - it writes into the install directory and to HKLM - but this is not pre-checked the way --update-schedule is. Run unelevated, --update typically fails partway through the file swap with INTERNAL_ERROR (70) rather than exiting immediately with a clean permission error.
--check [--source <s>]
A dry run of --update: fetches the manifest unconditionally (no ETag short-circuit, so it always reflects the true current state) and reports what would happen, but makes no changes: nothing is staged or swapped, a pending maintenance-serial update is only reported (not applied), and nothing is written to the registry.
pwtools.exe --check
pwtools.exe --check --source \\fileserver\Patchwork-updates
If an update is available, --check lists every file the manifest describes (not just changed ones) that a subsequent --update would fetch. Because a pending maintenance-serial update is only reported here, not reconciled, --check evaluates the expiry gate against the endpoint's current, unrenewed state - it can therefore report an update as held back in a case where --update (which reconciles the serial first) would actually let it through. Treat a --check result as informative, not a guarantee of what --update will do next.
17.4 - Update Scheduling
--update-schedule [CADENCE]
Creates a Windows scheduled task named Patchwork Product Update that runs pwtools.exe --update as SYSTEM at the highest run level. This is deliberately a different task name from Patchwork.exe's own Patchwork Install task (Section 7.13), so removing or replacing one can never accidentally touch the other.
The cadence grammar is identical to Patchwork.exe --update-schedule's: daily, weekly:<Mon..Sun> (three-letter or full day names, case-insensitive), or once.
pwtools.exe --update-schedule
pwtools.exe --update-schedule weekly:Sun --time 03:00
pwtools.exe --update-schedule daily --time 03:00 --time-variance 60
Unlike Patchwork.exe --update-schedule, --time is optional here. Left out, pwtools.exe derives an overnight time itself - deterministically, not randomly: it hashes this machine's computer name together with its own install path and uses that to pick an hour between 02:00 and 04:59 and a minute within the hour. The same machine always computes the same default on every re-run (so re-running --update-schedule to change something else doesn't silently move an otherwise-untouched schedule), while different machines land at different times, spreading fleet-wide load automatically. This is separate from --time-variance, which - exactly as in Patchwork.exe (see Section 7.13) - draws one random offset within ±MINUTES of the given or derived time at creation and bakes that draw into the task; it is not re-rolled on each run, and re-running --update-schedule draws a new one.
--set-source <target> optionally configures the update source in the same command used to create the schedule - equivalent to also running --set-source separately.
Requires Administrator to create - checked up front, and refused cleanly with PRIVILEGE_REQUIRED (77) and nothing changed if not elevated.
--update-schedule show | remove
show reports the task's schedule, status, next/last run, and last result, and does not require Administrator. remove deletes the task and requires Administrator, checked up front the same as creation.
pwtools.exe --update-schedule show
pwtools.exe --update-schedule remove
Neither form takes --time, --time-variance, or --set-source - passing any of those alongside show or remove is a usage error, exactly as with Patchwork.exe --update-schedule.
Re-running --update-schedule to create replaces the existing task rather than failing, so it is safe to re-run from a deployment script.
17.5 - Update Source Configuration
By default (no source configured) pwtools.exe fetches updates directly from Emerita's own release feed. These three switches point it at an internal mirror instead - see 17.6 for how to build one with --stage.
--set-source <HTTPS-URL | \\share\path | dir>
Configures this endpoint's update source, stored under HKLM\SOFTWARE\Emerita\Patchwork (value UpdateSource). Accepts an https:// (or http://) URL; anything else is treated as a filesystem path - a UNC share and a local directory are handled identically.
pwtools.exe --set-source https://updates.example.com/Patchwork
pwtools.exe --set-source \\fileserver\Patchwork-updates
pwtools.exe --set-source D:\LocalMirror\Patchwork
Requires Administrator (writes to HKLM); not pre-checked, so an unelevated attempt fails with INTERNAL_ERROR (70) rather than a clean permission error.
--clear-source
Removes the configured source, reverting to direct mode (updates come from Emerita). Takes no argument - passing one alongside --clear-source is a usage error, to guard against typing it when --set-source was meant. Requires Administrator, with the same unelevated-failure behaviour as --set-source.
pwtools.exe --clear-source
--show-source
Reports the configured source (or that this endpoint is in direct mode), the last update result, the installed version and where that was determined from, and the on-disk version of each binary. Read-only; does not require Administrator.
pwtools.exe --show-source
Configured source : https://updates.example.com/Patchwork
Last update : UPDATED (0)
Installed version : 3.0.0 (from registry)
Patchwork.exe : 3.0.0
pwtools.exe : 3.0.0
17.6 - Offline and Tier 2 Distribution
For environments that can't or won't let every endpoint reach Emerita's release feed directly - air-gapped networks, strict egress policy, a single compliance-approved ingress point - pwtools.exe supports mirroring releases internally and applying them from that mirror.
--stage --source <s> --dest <dir>
Mirrors a release into <dir>: fetches and verifies the source manifest's signature, fetches and verifies every payload file it lists, then writes manifest.json itself last, using the exact bytes as fetched - the signature is relayed unmodified, so endpoints later pointed at this mirror verify against the same signature as if talking to Emerita directly. <dir> is created if it doesn't already exist. Every file is re-fetched on each run (there is no hash-skip shortcut here, unlike --update's staging step), so a large mirror will take roughly as long to refresh as it did to build.
pwtools.exe --stage --source https://www.emerita.dev/downloads/Patchwork/ --dest \\fileserver\Patchwork-updates
Point the fleet at the resulting mirror with --set-source (or --update-schedule ... --set-source), and re-run --stage periodically, or whenever Emerita publishes a new release, to keep it current. Unlike --set-source/--clear-source, --stage only needs write access to <dir> - it does not require Administrator.
--set-new-serial --manifest <file> [--serial "Username|Serial"]
Stamps a maintenance serial onto a local copy of manifest.json - the mechanism for renewing a fleet's support entitlement through an internal mirror, without regenerating Emerita's own signature. The maintenance_serial field is deliberately excluded from what the signature covers, so adding or changing it on a mirrored manifest doesn't invalidate the signature --stage relayed. Prompts interactively for the Username and Serial Number if --serial is omitted.
pwtools.exe --set-new-serial --manifest \\fileserver\Patchwork-updates\manifest.json --serial "FirstName LastName/Companyname|XXXXX-XXXXX-XXXXX-XXXXX"
Each endpoint picks up the new serial and reconciles it into its own local license the next time it runs --update against that manifest (see the maintenance-serial step under --update above) - this is what lets an endpoint sitting behind the MAINT_EXPIRED gate get unblocked by a mirror refresh alone, without re-running --register.
Only run this against a local mirror copy of manifest.json (the output of --stage) - never against Emerita's own origin manifest.
--import-bundle <dir>
Applies an update from an offline bundle - today, a directory laid out exactly like a --stage mirror (manifest.json plus the payload files it names) that has been copied to the target machine by some out-of-band means (removable media, a one-way transfer). Runs through the same verification, staging, and health-check pipeline as --update - including the same Administrator requirement and the same INTERNAL_ERROR (70) failure mode if unelevated - just reading from <dir> as the source instead of a URL or share.
pwtools.exe --import-bundle D:\Transfer\Patchwork-update
--export-bundle, which would produce that container format, exists on the command line but is not yet implemented - running it only prints an error and exits INTERNAL_ERROR (70), with nothing written to <path>. There is currently no way to build a bundle other than --stage's directory output.17.7 - Exit Codes
pwtools.exe uses three separate, independently-numbered exit code families depending on which command ran, and - importantly - these are not the same numbers as Patchwork.exe's own exit codes (Section 9), even though several values overlap numerically with different meanings. Don't interpret a pwtools.exe exit code using Section 9's table, or vice versa. There is a fourth family too, unrelated to either binary's own codes: Section 18.15 covers the reserved 100-109 codes Patchwork GUI's underlying PWExec/Patchwork-svc engine uses for deployment-level failures.
Registration commands (--register, --clear, --show):
| Code | Meaning |
|---|---|
| 0 | Success - registered, cleared, or shown; or --help completed |
| 1 | Invalid input - empty or malformed username/serial |
| 2 | Registration rejected - well-formed but not a valid license |
| 3 | Could not read input in interactive mode |
Update-management commands (--update, --check, --update-schedule, --set-source/--clear-source/--show-source, --stage, --set-new-serial, --import-bundle, --export-bundle):
| Code | Token | Meaning |
|---|---|---|
| 0 | UPDATED | Update downloaded, verified, and applied successfully |
| 10 | NO_UPDATE | No newer version available; nothing to do |
| 11 | UPDATE_AVAILABLE | --check only - a newer version exists but was not applied |
| 12 | MAINT_EXPIRED | A newer release exists but postdates this endpoint's support window; deliberately not applied. Not itself a failure - expected to repeat on every poll until support is renewed |
| 20 | ROLLED_BACK | Update applied, failed its post-apply health check, and was cleanly rolled back - install directory is exactly as it was |
| 21 | ROLLBACK_FAILED | Health check failed and rollback could not fully restore state synchronously - needs attention |
| 30 | VERIFY_FAIL | A payload file failed hash or Authenticode verification |
| 31 | SIG_FAIL | The manifest's signature was missing or invalid |
| 40 | SOURCE_UNREACHABLE | The configured (or given) source could not be reached or read |
| 50 | LOCK_BUSY | Another pwtools.exe update is already in progress |
| 64 | USAGE_ERROR | The command line was malformed |
| 70 | INTERNAL_ERROR | An unexpected internal error occurred - this is also what an unelevated --update/--set-source/--clear-source/--import-bundle typically returns, rather than 77 (see each switch's entry above) |
| 77 | PRIVILEGE_REQUIRED | Administrator privileges are required and were not available; nothing was changed (currently only --update-schedule create/remove pre-check for this) |
17.8 - Registry Keys
All under HKLM\SOFTWARE\Emerita\Patchwork - the same key Patchwork.exe itself uses (see Appendix C) - with these additional values written and read only by pwtools.exe:
| Value | Type | Written by | Purpose |
|---|---|---|---|
UpdateSource | REG_SZ | --set-source (removed by --clear-source) | The configured update source, if any |
LastUpdateResult | REG_SZ | every update command, on exit | e.g. "UPDATED (0)" - outcome and code of the most recent update run (overwritten each time, not appended) |
Version | REG_SZ | a successful --update | Installed pwtools.exe/Patchwork.exe version, used to decide whether a fetched release is newer |
ManifestETag | REG_SZ | --update, on a fully successful run | Cached HTTP ETag, so the next poll's manifest fetch can be conditional |
MaintenanceSerial | REG_SZ | --update, after reconciling a maintenance-serial update | A fingerprint (the last 11 characters only) of the last-applied serial - the full serial is never stored in the registry |
Reading these values does not require elevation; writing or deleting them does.
18 - Patchwork GUI
New in v3.0.0
18.1 - Overview
Patchwork-gui.exe is a Windows front end for Patchwork.exe and pwtools.exe, built on the PWExec remote-execution engine. Rather than building a command line by hand, an administrator picks an operation from a dropdown, fills in the relevant tab(s), and adds one or more target computers on the Computers tab. The GUI composes the equivalent command line internally, deploys the correct binary to each target, runs it, and streams progress and results back per-host on the Execute tab.
It is an optional installer component, not part of a default install - see Section 3. It is offered, pre-checked, only under Advanced installation, and it always installs together with its required service host, Patchwork-svc.exe (see 18.9).
The notebook has eight tabs, not all shown for every operation: Action (the operation dropdown, per-run credentials, and the free-text Arguments line), Computers (the target list), Reboot (shown only when Reboot is selected - delay, message, force-close), Filter, Options, Reporting, Advanced, and Execute (per-host results and the run's transcript, appears once Run is pressed). Filter, Options, and Reporting correspond to the like-named parts of Section 7; Advanced is present for every operation and is never removed from the notebook, though most of its controls are greyed out for one operation (Register).
The dropdown offers 13 operations. Six map one-to-one onto a Patchwork.exe switch and always show every tab. Of the remaining seven, five genuinely behave as focused, single-purpose operations that clear Arguments and hide Filter/Options/Reporting - Reboot, Register, Update, Ping, and Patchwork Updates. Setup Patchwork and Schedule are exceptions to that pattern: both keep every tab visible and usable, described in 18.4 below.
18.2 - Operations Reference
| # | Dropdown item | Binary / switch | Hides Filter/Options/Reporting? |
|---|---|---|---|
| 1 | Search | Patchwork.exe --search | No |
| 2 | Download | Patchwork.exe --download | No |
| 3 | Install | Patchwork.exe --install | No |
| 4 | Uninstall | Patchwork.exe --uninstall | No |
| 5 | History | Patchwork.exe --history | No |
| 6 | Installed | Patchwork.exe --installed | No |
| 7 | Reboot | PWExec-deployed reboot, via Patchwork-svc.exe on the target | Yes |
| 8 | Setup Patchwork | Patchwork.exe --setup, then (on success) pwtools.exe --register and pwtools.exe --update | No |
| 9 | Patchwork Updates | pwtools.exe --update-schedule | Yes |
| 10 | Update | pwtools.exe --update | Yes |
| 11 | Schedule | Patchwork.exe --update-schedule | No |
| 12 | Register | pwtools.exe --register | Yes |
| 13 | Ping | local ping.exe, run by the GUI itself - no target deployment | Yes |
Setup Patchwork and Patchwork Updates sit next to each other in the dropdown (items 8 and 9) because both are "get this target current on Patchwork itself" operations - Setup Patchwork performs the one-time install/registration/first-update bring-up, Patchwork Updates configures the recurring cadence that keeps it current afterward.
18.3 - Functional Operations (1-6)
Search, Download, Install, Uninstall, History, and Installed map one-to-one onto the like-named Patchwork.exe switches described in Section 7.1. These operations show every tab:
- Action - the operation dropdown, per-run credentials (User/Password), and the free-text Arguments line the GUI composes.
- Computers - the target list (see 18.11).
- Filter - the switches from Section 7.3 (classification, severity, KB list, regex match, release date, etc.).
- Options - installation behaviour switches from Section 7.7 (
--autoaccepteula,--force,--continue-errors, etc.). This tab also carries the update-source controls (WSUS / Windows Update / Microsoft Update). - Advanced - proxy, WSUS, timeout/retry, and the Scheduled updates controls (see 18.5).
- Reporting - logging, XML/JSON output, and notification switches; below a separator, a read-only exit-code reference covering both Patchwork.exe's own codes and Patchwork-svc's (see 18.15).
- Execute - per-host progress and results, populated once Run is pressed.
18.4 - The Other Operations (7-13)
Five of the remaining seven operations don't take filters, install options, or report output, so the GUI clears Arguments and hides Filter, Options, and Reporting for them, to avoid presenting controls that would have no effect. Setup Patchwork and Schedule are the two exceptions - both keep every tab visible and usable, as described in their own entries below.
Reboot - Genuinely goes through PWExec, the same as any other operation: it deploys and starts Patchwork-svc.exe on the target via the target's own Service Control Manager, then sends it a direct reboot control message - this still requires the same remote-admin access as running Patchwork.exe/pwtools.exe on the target would (see 18.10). A Reboot tab appears with Delay, Message, and Force-applications-closed fields, matching Patchwork.exe's own --delay, --reboot-message, and --force-close. The GUI shows a confirmation prompt before dispatching, since a reboot interrupts whatever the target is doing.
Setup Patchwork - The primary action, composed onto the Arguments line the same way a functional operation's is, is Patchwork.exe --setup - so, unlike the rest of this group, Filter/Options/Reporting/Advanced all stay visible and usable, behaving exactly as they do for the six functional operations, since --setup is itself a real Patchwork.exe operation that can legitimately take those switches. Only after --setup succeeds on a given host does the GUI chain two further commands on that host: pwtools.exe --register (skipped, not failed, if this machine has no license to pass on) and then, unconditionally, pwtools.exe --update. Only the primary --setup step's own result decides pass/fail for that host in the results list - the two follow-up steps cannot flip it.
Patchwork Updates - Runs pwtools.exe --update-schedule on the target to register, remove, or show a recurring Patchwork product-update task (see 17.4). Hides Filter/Options/Reporting; the Source field on Options is not merely inert here - the whole Options tab is removed from the notebook, since pwtools.exe --update-schedule reads its update source from the target's own registry rather than a value the GUI could pass in (see 18.5). Requires Administrator privileges on the target for register/remove; show does not.
Update - Runs pwtools.exe --update for a one-off Patchwork update on the target, without touching any scheduled task. Advanced stays visible and fully enabled (Concurrent sessions genuinely applies here, same as any multi-target run) even though Filter/Options/Reporting are hidden.
Schedule - Runs Patchwork.exe --update-schedule to register, remove, or show the target's Windows update schedule (the Patchwork Install task described in 7.13). Distinct from Patchwork Updates, which schedules Patchwork's own updates via pwtools.exe instead. Like Setup Patchwork, this operation does not hide Filter/Options/Reporting - selecting it only navigates the notebook to the Advanced tab, so the Scheduled updates controls are immediately visible, while whatever the other tabs already held is left exactly as it was.
Register - Runs pwtools.exe --register to register or refresh the Patchwork licence on the target, independent of Setup Patchwork's chained flow. Advanced remains visible but greyed out for most of its controls here (Concurrent sessions/copies don't meaningfully apply to a single quick registration call), leaving only the read-only registration-status fields active.
Ping - The one operation this GUI performs itself, without going through PWExec at all: it spawns a local ping.exe -n 1 -w 4000 <host> process per target directly on the machine running the GUI. Nothing is deployed to any target, no PWExec service is installed or started, and no SMB/RPC connection to the target is made - Ping is meaningfully lighter-weight than every other operation, and a genuinely safe pre-flight check even against a target with no PWExec access configured at all. Because its command line never depends on gathering anything else from the form, Arguments is filled with the exact ping.exe flags immediately on selection, rather than only at Run (see 18.6).
18.5 - The Advanced Tab and Scheduled Updates (dual-use by design)
The Advanced tab's Scheduled updates section - a cadence dropdown, a time field, and a variance field - is shared between two operations that otherwise schedule completely different things:
| Field | Used by Schedule (Patchwork.exe --update-schedule) | Used by Patchwork Updates (pwtools.exe --update-schedule) |
|---|---|---|
| Cadence | Mandatory - daily, weekly:<day>, once, remove, show | Mandatory - same grammar |
| Time | Mandatory when creating a schedule | Optional - target derives a sensible default if omitted (see 17.4) |
| Variance | Optional, defaults to no variance | Optional, defaults to no variance |
Both Patchwork.exe and pwtools.exe accept the identical daily | weekly:<Mon..Sun> | once cadence grammar (see the note at the end of 7.13), so the GUI deliberately reuses one set of controls rather than duplicating them per binary. Which binary the values are sent to, and which scheduled task ends up being touched, is determined entirely by which operation is selected in the dropdown - Schedule targets the Patchwork Install Windows-update task; Patchwork Updates targets the separate Patchwork Product Update task. Selecting remove or show as the cadence value on either operation drops the time and variance fields from the composed command line, since neither subcommand accepts them.
Because Patchwork Updates does not require a source URL (pwtools.exe --update-schedule reads the update source from the target's own registry), the Options tab - where the source-related controls live - is removed from the notebook entirely while Patchwork Updates is selected, rather than merely left visible but inert.
18.6 - Argument Field and Tab Visibility Rules
For the five operations that genuinely hide tabs (Reboot, Patchwork Updates, Update, Register, Ping), the GUI:
- Clears the Arguments field on selection, since these five construct their entire command line from dedicated tab fields rather than free-text arguments - except Ping, which instead fills Arguments immediately with the exact ping.exe flags it is about to send (
-n 1 -w 4000), since that line is fixed and does not depend on Run gathering anything else from the form first. - Hides the Filter, Options, and Reporting tabs, since none of their switches apply.
- Leaves Advanced visible always - it is never removed from the notebook for any operation - fully enabled for Update and Ping, greyed to its read-only fields for Register, and the source of the Scheduled updates controls for Patchwork Updates.
Setup Patchwork and Schedule behave like the six functional operations in this respect: neither clears Arguments nor hides any tab. Schedule additionally navigates the notebook to Advanced on selection, since that is where its own controls live, but leaves Filter/Options/Reporting untouched.
Register, Update, and Patchwork Updates only reveal their real command line at Run. Selecting any of the three clears Arguments immediately, but the field stays empty until Run is pressed - what each of them actually sends (a masked licence serial, a fixed pwtools.exe switch, or a cadence read off the Advanced tab) is only computed then. Ping is the one tab-hiding operation whose command line is knowable up front, which is why it is shown immediately instead.
Leaving Register, Reboot, Update, Ping, or Patchwork Updates always clears Arguments too, regardless of the operation switched to. Switching between two operations that keep their tabs (the six functional operations, plus Setup Patchwork and Schedule) recomposes Arguments from whatever the Filter/Options/Reporting/Advanced tabs already held, since all of them genuinely describe the newly-selected operation. Switching away from any of the five tab-hiding operations is different: since none of them reads or writes those tabs while selected, whatever those tabs held is left over from before that operation was picked, not anything describing the operation now selected - so the GUI clears Arguments on the way out just as it does on the way in, rather than recomposing it from unrelated leftover state.
18.7 - Log Folder Naming
Each run's log output is written under a folder named after the first word of the selected dropdown item - so "Patchwork Updates" logs under a Patchwork folder, not PatchworkUpdates or Patchwork Updates:
| Dropdown item | Log folder |
|---|---|
| Search | Search |
| Download | Download |
| Install | Install |
| Uninstall | Uninstall |
| History | History |
| Installed | Installed |
| Reboot | Reboot |
| Setup Patchwork | Setup |
| Patchwork Updates | Patchwork |
| Update | Update |
| Schedule | Schedule |
| Register | Register |
| Ping | Ping |
18.8 - Execution and Progress Reporting
Every operation except Ping - whether a single Patchwork.exe/pwtools.exe invocation or Setup Patchwork's chained sequence - runs through PWExec's remote execution engine (see 18.10 for how). PWExec deploys the appropriate binary to each target, runs it, and reports progress back to the GUI per host via ProgressEvent/HostEvent callbacks, so a multi-target run shows live status for every computer rather than only an aggregate result. Cancellation is supported mid-run; a cancelled run stops dispatching to targets that have not yet started and reports the outcome for each target that had already begun. Ping bypasses PWExec entirely (see 18.4) but reports its own per-host progress through the same Execute-tab UI.
18.9 - Installation Requirements and the Service Host
Patchwork-gui.exe and its required service host, Patchwork-svc.exe, are installed together as the "Patchwork GUI" component (see Section 3). This component is offered, pre-checked, only under Advanced installation - a default Full installation does not include it, and neither binary is present unless Advanced installation was chosen and the component left ticked.
Patchwork-svc.exe must sit in the same directory as Patchwork-gui.exe - PWExec looks for the service host next to whichever executable started it. If it is missing (for example, Patchwork-gui.exe copied out of its install directory on its own, without Patchwork-svc.exe alongside it), every remote run against every target fails after roughly a 30-second Service Control Manager timeout, typically reported per host as an opaque [Ret=1053] rather than a clear "service host not found" message - if you see that error across every target at once, check for this first before assuming a target-side problem.
Patchwork-gui.exe itself takes no user-facing command-line arguments. It does accept one internal --crash-monitor <socket> argument, used only when it relaunches itself as its own crash-report watchdog (see 18.13) - this is not meant to be passed by hand.
18.10 - Deployment, Authentication, and Security
PWExec is a PsExec-style remote execution engine: for each target it opens an SMB connection to the target's IPC$/ADMIN$ administrative shares, then installs and starts a service via the target's own Service Control Manager to actually run the requested binary. A target therefore needs, at minimum: TCP 445 (SMB) and RPC reachable, the ADMIN$ share present and not disabled, the Server service (File and Printer Sharing) running, and credentials equivalent to local Administrator on that target.
The control channel between the GUI and the service it deploys on each target is authenticated and fully encrypted via SSPI/Negotiate - Kerberos where the machines are domain-joined, NTLM otherwise - with every control message, including the credentials the GUI passes, sealed via EncryptMessage.
Deploying Patchwork.exe/pwtools.exe itself to a target is a probe-then-copy: the service checks what is already present on the target at the fixed install path (C:\Program Files\Emerita\Patchwork) and copies whichever binary is needed from the GUI's own install directory only if it is missing or out of date. Every binary is Authenticode-verified against Emerita's signing certificate before it is ever sent to a target - the same check described for Patchwork.exe itself in Section 14, Code Signing.
18.11 - Credentials and Target Lists
The Action tab's User/Password fields are a single credential pair for the whole run, not one per target - every target in the current run is contacted with the same credentials. Leaving both blank uses the GUI's own process token (i.e. whatever account is running Patchwork-gui.exe) instead.
Regardless of which credentials authenticate the connection, the deployed process itself always runs as Local System on the target, not as the account given in User/Password - the GUI requests this unconditionally. The User/Password pair therefore only ever controls how the GUI connects to a target, never what account the operation actually runs under once it's there.
The target list on the Computers tab is a plain text list, one computer name per line (CRLF-terminated when saved from the GUI; a UTF-8 byte-order mark at the start of an imported file is tolerated). Adding or importing targets also accepts a comma-separated line as a shortcut for entering several names at once. This is not a CSV format with columns - there is nowhere to record per-target credentials, ports, or other metadata; every target in a run shares the one credential pair from the Action tab described above.
18.12 - Concurrency, Timeouts, and Retries
The Advanced tab's Concurrent sessions field controls how many targets are contacted in parallel; the GUI defaults it to 32. Concurrent copies - how many binary deployments can be in flight at once - defaults to 10. Concurrent sessions must be at least 1; Concurrent copies is bounded to 1-256.
There is no separate per-target connect timeout or overall run timeout configured by default - a run waits as long as each target's own connection and execution take. If a target is unreachable, expect the underlying SMB/SCM connection attempt to time out according to Windows' own network timeouts, not a Patchwork-specific one, and no automatic retry beyond that.
18.13 - Logging, Crash Reports, and Project Files
Each run writes one log file per target computer into that run's log folder (see 18.7), plus a Patchwork-svc.log covering run-level output and a status.csv summarising per-host counts, including each host's exit code. The Execute tab's transcript reflects the same information live during the run. A host's exit code there can come from three different places - see 18.15 before assuming a number means what it would in Section 9 or 17.7.
If Patchwork-gui.exe itself crashes (an unhandled panic, an access violation, a stack overflow), a built-in crash guard writes a log entry and a minidump under %LOCALAPPDATA%\Emerita\Patchwork-svc\Logs\Crashes\crashes.log (with accompanying .dmp files in the same folder). Include these if reporting a GUI crash to support, alongside the items listed in Section 16, Collecting a Support Bundle.
The GUI can save and reload its current Action/Filter/Options/Reporting/Advanced configuration as a project file (a plain key=value text format). Passwords are deliberately never saved to a project file, and the Computers target list is not part of a project either - both must be re-entered, or re-imported, when a project is reloaded.
18.14 - Licence and About
The About/Register dialog reads the GUI's own licence the same way Patchwork.exe/pwtools.exe do (via Obsidium - see Section 4), and displays it masked the same way it is shown elsewhere in the product, e.g. by pwtools.exe --show (17.2).
18.15 - PWExec/Patchwork-svc Exit Codes (100-109)
Every operation the GUI runs against a target - except Ping, which never leaves this machine (see 18.4) - goes through PWExec, the remote-execution engine behind both Patchwork-gui.exe and Patchwork-svc.exe (18.10). On success, the exit code reported for a host - in its Execute-tab row, in status.csv, in the run summary - is simply whatever Patchwork.exe or pwtools.exe itself returned on that target (Section 9 / Section 17.7). If PWExec itself could not get that far - the target was unreachable, the service host couldn't be deployed, the connection dropped mid-run - it reports one of these reserved codes instead, and no application ever ran (or its own exit code was never learned):
| Code | Meaning |
|---|---|
| 100 | Command line error |
| 101 | Failed to launch the application locally |
| 102 | No Patchwork-svc.exe service host available to copy to the target |
| 103 | Timed out connecting to the target |
| 104 | The Patchwork-svc.exe service could not be installed or started on the target |
| 105 | Could not communicate with the service once running |
| 106 | Failed to copy the application itself to the target |
| 107 | Failed to launch the application remotely |
| 108 | The application was terminated because it ran past a timeout |
| 109 | Stopped by Ctrl-C/Ctrl-Break, or - for one host in a multi-target run - the run was cancelled before that host's turn came |
This range is deliberately reserved well clear of any real application's own exit code, and clear of both Patchwork.exe's and pwtools.exe's own numbering (neither goes above 77) - a code of 100 or higher, seen anywhere in the GUI's output, always means a PWExec-level failure, never something Patchwork.exe/pwtools.exe itself reported. This same table is shown in the GUI itself, on the Reporting tab under Patchwork exit codes: - Patchwork.exe's own table first (headed Patchwork.exe error codes), then this one below it (headed Patchwork-svc error codes) - see 18.3.
--register's own exit code 2 means registration rejected, and 3 means it could not read the input - both genuine failures - but both happen to fall in the same success list and will still show green. If a Register, Update, Setup Patchwork, or Patchwork Updates row shows "Successful" but you have reason to doubt it, check the actual exit code column (or that host's own log) rather than trusting the colour alone.19 - Comparison and Migration
Patchwork vs Built-in Tools
| Capability | wuauclt / UsoClient | PSWindowsUpdate | Patchwork |
|---|---|---|---|
| Classification filtering | No | Yes | Yes |
| Severity filtering | No | Limited | Yes |
| Regex pattern filtering | No | No | Yes |
| JSON/XML reports | No | Limited | Yes |
| Email notifications | No | No | Yes |
| Syslog notifications | No | No | Yes |
| .NET runtime required | No | Yes | No |
| Exit codes for scripting | Minimal | Yes | Yes (extended) |
| WSUS target group control | No | Yes | Yes |
| KB allow/deny lists | No | Partial | Yes |
Migrating from PSWindowsUpdate
PSWindowsUpdate uses PowerShell verb-noun syntax. The mapping to Patchwork switches is straightforward:
| PSWindowsUpdate | Patchwork equivalent |
|---|---|
Get-WindowsUpdate | --search --info |
Get-WindowsUpdate -KBArticleID KB5012345 | --search --kb KB5012345 |
Install-WindowsUpdate -AcceptAll | --install --autoaccepteula |
Install-WindowsUpdate -Category Security | --install --classification U |
Remove-WindowsUpdate -KBArticleID KB5012345 | --uninstall --kb KB5012345 |
Get-WUHistory | --history |
Migrating from WuInstall
WuInstall users will find many switch names familiar, ensuring that a change-over to Patchwork is straightforward. Patchwork was designed with similar command-line conventions, although it was never designed as a drop-in replacement. There are key differences:
- Patchwork uses
--search,--download,--install,--uninstallas explicit operation flags rather than positional arguments. The/switch prefix is not available. - Classification codes largely match (C, U, D, etc.) but Patchwork adds
E(Driver Sets),V(Drivers), andG(Upgrades). - Output formats (XML and JSON) are richer and include per-update descriptions.
- Default options are stored in the registry via
--opt-saverather than a configuration file.
20 - Patchwork Installer Guide
This document describes PatchworkSetup.exe, built from Patchwork.iss in this directory — what the interactive wizard does step by step, every command-line switch it accepts for unattended/scripted installs, and where to look when something needs troubleshooting.
It does not cover using Patchwork itself once installed; see Patchwork.pdf (installed alongside the product) for that.
Install location
Patchwork always installs to:
C:\Program Files\Emerita\Patchwork
This is not user-configurable — the wizard's "Select Destination Location" page is disabled, because the product's own remote install/update logic already expects this fixed path on a 64-bit target.
Components
The installer offers two Setup Types, chosen on the "Select Installation Type" page:
| Setup type | What it installs |
|---|---|
| Full installation | Core files only. No further choice is offered. |
| Advanced installation | Shows a Select Components page (below) so Patchwork GUI can be added. |
Under Advanced installation, two Components are offered:
| Component | Contents | Notes |
|---|---|---|
| Core files | Patchwork.pdf, pwtools.exe, patchwork.exe | Fixed — always installed, checkbox cannot be unticked. This is the only thing a Full installation installs. |
| Patchwork GUI | patchwork-gui.exe, patchwork-svc.exe | Offered, pre-checked, under Advanced installation only. patchwork-svc.exe is the required service host — PWExec looks for it next to whichever executable is running, so it has to ship beside patchwork-gui.exe. |
Interactive install: step by step
Running PatchworkSetup.exe with no switches shows the normal wizard:
- Welcome — standard Inno Setup welcome page.
- Select Installation Type — choose Full installation or Advanced installation (see Components above).
- Select Components — Advanced installation only. Core files is fixed (always ticked); Patchwork GUI is offered, pre-checked.
- Product Registration (optional) — two fields, Username and Serial Number. Leave both blank to skip registration; you can always register later by running
pwtools.exe --register. If you fill in one field, you must fill in the other — Setup won't let you continue with just one. Neither field may contain a"character. This page can be pre-filled from the command line with/REGISTER=; see below. - Patchwork Command (optional) — a single Parameters field for any command-line parameters you want
patchwork.exerun with, silently, near the end of installation (for example, to import data or apply configuration as part of the rollout). Leave it blank to skip this step entirely. Unlike every other field in the wizard, this one is not validated — whatever you type is passed topatchwork.exeexactly as given, andpatchwork.exeis responsible for validating its own parameters. This page can be pre-filled from the command line with/PATCHWORKARGS=; see below. - Ready to Install — standard summary page; click Install.
- Installing — files are copied, then the silent steps described in the next section run, in order, before Setup finishes.
- Finished — standard completion page.
What happens silently at the end of every install
After files are copied, Setup runs up to four steps, each silently (no console window appears) and each optional in its own way. They run in this order:
- Registration — runs
pwtools.exe --register "Username|Serial", but only if both fields on the Product Registration page ended up non-blank (whether typed in or pre-filled by/REGISTER=). - Update scheduling — runs
pwtools.exe --update-schedule <cadence> --time <HH:MM> --time-variance <N>to create the recurring Windows scheduled task that keeps Patchwork up to date. By default:- cadence is
weekly:<Day>, where<Day>is the day of the week Setup itself is being run on; - time is the clock time Setup itself is being run at;
- time-variance is
60(minutes either side of that time, so many machines installed at once don't all phone home at the exact same second).
Each of these can be overridden — see
/CADENCE=,/TIME=and/TIMEVARIANCE=below.Before creating a schedule, Setup checks whether one already exists (
pwtools.exe --update-schedule show) and skips this step entirely if it finds one — so re-running the installer on a machine that already has a schedule (e.g. a repair install, or an upgrade) will not silently change or reset it. - cadence is
- Update source — runs
pwtools.exe --set-source <target>, but only if/SOURCE=was given on Setup's command line. There is no default; if it's omitted, the update source is left exactly as it was (or unconfigured, for a fresh install). This step is independent of step 2 above — it runs whenever a source is given, whether or not the schedule step ran. - Custom Patchwork command — runs
patchwork.exe <args>, but only if the Patchwork Command page's Parameters field ended up non-blank (whether typed in or pre-filled by/PATCHWORKARGS=). Both the exact command run and its output are logged — see Logs and troubleshooting.
Command-line switches
Standard Inno Setup switches
PatchworkSetup.exe is a standard Inno Setup installer, so it accepts all the usual Inno Setup command-line switches. The ones most relevant to a scripted/unattended install:
| Switch | Effect |
|---|---|
/SILENT | Hides the wizard and the progress window, but still shows error/prompt dialogs (e.g. the Registration page's validation errors, if reached). |
/VERYSILENT | Hides everything, including error/prompt dialogs — the fully unattended mode. Use this together with the switches below, since with no wizard shown, nothing can be typed in interactively. |
/SUPPRESSMSGBOXES | Suppresses message boxes; only has an effect combined with /SILENT or /VERYSILENT. |
/NORESTART | Prevents a reboot prompt even if one would otherwise be shown. |
/LOG or /LOG="filename" | Writes a full Setup log file — see Logs and troubleshooting. |
The full list is documented by Inno Setup itself (Setup's own /HELP switch, or the "Setup Command Line Parameters" topic in Inno Setup's documentation).
Patchwork-specific switches
All of the following are read via Inno Setup's own /Name=Value command-line parameter mechanism, so they work alongside any of the standard switches above. Every one is optional — omit it and the corresponding installer step either uses its computed default or is skipped entirely, as described in What happens silently.
Any switch value that needs to contain a space must be quoted, e.g. /TIME="02:00" (quoting isn't strictly needed for a value with no spaces, but doesn't hurt).
/ REGISTER
/REGISTER=Username|Serial
Pre-fills the Product Registration page's Username and Serial fields, in the same Username|Serial pipe-separated format pwtools.exe --register itself takes. In an unattended install (no page is ever shown), this is what actually causes registration to happen; in an interactive install it just pre-fills the two fields, which can still be edited or cleared before continuing.
If the value doesn't contain a | separator, it's ignored (and a note is written to Setup's log — see Logs); the fields are left blank rather than half-filled.
No default — omit it entirely and no registration happens unless the fields are filled in by hand.
/ CADENCE, / TIME, / TIMEVARIANCE
/CADENCE=<daily | weekly:<Mon..Sun> | once>
/TIME=<HH:MM>
/TIMEVARIANCE=<minutes>
Override the three parts of the update schedule described in step 2 of What happens silently:
| Switch | Overrides | Default when omitted |
|---|---|---|
/CADENCE | --update-schedule cadence | weekly:<the day Setup is run on> |
/TIME | --time | the clock time Setup is run at |
/TIMEVARIANCE | --time-variance | 60 |
These have no effect if an update schedule already exists on the machine — see step 2 above.
/ SOURCE
/SOURCE=<HTTPS-URL | \\share\path | dir>
If given, Setup runs pwtools.exe --set-source <value> — configuring where this machine fetches updates from (an HTTPS URL, a UNC share, or a local directory, for an offline/Tier 2 repository). If omitted, the update source is left untouched entirely; there is no default value.
/ PATCHWORKARGS
/PATCHWORKARGS=<args>
Pre-fills the Patchwork Command page's Parameters field with <args>, exactly as given. In an unattended install this is what causes patchwork.exe <args> to actually run, silently, near the end of installation.
This switch's value is not validated or restricted in any way — unlike every other switch above, it is not rejected for containing a " character, since it's expected to be a full patchwork.exe command line that may need its own quoted sub-arguments (for example, a file path containing spaces). patchwork.exe is responsible for validating whatever it's given.
No default — omit it (and leave the Patchwork Command page blank, if shown) and this step doesn't run at all.
Example command lines
A fully unattended install with a license and a source, using computed defaults for the update schedule:
PatchworkSetup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART ^
/REGISTER="Contoso Ltd|XXXX-XXXX-XXXX-XXXX" ^
/SOURCE=https://updates.example.com/patchwork
A fully unattended install that also pins a specific weekly update schedule:
PatchworkSetup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART ^
/REGISTER="Contoso Ltd|XXXX-XXXX-XXXX-XXXX" ^
/CADENCE=weekly:Sun /TIME=02:00 /TIMEVARIANCE=30 ^
/SOURCE=\\fileserver\patchwork-updates
An unattended install that also runs a custom patchwork.exe command (here, one whose own argument needs quoting, hence the doubled quotes) with a full Setup log for troubleshooting:
PatchworkSetup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART ^
/LOG="C:\Logs\patchwork-setup.log" ^
/PATCHWORKARGS="--import ""C:\seed data\customers.csv"""
(^ is the Windows cmd.exe line-continuation character, used above only to keep these examples readable across multiple lines — a real invocation is normally typed as a single line.)
Logs and troubleshooting
patchwork-setup-run.log — the custom Patchwork command's output
If the Patchwork Command step ran (i.e. /PATCHWORKARGS was given, or the Patchwork Command page wasn't left blank), both the exact command that was run and everything it printed (stdout and stderr) are written to:
C:\Program Files\Emerita\Patchwork\patchwork-setup-run.log
This is written to the install directory (not a temporary folder) so it survives after Setup exits and is available for troubleshooting. It's overwritten on each install that runs this step, so it always reflects the most recent run.
Setup's own log (/LOG)
Inno Setup can write a full log of everything Setup itself did — every page shown, every file installed, every [Run] entry and whether its Check condition passed, plus any diagnostic notes this script writes with Log(...) (for example, a note that /REGISTER or another switch was ignored because its value didn't parse). To capture this, add:
/LOG="C:\Logs\patchwork-setup.log"
to the Setup command line. This is the first place to look if a step you expected to run (registration, scheduling, source, or the custom command) doesn't appear to have happened.
Checking or changing settings after install
The following don't require re-running the installer — see Section 17 for pwtools.exe's full command reference. Run these from an elevated Command Prompt in the install directory (or with the full path to pwtools.exe).
| To... | Run |
|---|---|
| Check current registration | pwtools.exe --show |
| Register (or re-register) | pwtools.exe --register "Username|Serial" |
| Clear registration | pwtools.exe --clear |
| Check the update schedule | pwtools.exe --update-schedule show |
| Create/replace the update schedule | pwtools.exe --update-schedule weekly:Mon --time 03:00 |
| Remove the update schedule | pwtools.exe --update-schedule remove |
| Check the configured update source | pwtools.exe --show-source |
| Change the update source | pwtools.exe --set-source <target> |
| Revert to the default (direct) source | pwtools.exe --clear-source |
| Check for an update without applying it | pwtools.exe --check |
| Apply an update now | pwtools.exe --update |
Common issues
| Symptom | Likely cause / fix |
|---|---|
| Registration didn't happen | Either both Username and Serial were blank (by design — nothing to register), or /REGISTER was malformed (missing the | separator) and was ignored — check the Setup log. Run pwtools.exe --show to confirm current status, then pwtools.exe --register "Username|Serial" to register manually. |
| Update schedule wasn't created | Most likely one already existed — this step is skipped on purpose in that case (see step 2 of What happens silently). Confirm with pwtools.exe --update-schedule show; if you do need to change it, run pwtools.exe --update-schedule ... directly. |
| Update source wasn't set | /SOURCE wasn't given — there's no default. Set it after the fact with pwtools.exe --set-source <target>. |
| Custom Patchwork command didn't seem to run, or its effect isn't visible | Check patchwork-setup-run.log in the install directory (see above) for the exact command and its output — since this step isn't validated by Setup, any failure will be patchwork.exe's own error output in that log. |
| Need to know exactly what Setup did | Re-run with /LOG="<path>" and inspect the resulting log. |
21 - Appendices
Appendix A - Full Exit Code Reference
See Section 9.
Appendix B - Classification and Severity Code Reference
Classification codes:
| Code | Full name |
|---|---|
| C | Critical Updates |
| U | Security Updates |
| D | Definition Updates |
| I | Updates |
| R | Update Rollups |
| S | Service Packs |
| F | Feature Packs |
| E | Driver Sets |
| V | Drivers |
| G | Upgrades |
Severity codes:
| Code | Full name |
|---|---|
| C | Critical |
| I | Important |
| M | Moderate |
| L | Low |
| U | Unknown |
Appendix C - Registry Keys
| Key | Value | Type | Written by |
|---|---|---|---|
HKLM\SOFTWARE\Emerita\Patchwork | Installed | REG_SZ | --setup |
HKLM\SOFTWARE\Emerita\Patchwork | Version | REG_SZ | --setup |
HKLM\Software\Emerita\Patchwork | DefaultOptions | REG_SZ | --opt-save |
HKLM\Software\Emerita\Patchwork | RebootCycle | REG_SZ | --rebootcycle |
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment | Path | REG_EXPAND_SZ | --setup |
License keys are also stored in this location, but are not documented here.
WSUS and proxy configuration keys are modified temporarily during operations and restored on exit.
Appendix D - Commands that CAN be saved with --opt-save
The following switches can be added to the default options. Flag names below are the exact spelling Patchwork.exe accepts (kebab-case) - this list was previously stale in places; if you were matching a saved-default flag against an older copy of this table and it was rejected as unrecognized, this revision is why.
Update Type Selection
--driveronly--includedrivers--alltypes--include-potentially-superseded-updates--preview
Search Criteria & Filtering
--all--criteria--classification--severity--product--exclude-product--match-filter--nomatch-filter--matchfile--nomatchfile--releasedate--max-update-count--max-total-size--only-downloaded
Configuration
--use-wsus--use-windowsupdate--wsus-server--use-mu-on-error--use-wu-on-error--use-microsoftupdate--targetgroup--notargetgroup
Proxy
--disable-win-http-proxy--disable-ie-proxy--auto-detect-proxy--proxy-address--proxy-port
--proxy-username and --proxy-password are deliberately not in this list - see Appendix E; they parse but are not yet implemented, and saving them would persist a no-op (and, being credentials, a plaintext password in HKLM).
Installation Options
--autoaccepteula--quiet--force--ignore-errors--continue-errors--redownload--parallel-downloads(only if non-default)--defender-fix
--disableprompt, --nocachedel, and --clear-localcache are likewise excluded - see Appendix E.
Offline Scanning
--offlinescan
Logging & Reporting
--logfile--logmode--logencoding--xmlout--xmlout-with-bom--jsonout--info--show-progress--third-party-progress--silent--color--nocolor--extended-error--simple-error--hide-sensitive
Timeout & Runtime
--maxruntime--retrycount--noretry
Custom Actions
--custom-action-before--custom-action-after
System Checks
--check-available-disk-space--refresh-last-update-timestamps
Registration / Setup / Service
--home
Email & SMTP Notifications
--smtp-server--smtp-port--smtp-encryption--smtp-user--smtp-password--email-from--email-to--email-subject--send-email-on-completion
Syslog Notifications
--syslog-server--syslog-port--syslog-protocol--syslog-facility--syslog-tag--send-syslog-on-completion
Appendix E - Commands that CANNOT be saved with --opt-save
These are deliberately excluded - operations, registration/setup, reboot/shutdown, and the option-management/special flags themselves.
Operations (mandatory action flags)
--search--download--install--uninstall--history--installed--download-cache--install-cache
Search filters NOT persisted (these are filters but are intentionally not saved due to their typically explicit nature)
--kb--match-id
Registration / Setup / Service
--register--unregister--setup--remove--register-microsoftupdate--clear-wsus-server
Reboot / Shutdown
--reboot--shutdown--reboot-if-needed--shutdown-if-needed--force-close--delay--reboot-message--rebootcycle
Logging / Debug (not persisted)
--debug
Testing & Scheduling
--donothing--update-schedule--time--time-variance
Default Options Management & special/self flags
--opt-save--opt-add--opt-clear--opt-show--opt-ignore--opt-verbose--list-exit-codes--healthcheck
Accepted but not yet implemented
These switches parse successfully and are validated, but currently have no effect - see each one's own entry in Section 7 for detail. They are excluded here specifically so a saved default can't silently store no-op behaviour (and, for the proxy credentials, a plaintext password in HKLM):
--clear-localcache--nocachedel--disableprompt--proxy-username--proxy-password
Appendix F - Sample XML Report
<?xml version="1.0" encoding="utf-8"?>
<PatchworkReport>
<Summary>
<TotalUpdates>3</TotalUpdates>
<TotalSize>314572800</TotalSize>
<Operation>install</Operation>
<Status>Success</Status>
</Summary>
<Updates>
<Update>
<Title>2025-04 Cumulative Update for Windows 10 Version 22H2</Title>
<KBArticleID>KB5036893</KBArticleID>
<Classification>Security Updates</Classification>
<Severity>Critical</Severity>
<Size>209715200</Size>
<ReleaseDate>2025-04-08</ReleaseDate>
<UpdateID>9fb049d9-8ee3-4913-937f-196648006ca5</UpdateID>
</Update>
</Updates>
</PatchworkReport>
Appendix G - Sample Scheduled Task
The following XML creates a weekly Sunday 02:00 task that runs Patchwork under SYSTEM:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Triggers>
<CalendarTrigger>
<StartBoundary>2025-01-05T02:00:00</StartBoundary>
<ScheduleByWeek>
<WeeksInterval>1</WeeksInterval>
<DaysOfWeek><Sunday /></DaysOfWeek>
</ScheduleByWeek>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal>
<UserId>S-1-5-18</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Actions>
<Exec>
<Command>C:\Program Files\Emerita\Patchwork\patchwork.exe</Command>
<Arguments>--install --classification CU --severity CI --autoaccepteula --reboot-if-needed --delay 300 --silent --logfile C:\Logs\weekly-patch.log --xmlout C:\Reports\weekly-patch.xml</Arguments>
</Exec>
</Actions>
</Task>
Import with: schtasks /create /xml "task.xml" /tn "Patchwork Weekly"
Appendix H - Sample PowerShell Deployment Script
$date = Get-Date -Format 'yyyyMMdd'
$logFile = "C:\Logs\patch-$date.log"
$reportFile = "C:\Reports\patch-$date.xml"
Stop-Service -Name "MyAppService" -ErrorAction SilentlyContinue
patchwork --install `
--classification CU `
--severity CI `
--autoaccepteula `
--ignore-errors `
--reboot-if-needed `
--delay 300 `
--silent `
--logfile $logFile `
--xmlout $reportFile
$result = $LASTEXITCODE
Start-Service -Name "MyAppService" -ErrorAction SilentlyContinue
switch ($result) {
0 { Write-EventLog -LogName Application -Source Patchwork -EventId 1000 -Message "Patching complete, no reboot." }
10 { Write-EventLog -LogName Application -Source Patchwork -EventId 1001 -Message "Patching complete, reboot scheduled." }
3 { Write-EventLog -LogName Application -Source Patchwork -EventId 1002 -Message "No updates found." }
default {
Write-EventLog -LogName Application -Source Patchwork -EventId 1099 -EntryType Warning `
-Message "Patching finished with unexpected code $result. See $logFile."
}
}
exit $result
Appendix I - Glossary
| Term | Definition |
|---|---|
| Classification | The update category as defined by Microsoft (Critical, Security, Definition, etc.) |
| KB | Knowledge Base article number. Each update is associated with one KB article that describes its content. |
| MECM (SCCM) | Microsoft Endpoint Configuration Manager (formerly SCCM). An enterprise device management platform. |
| MU | Microsoft Update. An update service that extends Windows Update to cover Office and other Microsoft products. |
| Severity | The MSRC (Microsoft Security Response Center) risk rating for a security update. |
| WUA | Windows Update Agent. The operating system component that manages update operations via COM. |
| WSUS | Windows Server Update Services. An enterprise update proxy that caches and controls the distribution of Microsoft updates. |
21 - Support
In the event of any configuration issues or bugs, if you have an active support agreement in place, please contact us via support@emerita.dev so we can investigate further.
For additional support and updates, please visit https://www.emerita.dev/patchwork.html
Patchwork is provided expressly with NO warranty.
See the link above for terms, conditions and support.
Patchwork is © Emerita Codeworks (UK Ltd) 2026.
If you can't find the answer here, get in touch. We typically reply within a working day.