Assign a specific machine SID to a new Windows system

Windows Setup assigns a unique machine SID to a Windows system at install time. The machine SID is not exposed over the network, and as such it usually does not matter what it is, but local users' security identifiers are based on the machine SID, and this can create problems when sharing user profiles and user-created files on NTFS volumes. Even if the files and folders have ACLs with only predefined, non-machine-specific SIDs such as the builtin Administrators group, their owner is the creating local user, identified by the machine SID and user RID. This scenario comes up, for instance, if you want to script-build your development system from fresh Windows installation media as if it were a Linux container. In this case you want every Windows system you build to share the same machine SID.

However, SysInternals' NewSID utility was deprecated and retired way back in 2009, and does not work properly on modern Windows versions. Is there a way to achieve the same result with regular Windows deployment tools? Mark Russinovich hinted in his post deprecating NewSID that this may be the case, but if so this capability is not documented. Of course, it would not be surprising: Microsoft has a long history of undocumented features going back to the days of MS-DOS.


Solution 1:

The undocumented SetupCl.exe utility, which is part of the Windows setup tooling that cleans up the system image as one step of the generalization process that runs when the new Windows system boots, normally does such things as generate new disk identifiers, fix up reparse points and replace references to the default system root (usually X:\) with whatever is appropriate for your target system (usually C:\), in all registry keys and possibly configuration files. This utility is invoked by the Windows setup process on first boot, and is controlled by the SYSTEM\Setup\SetupCl\PendingRequest registry key. The DWORD value OperationFlags in this key is a bit field that specifies which transformations the utility will perform.

In addition to the transformations mentioned above, SetupCl can replace an existing machine SID with a new one. This transformation is requested by setting bit 2 (0x4) in OperationFlags in the SYSTEM\Setup\SetupCl\PendingRequest key. Two optional binary values SidAccountDomainOld and SidAccountDomainNew in the same key supply the source and target machine SIDs. If the source SID is omitted, SetupCl takes it from the running system. If the target SID is omitted, SetupCl generates a new one. These values contain the machine SID in binary form and are 24 bytes long (the 8-byte fixed length header and 4 32-bit sub-authorities). To make SetupCl assign a specific machine SID, set bit 2 in OperationFlags and create the SidAccountDomainNew value containing the SID.

There are a couple of complications with this procedure:

  1. It works on images prepared by sysprep /generalize, but fails on Windows images freshly deployed by DISM or Expand-WindowsImage cmdlet. Fresh images are also in a generalized state, with a pending SetupCl request set up in the SYSTEM hive to run on first boot, but this request does not have bit 2 set. Setting it in the offline image results in an image that fails to deploy. To work around this limitation, one has to perform an extra round of generalize/specialize. One way to do this is with chained unattend files: the first unattend file specifies a single Microsoft-Windows-Setup-Shell/FirstLogonCommands command to execute sysprep /generalize /oobe /unattend:<second unattend file> /shutdown.

  2. Adding the SidAccountDomainNew value online, before or after sysprep /generalize, does not work, most likely because sysprep schedules some final steps to be performed at system shutdown. Mount the offline Windows image after sysprep /generalize finishes and the system shuts down, load the SYSTEM hive, and add it at that point.

  3. sysprep /generalize fails if there is a pending reboot from installing software. Reboot the system before generalizing, or perform the extra generalize/specialize step before installing software to the image.