DisplaySync

Capturing the image

This is the last step before your image becomes the source of truth for a fleet. Get it wrong and every cloned device inherits the same defect; get it right and the next 50 deployments are 30 minutes apiece instead of 4 hours.

Three phases:

  1. Clean — strip identity and admin scaffolding the image shouldn't carry
  2. Sysprep generalize — Microsoft's mechanism for making a Windows install reusable
  3. Capture — copy the now-generalized disk into a redeployable image file

Clean before Sysprep

Anything machine-specific that survives Sysprep gets cloned to every device. The cleanup checklist:

Reset the DisplaySync identity

If you launched the sign app at any point during testing, it generated a unique sign ID and (if you claimed it) wrote organization/event assignment to disk. Both must be removed. (For the full map of what lives under the data root, see File locations.)

# Identity, assigned URL, cache database — all of it (machine-wide data root)
Remove-Item "C:\ProgramData\DisplaySync" -Recurse -Force -ErrorAction SilentlyContinue

The desktop sign's clone-detection logic also handles this on first boot — when a clone sees its MAC address doesn't match the stored sign-identity's MAC, it clears stale state. That's a backstop, not a substitute. Cleaner to start each clone from a blank slate.

Confirm maintenance mode is off

Remove-Item "C:\ProgramData\DisplaySync\.maintenance" -Force -ErrorAction SilentlyContinue

Clear logs

Logs accumulated during testing aren't useful in production:

Remove-Item "C:\ProgramData\DisplaySync\logs\*" `
  -Force -ErrorAction SilentlyContinue

The imgadmin account exists for image building. Production kiosks don't need it, and it's a privileged account whose password Sysprep does not rotate. Two options:

Option A — delete the account. Cleaner, but requires you to log in as another local admin (or the built-in Administrator) before the deletion takes effect:

# As a different admin
Remove-LocalUser -Name "imgadmin"
Remove-Item "C:\Users\imgadmin" -Recurse -Force

Option B — keep imgadmin, rotate its password. Less paranoid; if you re-image fleet devices in the field this account is useful to have:

$newPw = ConvertTo-SecureString "<long-random>" -AsPlainText -Force
Set-LocalUser -Name "imgadmin" -Password $newPw

Either is defensible. Pick one and apply it consistently across your fleet.

Leave Tailscale alone — the join task handles it

If you installed Tailscale, there is nothing to clean up here, and one thing not to assume.

Sysprep does not touch Tailscale. Generalize strips Windows' own machine-specific data; it has no idea third-party service state exists. The node identity lives in C:\ProgramData\Tailscale\ and comes through capture intact — so clones made from a joined image all boot carrying the same identity, and your tailnet shows one device entry flapping between machines instead of one entry per sign. Logging the build machine out before capture doesn't fix it either: a successful tailscale up --authkey ... doesn't keep the key on disk, only the identity it earned, so a logged-out image contains nothing that could join.

The boot-time join task from the Tailscale step is what makes this question moot. It runs on every boot of every clone and compares the machine's hardware fingerprint against the one recorded when the identity was created: same hardware means no-op, changed hardware means the disk was cloned, so the copied identity is cleared and the machine enrolls as a fresh device. That covers this Sysprep flow and straight disk duplication.

So: don't clear Tailscale state before Sysprep, don't log the build machine out, and don't leave enrollment to chance — before you capture, confirm the join task is registered and its staged key is in place. Both survive generalize, which is the point.

# Your join task, whatever you named it
Get-ScheduledTask | Where-Object { $_.TaskName -match "Tailscale" }

Sysprep generalize

Sysprep removes machine-specific data (SIDs, hostname, hardware info, MSA links, crypto keys) and prepares Windows to OOBE on next boot.

C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /shutdown

What each flag does:

FlagEffect
/generalizeStrip the SID and other machine-specific identifiers
/oobeOn next boot, drop into Windows OOBE (which auto-configures from the answer file if present)
/shutdownPower off after generalize completes (you don't want the device to boot back up before you capture)

A few things to know:

  • Sysprep can only run a limited number of times on a given install (3 by default on consumer Windows; effectively unlimited if you don't care). Don't repeatedly Sysprep the same install during iteration — work from a snapshot or fresh build instead.
  • WiFi profiles survive Sysprep generalize (they're in the system profile store). Verify on first clone boot anyway.
  • Scheduled Tasks survive. Your DisplaySync Sign task, the SetPrivateNetwork watchdog from base setup, and the Tailscale join task all come along — as does anything you staged under C:\ProgramData\.
  • Registry policies survive. All the kiosk hardening from Kiosk configuration carries over.

Optional: ship an unattend.xml

You can pair Sysprep with an unattend.xml answer file to fully automate OOBE on every clone:

C:\Windows\System32\Sysprep\sysprep.exe `
  /generalize /oobe /shutdown `
  /unattend:C:\path\to\unattend.xml

Useful values to script:

  • Time zone, region, keyboard layout
  • Whether to skip OEM screens
  • Auto-set computer name from MAC (with <ComputerName> set to a placeholder like *)

Worth the effort if your fleet is hundreds of signs. For dozens, manual Rename-Computer post-clone is fine.

Capture the image

Once Sysprep has shut the machine down, boot from your imaging tool of choice. We're agnostic — pick what your shop already uses:

ToolNotes
Macrium ReflectFree for non-commercial; commercial license is reasonable. Most polished UI.
ClonezillaFree, Linux-based, scriptable. Good for fleets.
DISM (Windows-native)dism /capture-image /imagefile:E:\image.wim /capturedir:C:\ /name:"DisplaySync"
Custom dd / partclonePower-user route; works for everything.

Whatever tool, capture the whole disk (or at least the system + recovery partitions), not just C:\. Boot loaders, ESP, and recovery partitions matter.

Save the captured image with a clear filename:

displaysync-kiosk-<sku>-<date>-<sign-version>.wim
displaysync-kiosk-thinclient-pro7-2026-05-01-v1.2.20.wim

Document which desktop-sign version is baked in, which BIOS revision the source had, and which Windows cumulative update was current when you captured. Future-you will thank you.

Validate the captured image

The image isn't done until you've cloned it back to a different unit and seen it boot cleanly. Pick a second device (same SKU as the build machine) and:

  1. Apply the captured image
  2. Power on, time the boot
  3. Confirm:
    • Auto-login works as DisplaySync
    • Sign app launches, shows the QR claim screen
    • Sign ID is different from your build machine's (status dashboard, Ctrl + Shift + S)
    • Heartbeat appears in the dashboard under Unclaimed Signs, separately from the build machine
    • If you use Tailscale: the clone shows up in the admin console as its own device (the build machine's entry untouched), and its sign detail page shows a Tailscale IP — see Verify the fleet joined
  4. Run a quick claim → assign → reboot cycle to confirm end-to-end works

If the second clone shows the same sign ID as the first, the identity reset step didn't take. Re-do it on the build image and re-Sysprep.

Fleet tracking

Once the image is validated, log it. A simple spreadsheet works fine:

HostnameMACSign IDLocationHardware ModelImage VersionProvisioned
LOBBY-SIGN-01aa:bb:cc:00:00:018f3..."Main Lobby"TC-Pro-7v1.2.20-2026-05-012026-05-04

Update it as you provision and as devices move between events. The dashboard's Sign detail view shows current state; the spreadsheet is for the offline questions ("which units shipped to the May 12 show?").

What's next

You have a deployable kiosk image. Next steps: