Offline Windows Patching on an Air-Gapped VPS: Exporting and Importing with wsusutil

An air-gapped VPS has no route to Microsoft Update, and WSUS cannot synchronize its catalog without one. The workable answer is to carry the update metadata and binaries across the gap on removable media using wsusutil export on a connected upstream server and wsusutil import on the isolated downstream. The mechanics are simple; the disk space math is what trips people.

The export package is not just the .cab payloads. It contains the WSUS database content minus the log files, expanded to a folder on disk before being packed, so peak usage during export is roughly twice the final package size plus the SQL database itself. On a VPS with a 100 GB data disk and a 60 GB WSUS content store, that peak easily exceeds the volume.

Plan the sizing before you run the command, not after. A useful starting number: content store × 2 + database size + 20 GB working headroom. For a Windows VPS used as an offline update point, that usually means attaching a temporary second volume for the export stage and detaching it once the media is written.

Preparing the upstream server

Decline nothing casually. Every declined update is excluded from the export, so the isolated side will never receive it. On the connected upstream, approve updates for the exact products and classifications the air-gapped estate needs, let synchronization finish, and confirm that content has actually downloaded — approved but not downloaded updates appear in the catalog but fail at install with error 0x80244019.

# On the connected upstream
& "$env:ProgramFiles\Update Services\Tools\WsusUtil.exe" export D:\export\wsus-2026-11.cab D:\export\wsus-2026-11.log
Get-ChildItem D:\export | Select Name,@{n='GB';e={[math]::Round($_.Length/1GB,2)}}

# On the isolated downstream
& "$env:ProgramFiles\Update Services\Tools\WsusUtil.exe" import E:\media\wsus-2026-11.cab E:\media\wsus-2026-11.log
StageDisk needed (GB)Duration at 150 MB/s
Content store (mirrored)60baseline
Temp expand during export607 min
Output .cab556 min
Log file1–2< 1 min
Total working set~18015–25 min

The log file is worth attention. WsusUtil writes one line per update exported, and on a catalog of 60,000 updates it grows past a gigabyte. It is also the only record of which updates made it into the package, so archive it with the media rather than deleting it to save space.

What the export does not include

The package carries the update metadata, the binary payloads, and the approval state at export time. It does not carry computer group membership, target group assignments in a form the downstream will honor unconditionally, or the WSUS server’s own configuration — port, SSL settings, content path, and product list all have to match on the receiving side or the import will complete but clients will not see the updates.

It also does not carry the synchronization schedule or the server certificate. If the downstream uses SSL with a self-signed certificate, deploy the certificate to clients separately; an imported catalog over HTTPS with an untrusted certificate produces client-side errors that look like missing updates.

The import on the isolated side

Import is a database merge, not a replacement. Updates already present are updated; new ones are added; nothing is deleted. That is useful for incremental monthly packages but means an old package applied after a new one will not roll anything back. Sequence imports by date and keep the media labeled with the export date and the upstream sync timestamp.

The import runs as a single database transaction, so a 60 GB package can hold the WSUS database locked for 40–90 minutes on modest hardware. Schedule it outside the approval window, stop the WSUS service during the operation if your version permits, and take a database backup first with wsusutil.exe backupAll — a failed import mid-way is rare but recovery without a backup is a rebuild.

Content path and hash verification

The common failure after a successful import is content that exists in the catalog but not on disk. WsusUtil reports success based on the database, and the binaries land under the configured local content folder — C:\WSUS\WsusContent by default. Confirm the content folder has the expected file count and total size before letting clients scan.

Hash mismatch is the other one: media copied over USB with a generic copy tool can lose a block silently. Always compare SHA-256 of the .cab before import, and on the downstream run a client-side wuauclt /resetauthorization /detectnow on one test machine to confirm it reports updates rather than error 0x80244022 or a pending install that fails on hash validation.

CheckPass criterionTool
Package integritySHA-256 matches sourceGet-FileHash
Catalog countWithin 1% of upstream approvedWSUS console counts
Content folderSize equals upstream content store ±3%Explorer / du
Client scanTest host sees the latest CUwuauclt /detectnow

Keeping packages small

Full content store exports become unmanageable after a year. Use incremental exports: run the export monthly with only newly approved updates still in the “not yet exported” state, which WsusUtil tracks on the upstream server. A monthly incremental for a typical 200-server estate is 2–6 GB; the initial full package is 50–80 GB. Keep the full package on the shelf as a rebuild artifact.

Decline superseded updates before each export. Microsoft supersedes cumulative updates on a fixed cadence, and declining the old one removes its binaries from the content store and shrinks the next incremental. Run the cleanup wizard with “unused updates and update revisions” monthly, but never with “unneeded update files” on a server you export from — it deletes payloads an unexported update still needs.

Pilot approval and rollback

Approve each imported package to a pilot group of three to five machines for 48 hours before promoting it. An air-gapped estate cannot pull a replacement update on demand, so a bad patch is fixed by importing a superseding package on the next media run — typically a week later. The pilot window is what prevents a fleet-wide outage with a one-week recovery tail.

Keep the previous two approved cumulative updates unapproved rather than declined, so a rollback via wusa /uninstall /kb:<number> works if a pilot finds a regression. Declining removes the payload from content and makes the uninstall fail with 0x800f0906.

A repeatable monthly routine

  • Day 1: upstream syncs, approve for the air-gapped product set, confirm downloads complete.
  • Day 2: decline superseded, run export to a temp volume with 2× headroom.
  • Day 2: hash the .cab, write to two media, label with date and sync timestamp.
  • Day 3: verify media on a scratch machine, then import on the downstream.
  • Day 3: compare content folder size, scan one test client, approve for pilot.
  • Day 4: promote to production groups; archive the log and hash list.

Two people should be able to run this without tribal knowledge; write the disk-size table into the runbook so nobody starts an export with 70 GB free. The transport is the fragile part of an offline Windows VPS patching workflow, not the commands, and the hash list is the only thing standing between a corrupt copy and a patch Tuesday that silently installs nothing.

Leave a Comment