feat(windows): unattended install — noprompt boot + disk config (M2)
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 3m25s
All checks were successful
Build SilverMetal Enhanced - Windows ISO / build (push) Successful in 3m25s
VM boot test proved the ISO boots under UEFI+SecureBoot+TPM2 but stopped at the "press any key" prompt and (post-boot) the disk screen. Enable hands-off install: - build.ps1: use efisys_noprompt.bin (fall back to efisys.bin) so the ISO boots without a keypress. - autounattend.xml: add GPT/UEFI DiskConfiguration (wipe disk 0 -> EFI/MSR/Win), ImageInstall index 1, AcceptEula (eval = no key). Bootstrap local-admin pw is a PLACEHOLDER the SKU pipeline must replace. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,12 +2,14 @@
|
||||
<!--
|
||||
SilverMetal Enhanced - Windows : Windows 11 IoT Enterprise LTSC answer file.
|
||||
|
||||
Purpose: automate OOBE, force a LOCAL account (no Microsoft Account / no cloud
|
||||
key escrow), set regional defaults, prepare a BitLocker-ready disk layout, and
|
||||
hand off to $OEM$\SetupComplete.cmd for first-boot hardening.
|
||||
Automates OOBE, wipes disk 0 to a clean GPT/UEFI layout, installs the LTSC
|
||||
image (index 1), forces a LOCAL account (no Microsoft Account / no cloud key
|
||||
escrow), and hands off to C:\Windows\Setup\Scripts\SetupComplete.cmd (run
|
||||
automatically as SYSTEM at end of setup) for the §A-H hardening.
|
||||
|
||||
SCAFFOLD (M0). Disk layout + image selectors are filled at M2 against the
|
||||
licensed media. Do NOT embed product keys, PINs, or secrets here.
|
||||
SECURITY NOTE: the bootstrap local-admin password below is a PLACEHOLDER for
|
||||
unattended setup only. The shippable SKU pipeline MUST inject a per-device
|
||||
credential (or force change at first logon); never ship this value.
|
||||
|
||||
Design: ../../iso-builder.md Controls: ../../hardening-spec.md (domains A, C)
|
||||
-->
|
||||
@@ -24,10 +26,35 @@
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64"
|
||||
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<!-- TODO-M2: DiskConfiguration (GPT, ESP + MSR + Windows), single GPT disk, BitLocker-ready.
|
||||
ImageInstall/OSImage/InstallFrom MetaData = IoT Enterprise LTSC index (see inputs.manifest.json). -->
|
||||
<DiskConfiguration>
|
||||
<WillShowUI>OnError</WillShowUI>
|
||||
<Disk wcm:action="add" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<DiskID>0</DiskID>
|
||||
<WillWipeDisk>true</WillWipeDisk>
|
||||
<CreatePartitions>
|
||||
<CreatePartition wcm:action="add"><Order>1</Order><Type>EFI</Type><Size>300</Size></CreatePartition>
|
||||
<CreatePartition wcm:action="add"><Order>2</Order><Type>MSR</Type><Size>16</Size></CreatePartition>
|
||||
<CreatePartition wcm:action="add"><Order>3</Order><Type>Primary</Type><Extend>true</Extend></CreatePartition>
|
||||
</CreatePartitions>
|
||||
<ModifyPartitions>
|
||||
<ModifyPartition wcm:action="add"><Order>1</Order><PartitionID>1</PartitionID><Label>System</Label><Format>FAT32</Format></ModifyPartition>
|
||||
<ModifyPartition wcm:action="add"><Order>2</Order><PartitionID>2</PartitionID></ModifyPartition>
|
||||
<ModifyPartition wcm:action="add"><Order>3</Order><PartitionID>3</PartitionID><Label>Windows</Label><Format>NTFS</Format><Letter>C</Letter></ModifyPartition>
|
||||
</ModifyPartitions>
|
||||
</Disk>
|
||||
</DiskConfiguration>
|
||||
<ImageInstall>
|
||||
<OSImage>
|
||||
<InstallTo><DiskID>0</DiskID><PartitionID>3</PartitionID></InstallTo>
|
||||
<InstallFrom>
|
||||
<MetaData wcm:action="add" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<Key>/IMAGE/INDEX</Key><Value>1</Value>
|
||||
</MetaData>
|
||||
</InstallFrom>
|
||||
</OSImage>
|
||||
</ImageInstall>
|
||||
<UserData>
|
||||
<ProductKey><!-- TODO-M2: IoT Enterprise LTSC key, build-time injected; NOT committed --></ProductKey>
|
||||
<!-- IoT Enterprise LTSC eval media is pre-pidded; no product key required. -->
|
||||
<AcceptEula>true</AcceptEula>
|
||||
</UserData>
|
||||
</component>
|
||||
@@ -38,28 +65,26 @@
|
||||
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||
<OOBE>
|
||||
<HideEULAPage>true</HideEULAPage>
|
||||
<HideOnlineAccountScreens>true</HideOnlineAccountScreens> <!-- force local account -->
|
||||
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
|
||||
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||
<ProtectYourPC>3</ProtectYourPC> <!-- disable "send data" express settings -->
|
||||
<ProtectYourPC>3</ProtectYourPC>
|
||||
</OOBE>
|
||||
<UserAccounts>
|
||||
<!-- TODO-M2: provision a local admin (no MSA). Password set at provisioning, not committed. -->
|
||||
<LocalAccounts>
|
||||
<LocalAccount wcm:action="add" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||
<Name>silvermetal</Name>
|
||||
<Group>Administrators</Group>
|
||||
<DisplayName>SilverMetal</DisplayName>
|
||||
<Password><Value>SM-setup-CHANGEME-1!</Value><PlainText>true</PlainText></Password>
|
||||
</LocalAccount>
|
||||
</LocalAccounts>
|
||||
</UserAccounts>
|
||||
<!--
|
||||
Hardening runs from C:\Windows\Setup\Scripts\SetupComplete.cmd, which
|
||||
Windows Setup executes automatically (as SYSTEM) at the end of setup,
|
||||
before first interactive logon. build.ps1 stages it + the hardening/
|
||||
modules into the image. No FirstLogonCommands needed (avoids a double-run).
|
||||
-->
|
||||
<RegisteredOwner>SilverMetal</RegisteredOwner>
|
||||
<RegisteredOrganization>SilverLABS</RegisteredOrganization>
|
||||
<!--
|
||||
Hardening runs from C:\Windows\Setup\Scripts\SetupComplete.cmd, which
|
||||
Windows Setup executes automatically (as SYSTEM) at the end of setup.
|
||||
-->
|
||||
</component>
|
||||
</settings>
|
||||
|
||||
|
||||
@@ -142,8 +142,11 @@ function Invoke-Brand { Write-Stage 'Stage 5: branding'; Write-Warning ' defer
|
||||
function Invoke-Repack {
|
||||
Write-Stage 'Stage 6: repack UEFI-bootable ISO (oscdimg)'
|
||||
$etfs = Join-Path $isoRoot 'boot\etfsboot.com'
|
||||
$efi = Join-Path $isoRoot 'efi\microsoft\boot\efisys.bin'
|
||||
if (-not (Test-Path $efi)) { throw "missing UEFI boot image: $efi" }
|
||||
# Prefer the no-prompt UEFI boot image so the ISO boots hands-off (no "press
|
||||
# any key"); fall back to the prompt variant if absent.
|
||||
$efi = Join-Path $isoRoot 'efi\microsoft\boot\efisys_noprompt.bin'
|
||||
if (-not (Test-Path $efi)) { $efi = Join-Path $isoRoot 'efi\microsoft\boot\efisys.bin' }
|
||||
if (-not (Test-Path $efi)) { throw "missing UEFI boot image under efi\microsoft\boot\" }
|
||||
# Work paths have no spaces (SYSTEM TEMP / runner temp), so omit oscdimg's
|
||||
# inner quotes around the boot images -- otherwise PowerShell mangles the
|
||||
# native -bootdata arg into doubled quotes (oscdimg Error 123).
|
||||
|
||||
Reference in New Issue
Block a user