sysprep /generalize regenerates the machine SID on every build, so an account
built by one image does not match a profile left on a persistent disk by an
earlier one -- different SID, so file ACLs, the NTUSER.DAT hive and ProfileList
all mismatch, and the profile will not load.
keepMachineSid drops /generalize and uses /oobe alone. The SID is then
inherited from the cached base install derivation, which is content-addressed
and so identical across every rebuild of the layers above it; the account,
always RID 1000, comes out the same each time. A profile kept on a data disk
then matches exactly, with no ownership or ProfileList fixups.
Without /generalize the specialize pass does not run, so the profile relocation
cannot ride the unattend there. It is written to the registry offline instead,
before the build's OOBE, which virt-win-reg applies ahead of the Audit Mode
boot. And because /generalize is also what strips MountedDevices, dropping it
means the data disk keeps its drive letter into the shipped image -- the
letterless-first-boot race that sent profiles temporary goes away at the root.
Default is unchanged (/generalize), correct for an image deployed to many
hosts; keepMachineSid is for an image that is always the same one machine.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117qMyjpuXsjpVAcpJbFD8g