1

I want to script-build a development system from fresh Windows installation media as if it were a Linux container. In this case I need every Windows system I build to share the same machine SID.

According to explanation by @AntonTykhyy this is done in the following manner:

  1. Fresh installation media is created with chained Unattend.xml files where the first file calls single sysprep /generalize /oobe /unattend:C:\Windows\System32\Sysprep\Second_Unattend.xml> /shutdown command using Microsoft-Windows-Setup-Shell/FirstLogonCommands Windows Component in pass 7
  2. When Sysprep finishes and computer shuts down the Windows Registry SYSTEM (from C:\Windows\System32\config\SYSTEM) hive should be loaded offline (using regedit.exe executed from Windows PE or different method)
  3. Bit 2 should be set to 1 in value OperationFlags of key SYSTEM\Setup\SetupCl\PendingRequest of the offline hive, i.e. REG_DWORD should be changed from hexadecimal 0x00007f0f (01111111 00001111 which is set by default) to 0x00000004 (0100)
  4. New "binary" value SidAccountDomainNew should be added to SYSTEM\Setup\SetupCl\PendingRequest registry key with the value of SID in "binary form" of 24 bytes long (the 8-byte fixed length header and 4 32-bit sub-authorities)

I have completed steps 1-3 successfully and I get new random machine SID every time. However I absolutely cannot figure out step 4. I have examined SID documentation (one, two, three) but whichever type of value I specify for SidAccountDomainNew - REG_BINARY or REG_DWORD - and whichever value I set I absolutely cannot get it to work (Install Windows dialog appears after reboot with this message Windows could not complete installation. To install Windows on this computer, restart the installation).

My best guess the 8-byte header of SidAccountDomainNew is S-1-5-21 in binary (01010011 00101101 00110001 00101101 00110101 00101101 00110010 00110001 using online ASCII text-to-binary converter) and that's it. I re-educated myself on binary (bits and bytes and 32-bit numbers) but cannot get the numbers to fit in 24 bytes specified by @AntonTykhyy.

According to my research there's absolutely no documentation on this matter on the Internet and SetupCl.exe is completely undocumented. The only source of knowledge is information provided by @AntonTykhyy but I cannot comment in his question to ask for an example on how the SidAccountDomainNew should be set correctly for i.e. S-1-5-21-86420-86420-86420 (also he mentions 4 sub-authorities so the correct SID might be S-1-5-21-86420-86420-86420-something because Microsoft's article says sub-authorities are tree blocks of digits 1-2-3 that follow S-1-5-21-, so it's unclear what are 4 sub-authorities of 32-bits).

I have also found this SID explanation which makes my assumptions regarding first 8 bytes of header incorrect, I guess:

The common way to write a SID is in the form S-1-5-21-xxx, or S-R-I-S… Where the first S is a literal to identify that this is a SID, the R is the revision number, and so far there has only been revision 1, the I is the identifier authority, and then the last S is the subauthority which can theoretically be repeated up to 15 times, although for Windows it’s repeated only 5 times. So for a standard Windows computer or domain SID it would look like S-1-5-21-aaaaaaa-bbbbbbb-ccccccc-ddddddd.

Internally within Windows a SID is stored as a variable array of 32 bit integers, typically for a total of 28 bytes. The first integer stores the revision, the count of number of sub-authorities, and the identifier authority. This is then followed by however many sub-authorities are in this SID. These sub-authority integers are stored in little-endian format meaning that the least significant byte is stored first, and explains why we have to do a complex transformation to get from the integers to the more common S-1-5-21-* format.

To summarize, I ask for an example of assigning specific SID S-1-5-21-86420-86420-86420 for machine using OperationFlags and SidAccountDomainNew after executing sysprep /generalize, specifically what type of the SidAccountDomainNew value should be used and what actual user input is required.

SID S-1-5-21-86420-86420-86420 example will do since according to article the 32-bit representation of 86420 decimal is known to be 000000000000000 10101000110010100 - this might save answer writing time (if it's relevant data at all).

P.S. I'm also not sure if setting OperationFlags to hexadecimal 0x00000004 is required because hexadecimal 0x00007f0f (01111111 00001111) has bit 2 set too.

1 Answer 1

0

The problem is with the format of the 8-byte header. According to the SID structure, the header consists of 1 byte for the SID format version, 1 byte for the number of subauthorities, and 6 bytes (one SID_IDENTIFIER_AUTHORITY) for the authority. In "S-1-5-21-86420-86420-86420", the 1 is the version, the 5 is the authority, and each remaining component (including the 21, in contradiction of several articles!) is a subauthority. Then one field at a time, the numeric representation (bytes written in hex here) of this SID is:

  • 01 for the version (1)
  • 04 for the number of subauthorities (4), which is not written explicitly in the textual SDDL form
  • 00 00 00 00 00 05 for the authority (5), in big-endian order unlike the subauthorities
  • 15 00 00 00 for the first subauthority (21)
  • 94 51 01 00 three times, for the last three subauthorities (each 86420)

To more easily convert a SID to numeric format, you can use PowerShell!

#                                                         ↓ Change to your desired SID ↓
$sid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-21-86420-86420-86420')
$bytes = [array]::CreateInstance([byte], $sid.BinaryLength)
$sid.GetBinaryForm($bytes, 0)
$bytes | Format-Hex

Writing those 24 bytes as a REG_BINARY value named SidAccountDomainNew worked for me on Windows 10 2004 Enterprise. I didn't have to change OperationFlags because, as you said, its data already had bit 2 set.

1
  • Dear @BenN, I'm truly grateful for this comprehensive answer that features in-depth explanation and a valuable PowerShell script! Everything you explained works as advertised in Windows 10 version 21H2 as well. Thank you so much sir for your time, knowledge & expertise!
    – bananakid
    Commented May 18, 2022 at 14:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .