aunt — Auto Unattend¶
                aunt automates Windows installation with AutoUnattend.xml and reduces image size.
Usage¶
aunt -h shows the help, aunt without argument checks dependencies then shows the help:
usage: aunt [-h] [-aimnqvy] [-e ED] [-k KEY] [-l LANG] [-p NAME] [-s SUF] ISO [FILE] ...
Auto Unattend 0.3
positional arguments:
  ISO                   Windows.iso to be automated
  FILE ...              include custom files and directories
optional arguments:
  -h, --help            show this help message and exit
  -a, --all             flags -mny
  -e ED, --edition ED   Core, CoreN, Professional... not -e: registry
  -i, --inplace         rewrite ISO
  -k KEY, --key KEY     auto-activate... not -k: limited features
  -l LANG, --lang LANG  en-US, fr-FR... not -l: lang.ini
  -m, --microsoft       no Microsoft account
  -n, --network         no network setup
  -p NAME, --pc NAME    computer name... not -p: PC
  -q, --quiet           no output
  -s SUF, --suffix SUF  append to ISO name... not -s: _
  -v, --verbose         detail actions in bash syntax
  -y, --yes             accept license
                    aunt Windows.iso rewrites the bootable UDF *.iso and shows the steps:
extract Windows.iso to _tmp
query EditionID
read lang.ini
read boot.wim
reduce boot.wim
read install.esd
reduce install.esd
write AutoUnattend.xml
write Windows.iso
delete _tmp
                    aunt -v Windows.iso details actions in bash syntax, grep mv rm words are handy for understanding what’s going on, although these actions are written in pure Python:
find dependencies
  C:\Program Files\7-Zip\7z.exe
  C:\Windows\System32\dism.exe
  C:\Program Files\Quix0\oscdimg.exe
extract Windows.iso to _tmp
  7z x -y -o_tmp Windows.iso bootmgr{,.efi} boot\{bcd,bood.sdi,bootfix.bin,etfsboot.com} efi\microsoft\boot\{bcd,efisys.bin} sources\{boot.wim,compres.dll,install.esd,lang.ini,setup.exe}
query EditionID
  reg query 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion' /v EditionID
  = Core
read lang.ini
  grep -Eom1 '^([a-z]{2}-[a-zA-Z]{2}) ' lang.ini
  = fr-fr
read boot.wim
  dism /Get-WimInfo /WimFile:boot.wim
reduce boot.wim
  dism /Export-Image /SourceImageFile:boot.wim /SourceIndex:2 /DestinationImageFile:boot.wim_
  mv boot.wim_ boot.wim
read install.esd
  dism /Get-WimInfo /WimFile:install.esd
reduce install.esd
  dism /Export-Image /SourceImageFile:install.esd /SourceIndex:1 /DestinationImageFile:install.esd_
  mv install.esd_ install.esd
write AutoUnattend.xml
write Windows_.iso
  oscdimg -u2 -bootdata:2#p0,e,b_tmp\boot\etfsboot.com#pEF,e,b_tmp\efi\microsoft\boot\efisys.bin _tmp Windows_.iso
delete _tmp
  rm -r _tmp
                    The dism commands above strips all Windows editions other than the one chosen by the -e option. Without -e assumes that the desired edition is the same as the host’s EditionID.
It is possible to include custom files and directories in ISO:
aunt Windows.iso ExecTI.exe python-3.7.2-amd64.exe
                    -a equals -mny, which generates an AutoUnattend.xml as below:
<?xml encoding="utf-8"?>
<unattend>
    <settings pass="WindowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" ...>
            <UILanguage>en-us</UILanguage>
        </component>
        <component name="Microsoft-Windows-Setup" ...>
            <ImageInstall>
                <OSImage>
                    <InstallFrom>
                        <MetaData>
                            <Key>/IMAGE/INDEX</Key>
                            <Value>1</Value>
                        </MetaData>
                    </InstallFrom>
                </OSImage>
            </ImageInstall>
            <UserData>
                <ProductKey>
                    <Key></Key>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
            </UserData>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-Shell-Setup" ...>
            <ComputerName>PC</ComputerName>
        </component>
    </settings>
    <settings pass="OOBESystem">
        <component name="Microsoft-Windows-International-Core" ...>
            <SystemLocale>en-us</SystemLocale>
        </component>
        <component name="Microsoft-Windows-Shell-Setup" ...>
            <OOBE>
                <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
                <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
            </OOBE>
        </component>
    </settings>
</unattend>
                    Exit status:
0: success 1: missing file 2: missing edition in image file
Screens¶
Hidden screen, --lang or lang.ini sets the language:
 
                Hidden screen:
 
                Hidden screen, --key sets the activation key otherwise continues without a key:
 
                Hidden screen, --edition or host’s EditionID sets the Windows edition:
 
                --yes accepts the license and hides this screen:
 
                Hidden screen, chooses “Custom” installation:
 
                Displayed:
 
  
                3 hidden screens, --lang or lang.ini sets the language:
 
  
  
                --network hides these 2 screens:
 
  
                --microsoft hides these 2 screens:
 
  
                Displayed:
 
  
  
  
  
                Writing HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableFirstLogonAnimation = 0 in install.esd is the only way to hide this animation, <FirstLogonCommands> runs too late:

Tests¶
💿 English x64 💿 French x64 — Home Pro Education [1] — VirtualBox 6 — VMware 15:
| 1809: | November 13, 2018 — Redstone 5 | 
|---|
| [1] | Education edition is Enterprise edition without long-term support |