Templates/unattend.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
  THE ANSWER FILE A NEW TASK SEQUENCE GETS, and MDT's Unattend_x64.xml in the
  same role: its New Task Sequence wizard copies a template answer file into the
  new sequence's folder, because a sequence whose Apply Windows Settings step
  names a file nobody supplied is a sequence that fails at the machine.

  IT IS THE SPIKES S7 DOCUMENT, TOKENISED. This is what was actually deployed to
  a Windows 11 Enterprise LTSC VM in SPIKES.md S7 - captured from the machine, not
  written from memory. S7 observed, on the machine it built:

    ComputerName applied from the specialize pass
    OOBE fully skipped
    the built-in Administrator enabled
    AutoLogon armed, with the password stored as an LSA SECRET and
      DefaultPassword absent from the registry

  THE TOKENS ARE NAMED HERE WITHOUT THEIR PER CENT SIGNS, on purpose: expansion
  runs over the WHOLE document, comments included, so a comment written with the
  token in it would put the machine's local Administrator password into a
  comment in the deployed answer file. The 'mints one password for a run'
  assertion counts occurrences, and it is what caught exactly that.

  HDTAdminPassword APPEARS TWICE BELOW - once under UserAccounts and once inside
  AutoLogon - because Setup reads them separately.

  HDTFullName AND HDTOrgName ARE WHAT THE WIZARD ASKS FOR on MDT's OS Settings
  page. A sequence that sets neither leaves the tokens unexpanded, which Windows
  accepts as literal text in those two fields - so the wizard writing them is
  what makes them meaningful, and leaving them out of the wizard is not a
  failure, only a machine registered to nobody in particular.

  New-HDTDeploymentPassword's alphabet excludes < > & " ' and %, on purpose, so
  a minted password substitutes into this document without escaping.
-->
<unattend xmlns="urn:schemas-microsoft-com:unattend">
  <settings pass="specialize">
    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64"
               publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
               xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
      <ComputerName>%HDTComputerName%</ComputerName>
      <RegisteredOwner>%HDTFullName%</RegisteredOwner>
      <RegisteredOrganization>%HDTOrgName%</RegisteredOrganization>

      <!--
        WITHOUT THIS, THE LOCALE DECIDES, AND en-US MEANS PACIFIC. Microsoft's
        rule is that an unspecified TimeZone is derived from the installed
        language and region: this document sets UserLocale en-US below, which
        gives every machine Pacific Standard Time. MDT has TimeZoneName in
        CustomSettings.ini for exactly this reason.

        THE VALUE COMES FROM THE BOOT IMAGE unless a rule says otherwise.
        Start-HDTDeployment seeds HDTTimeZone from the time zone the Windows PE
        window chose, so one answer covers WinPE's clock and the deployed
        machine's; rules.yaml overrides it per machine through the ordinary
        precedence.
      -->
      <TimeZone>%HDTTimeZone%</TimeZone>
    </component>
  </settings>

  <settings pass="oobeSystem">
    <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64"
               publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
               xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
      <!--
        LANGUAGE AND REGION, AND NOT en-US BECAUSE NOBODY DECIDED IT. These four
        were literals here, so every machine this template deployed came up with
        a US keyboard, a US system locale and a US display language whatever the
        site was - changeable only by hand-editing the XML of every task
        sequence.

        THEY ARE VARIABLES, WHICH IS THE ANSWER MDT GAVE: UILanguage, UserLocale
        and KeyboardLocale are CustomSettings.ini entries there, so one rule sets
        them for a site, a model or a subnet. InputLocale IS MDT's
        KeyboardLocale - the same setting under two names, so HDT keeps one.

        Start-HDTDeployment seeds all four when nothing else resolved them, so a
        share that never mentions them deploys exactly as it did before.
      -->
      <InputLocale>%HDTKeyboardLocale%</InputLocale>
      <SystemLocale>%HDTSystemLocale%</SystemLocale>
      <UILanguage>%HDTUILanguage%</UILanguage>
      <UserLocale>%HDTUserLocale%</UserLocale>
    </component>

    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64"
               publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
               xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
      <OOBE>
        <HideEULAPage>true</HideEULAPage>
        <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
        <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
        <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
        <NetworkLocation>Work</NetworkLocation>
        <ProtectYourPC>3</ProtectYourPC>
      </OOBE>

      <UserAccounts>
        <AdministratorPassword>
          <Value>%HDTAdminPassword%</Value>
          <PlainText>true</PlainText>
        </AdministratorPassword>
      </UserAccounts>

      <!-- DESIGN 4.5.1: the oobeSystem AutoLogon block is what arms the FIRST
           logon of the deployed machine. Every leg after that is armed by
           Set-HDTAutoLogon against the machine's own registry and LSA store. -->
      <AutoLogon>
        <Enabled>true</Enabled>
        <LogonCount>999</LogonCount>
        <Username>Administrator</Username>
        <Password>
          <Value>%HDTAdminPassword%</Value>
          <PlainText>true</PlainText>
        </Password>
      </AutoLogon>
    </component>
  </settings>
</unattend>