使用 Sysprep 为新的 Windows 安装分配特定计算机 SID

使用 Sysprep 为新的 Windows 安装分配特定计算机 SID

我想从全新的 Windows 安装介质编写脚本来构建开发系统,就像它是 Linux 容器一样。在这种情况下,我需要构建的每个 Windows 系统共享相同的机器 SID。

根据解释@AntonTykhyy 按以下方式完成:

  1. 新的安装媒体是使用链式Unattend.xml文件创建的,其中第一个文件使用Windows 组件调用单个sysprep /generalize /oobe /unattend:C:\Windows\System32\Sysprep\Second_Unattend.xml> /shutdown命令Microsoft-Windows-Setup-Shell/FirstLogonCommandspass 7
  2. 当 Sysprep 完成并且计算机关闭时,Windows 注册表SYSTEM(来自C:\Windows\System32\config\SYSTEM)配置单元应该离线加载(使用regedit.exe从 Windows PE 执行或其他方法)
  3. 离线配置单元的键值中的位 2 应设置为,即应从1十六进制(默认设置)更改为()OperationFlagsSYSTEM\Setup\SetupCl\PendingRequestREG_DWORD0x00007f0f01111111 000011110x000000040100
  4. 新的“二进制”应将值SidAccountDomainNew添加到SYSTEM\Setup\SetupCl\PendingRequest注册表项中,其中 SID 的值“二进制形式”长度为 24 字节(8 字节固定长度的头部和 4 个 32 位的子授权)

我已成功完成步骤 1-3,每次都会获得新的随机计算机 SID。但是我完全搞不懂步骤 4。我检查了 SID 文档()但无论我指定哪种类型的值SidAccountDomainNew-REG_BINARYREG_DWORD- 以及无论我设置哪种值,我都无法让它工作(Install Windows重启后会出现此消息的对话框Windows could not complete installation. To install Windows on this computer, restart the installation)。

我猜测的 8 字节头SidAccountDomainNewS-1-5-21二进制的(01010011 00101101 00110001 00101101 00110101 00101101 00110010 00110001使用在线 ASCII 文本到二进制转换器)就这样。我重新学习了二进制(位和字节32 位数字),但无法让数字适合@AntonTykhyy 指定的 24 个字节。

据我研究,互联网上根本没有关于此事的记录,SetupCl.exe完全没有记录。唯一的知识来源是@AntonTykhyy但我无法在他的问题中发表评论,要求给出一个关于如何SidAccountDomainNew正确设置 ie 的示例S-1-5-21-86420-86420-86420(他还提到了 4 个子权限,因此正确的 SID 可能是S-1-5-21-86420-86420-86420-something因为微软的文章说子权限是随后的数字 1-2-3 的树块S-1-5-21-,因此不清楚 4 个 32 位的子权限是什么)。

我还发现此 SID 解释这使得我对标头的前 8 个字节的假设不正确,我猜:

SID 的常见书写方式为 S-1-5-21-xxx 或 SRIS… 其中第一个 S 是文字,用于标识这是一个 SID,R 是修订号,到目前为止只有修订号 1,I 是标识符权限,最后一个 S 是子权限,理论上最多可重复 15 次,但对于 Windows 来说,它只重复了 5 次。因此,对于标准的 Windows 计算机或域 SID,它看起来像 S-1-5-21-aaaaaaa-bbbbbbb-ccccccc-ddddddd。

在 Windows 内部,SID 存储为 32 位整数的变量数组,通常总共 28 个字节。第一个整数存储修订版、子权限数量和标识符权限。然后是此 SID 中的子权限数量。这些子权限整数以小端格式存储,这意味着最低有效字节首先存储,并解释了为什么我们必须进行复杂的转换才能从整数转换为更常见的 S-1-5-21-* 格式。

总而言之,我要求提供一个S-1-5-21-86420-86420-86420为机器使用 分配特定 SID 的示例OperationFlags,以及SidAccountDomainNew执行后sysprep /generalize具体SidAccountDomainNew应该使用什么类型的值以及需要什么实际用户输入。

SIDS-1-5-21-86420-86420-86420示例将按照文章已知 86420 十进制的 32 位表示形式000000000000000 10101000110010100- 这可能会节省答案的书写时间(如果它是相关数据的话)。

PS 我也不确定是否需要设置OperationFlags为十六进制,因为十六进制()也设置了位 2。0x000000040x00007f0f01111111 00001111

答案1

问题出在 8 字节头的格式上。根据结构SID,头部由 1 个字节表示 SID 格式版本、1 个字节表示子授权数量、6 个字节(一个SID_IDENTIFIER_AUTHORITY) 表示权限。在“S-1-5-21-86420-86420-86420”中,1 表示版本,5 表示权限,其余每个部分(包括 21,与几篇文章相矛盾!)都是子权限。然后一次一个字段,此 SID 的数字表示(此处以十六进制表示的字节)为:

  • 01针对版本 (1)
  • 04子授权的数量 (4),在 SDDL 文本格式中没有明确写出
  • 00 00 00 00 00 05对于授权机构 (5),与子授权机构不同,采用大端顺序
  • 15 00 00 00对于第一个子权限(21)
  • 94 51 01 00三次,针对最后三个子权限(各 86420)

为了更轻松地将 SID 转换为数字格式,您可以使用 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

在 Windows 10 2004 Enterprise 上,将这 24 个字节写入REG_BINARY名为的值SidAccountDomainNew对我来说是可行的。我不需要更改,OperationFlags因为正如您所说,它的数据已经设置了位 2。

相关内容