Solved Automated Windows 11 installation with post-installation script


HaRD

Member
Local time
3:23 AM
Posts
10
Visit site
OS
Windows 10
Hello everyone,
I am going at this already for almost a week and I am stuck at this point.

As the topic title suggests, I am attempting to create completely zero-touch Windows 11 Enterprise installation; tThrough autounattend.xml answer file I've managed to automate W11 installation itself; that's fine, works as intended. However, my aim is little more zero-touch installation at this point, as I would like to run custom script for driver installation & windows updates as well - basically, I need to run custom script right after completed system installation, where OS boots into OOBE. Currently I am doing that manually in OOBE via Shift + F10 via command prompt - surely there must be a way to skip this and completely automate this step?

Due to the hardware which is being installed being later put through Autopilot and in being in enterprise, I am quite limited at the options available to me.

Tried:
- adding this as part of answer file; seems like this way it will work only AFTER the user logs in, or after OOBE and before user logon; this does not works for me, as I need to prep the devices before user logon
- looked at solutions in this topic: Start a powershell script at the end of Windows 10 installation? - does not work for me as well; 1. solution - SetupComplete.cmd - does not work after clean OS installation from VLSC ISO image USB media; would work after logon. 2. solution - via unattend.xml - same issue; works only after sysprep, not out of the box clean installation. 3. solution - same.

I have worked out how to copy the scripts I need from installation media thanks to this guide $OEM$ folders, but executing them AFTER setup reboot in OOBE - that seems to be challenge.

So - stuck at this point.

Does anyone have working solution for this? Also, autounattended.xml I am currently using below:

Code:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>cs-CZ</UILanguage>
            </SetupUILanguage>
            <InputLocale>0405:00000405</InputLocale>
            <SystemLocale>cs-CZ</SystemLocale>
            <UILanguage>cs-CZ</UILanguage>
            <UserLocale>cs-CZ</UserLocale>
            <UILanguageFallback>en-US</UILanguageFallback>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Size>1024</Size>
                            <Type>Primary</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>2</Order>
                            <Size>100</Size>
                            <Type>EFI</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>3</Order>
                            <Size>16</Size>
                            <Type>MSR</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Extend>true</Extend>
                            <Order>4</Order>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Format>NTFS</Format>
                            <Label>WinRE</Label>
                            <Order>1</Order>
                            <PartitionID>1</PartitionID>
                            <TypeID>DE94BBA4-06D1-4D40-A16A-BFD50179D6AC</TypeID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Format>FAT32</Format>
                            <Label>System</Label>
                            <Order>2</Order>
                            <PartitionID>2</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Order>3</Order>
                            <PartitionID>3</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Format>NTFS</Format>
                            <Label>Windows</Label>
                            <Letter>C</Letter>
                            <Order>4</Order>
                            <PartitionID>4</PartitionID>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <WillWipeDisk>true</WillWipeDisk>
                    <DiskID>0</DiskID>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>4</PartitionID>
                    </InstallTo>
                </OSImage>
            </ImageInstall>
            <UserData>
                <AcceptEula>true</AcceptEula>
                <ProductKey>
                    <Key>NPPR9-FWDCX-D2C8J-H872K-2YT43</Key>
                    <WillShowUI>OnError</WillShowUI>
                </ProductKey>
            </UserData>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim:d:/iso_files/sources/install.wim#Windows 11 Enterprise" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>
 
Windows Build/Version
Windows 11 23H2

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender

My Computer

System One

  • OS
    Microsoft Windows 11 Home
    Computer type
    PC/Desktop
    Manufacturer/Model
    MSI MS-7D98
    CPU
    Intel Core i5-13490F
    Motherboard
    MSI B760 GAMING PLUS WIFI
    Memory
    2 x 16 Patriot Memory (PDP Systems) PSD516G560081
    Graphics Card(s)
    GIGABYTE GeForce RTX 4070 WINDFORCE OC 12G (GV-N4070WF3OC-12GD)
    Sound Card
    Bluetooth Аудио
    Monitor(s) Displays
    INNOCN 15K1F
    Screen Resolution
    1920 x 1080
    Hard Drives
    WD_BLACK SN770 250GB
    KINGSTON SNV2S1000G (ELFK0S.6)
    PSU
    Thermaltake Toughpower GF3 1000W
    Case
    CG560 - DeepCool
    Cooling
    ID-COOLING SE-224-XTS / 2 x 140Mm Fan - rear and top; 3 x 120Mm - front
    Keyboard
    Corsair K70 RGB TKL
    Mouse
    Corsair KATAR PRO XT
    Internet Speed
    100 Mbps
    Browser
    Firefox
    Antivirus
    Microsoft Defender Antivirus
    Other Info
    https://www.userbenchmark.com/UserRun/66553205
The normal sequence for Windows Post-Setup:
- Exit specialize pass, and run OOBE​
- Run C:\Windows\Setup\Scripts\SetupComplete.cmd, except when Windows finds an OEM license key and it's skipped entirely​
- Begin user provisioning for the first logon user​
- Run RunOnce or Run registry tasks​

SetupComplete.cmd would be ideal for you, it's right after OOBE but before any user profiles are provisioned. But the problem is Windows deliberately skips SetupComplete when it detects an OEM setup.

So you insert your own call to SetupComplete using the PostOobe reg key. This is the same thing as running "setup.exe /PostOOBE C:\path\script.cmd" from WinPE.

Copy this XML to your autounattend.xml:
XML:
        <settings pass="specialize">
                <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                        <RunSynchronous>
                                <RunSynchronousCommand wcm:action="add">
                                        <Order>1</Order>
                                        <Path>reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd /c C:\Windows\Setup\Scripts\SetupComplete.cmd & exit /b 0 " /f</Path>
                                </RunSynchronousCommand>
                        </RunSynchronous>
                </component>
        </settings>

If you're using WSIM, just add a specialize pass command:
Code:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd /c C:\Windows\Setup\Scripts\SetupComplete.cmd & exit /b 0 " /f
 

My Computer

System One

  • OS
    Windows 7
@garlin: Thank you, that looks promising - will look it over!
 

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender
Christoph Schneegan's autounattend generator will insert scripts or commands during the specialize phase. This may accomplish what you need, it's simply a matter of timing. When do you need to make a change? Is it too early or too late for what is required?

For driver installation, specialize pass is better because you can schedule a reboot, or expect a reboot to eventually happen.
For user related settings, specialize is too early because OOBE will force locale and other settings to the Default user's profile. PostOOBE is better for that.
 

My Computer

System One

  • OS
    Windows 7
The Schneegan's generator is certainly great tool, but in my opinion it creates a lot of unnecessary things, for which there is not "keep system defaults" option - that is one thing I really do not like on this tool, at least in the case of my use case.

As part of the timing - I need the script to run precisely after installation ends and system reboots into OOBE; script is installing drivers AND system updates from online sources (basically it is forced Windows Update script).

That script looks like this:

Powershell:
Get-WmiObject -Class Win32_OperatingSystem | Where-Object { if ($_.Caption -eq "Microsoft Windows 11 Enterprise") { Write-Host -ForegroundColor Green $_.Caption} else { Write-Host -ForegroundColor Red $_.Caption }}
$Logfile = "$env:SystemDrive\Drivers\Driver_Update_Script.log"
function Write-Log
{
    Param ([string]$LogString)
    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    $LogMessage = "$Stamp $LogString"
    Add-content $LogFile -value $LogMessage -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
}

#Create C:\Drivers folder
if(-not(Test-Path "$env:SystemDrive\Drivers" -PathType Container))
{
    New-Item -Path "$env:SystemDrive\Drivers" -ItemType directory -Force -ErrorAction SilentlyContinue
    Write-Log "Created $env:SystemDrive\Drivers folder"
}

#Get current location of script
$CurrentPath = (Get-Location -PSProvider 'FileSystem').Path
Write-Log "Current File Directory Path - $CurrentPath"

#Copy PSWindowsupdate folder to C:\Program Files\WindowsPowerShell\Modules folder
$DestinationPath = "$env:ProgramFiles\WindowsPowerShell\Modules"
if(Test-Path "$DestinationPath" -PathType Container)
{
    Write-Log "Copy '$CurrentPath\PSWindowsupdate' folder to $DestinationPath folder"
    Copy-Item -Path "$CurrentPath\PSWindowsupdate" -Destination $DestinationPath -recurse -Force -ErrorAction  SilentlyContinue
}

#Install drivers
try
{
    Write-Log "Starting Driver Installation"
   
    Install-WindowsUpdate -Install -AcceptAll -UpdateType Software -MicrosoftUpdate -ForceDownload -ForceInstall -IgnoreReboot -ErrorAction SilentlyContinue | Out-File "C:\Drivers\Drivers_Install_1_$(get-date -f dd-MM-yyyy).log" -Force
    Install-WindowsUpdate -Install -AcceptAll -UpdateType Driver -MicrosoftUpdate -ForceDownload -ForceInstall -IgnoreReboot -ErrorAction SilentlyContinue | Out-File "C:\Drivers\Drivers_Install_2_$(get-date -f dd-MM-yyyy).log" -Force
    Install-WindowsUpdate -Install -AcceptAll -UpdateType Driver -MicrosoftUpdate -ForceDownload -ForceInstall -IgnoreReboot -ErrorAction SilentlyContinue | Out-File "C:\Drivers\Drivers_Install_3_$(get-date -f dd-MM-yyyy).log" -Force
    Write-Log "Driver Installation Successfull"
    restart-computer
}
catch
{
    $Err = $_.Exception.ErrorCode
    Write-Log "Driver Installation ends with Errorcode: $Err"
}

#Restart in 1min
Write-Log "Restart machine in 1 minute"

If there is a better way to implement it, I would not really object again it - just did not figure out a better way yet.
 

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender
Just tried to generate answer file via Schneegan's tool just to see if I missed something; seems like it does work?

XML:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
    <!--https://schneegans.de/windows/unattend-generator/?LanguageMode=Unattended&UILanguage=cs-CZ&GeoLocation=75&Locale=cs-CZ&Keyboard=00000405&ProcessorArchitecture=amd64&ComputerNameMode=Random&TimeZoneMode=Implicit&PartitionMode=Unattended&PartitionLayout=GPT&EspSize=300&RecoveryMode=Partition&RecoverySize=1000&WindowsEditionMode=Interactive&UserAccountMode=Interactive&PasswordExpirationMode=Default&LockoutMode=Default&HideFiles=Hidden&WifiMode=Interactive&ExpressSettings=DisableAll&SystemScript0=reg+add+%22HKEY_LOCAL_MACHINE%5CSYSTEM%5CSetup%5CFirstBoot%5CPostOobe%22+%2Fv+%2200%22+%2Ft+REG_SZ+%2Fd+%22cmd+%2Fc+C%3A%5CWindows%5CSetup%5CScripts%5CSetupComplete.cmd+%26+exit+%2Fb+0+%22+%2Ff&SystemScriptType0=Cmd&WdacMode=Skip-->
    <settings pass="offlineServicing"></settings>
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
            <SetupUILanguage>
                <UILanguage>cs-CZ</UILanguage>
            </SetupUILanguage>
            <InputLocale>0405:00000405</InputLocale>
            <SystemLocale>cs-CZ</SystemLocale>
            <UILanguage>cs-CZ</UILanguage>
            <UserLocale>cs-CZ</UserLocale>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
            <ImageInstall>
                <OSImage>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>3</PartitionID>
                    </InstallTo>
                </OSImage>
            </ImageInstall>
            <UserData>
                <ProductKey>
                    <Key>NPPR9-FWDCX-D2C8J-H872K-2YT43</Key>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
            </UserData>
            <RunSynchronous>
                <RunSynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo SELECT DISK=0"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>2</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo CLEAN"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>3</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo CONVERT GPT"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>4</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo CREATE PARTITION EFI SIZE=300"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>5</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo FORMAT QUICK FS=FAT32 LABEL="System""</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>6</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo CREATE PARTITION MSR SIZE=16"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>7</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo CREATE PARTITION PRIMARY"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>8</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo SHRINK MINIMUM=1000"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>9</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo FORMAT QUICK FS=NTFS LABEL="Windows""</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>10</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo CREATE PARTITION PRIMARY"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>11</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo FORMAT QUICK FS=NTFS LABEL="Recovery""</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>12</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo SET ID="de94bba4-06d1-4d40-a16a-bfd50179d6ac""</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>13</Order>
                    <Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" echo GPT ATTRIBUTES=0x8000000000000001"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>14</Order>
                    <Path>cmd.exe /c "diskpart.exe /s "X:\diskpart.txt" &gt;&gt;"X:\diskpart.log" || ( type "X:\diskpart.log" &amp; echo diskpart encountered an error. &amp; pause &amp; exit /b 1 )"</Path>
                </RunSynchronousCommand>
            </RunSynchronous>
        </component>
    </settings>
    <settings pass="generalize"></settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
            <RunSynchronous>
                <RunSynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Path>powershell.exe -NoProfile -Command "$xml = [xml]::new(); $xml.Load('C:\Windows\Panther\unattend.xml'); $sb = [scriptblock]::Create( $xml.unattend.Extensions.ExtractScript ); Invoke-Command -ScriptBlock $sb -ArgumentList $xml;"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>2</Order>
                    <Path>cmd.exe /c "C:\Windows\Setup\Scripts\unattend-01.cmd &gt;&gt;"C:\Windows\Setup\Scripts\unattend-01.log" 2&gt;&amp;1"</Path>
                </RunSynchronousCommand>
            </RunSynchronous>
        </component>
    </settings>
    <settings pass="auditSystem"></settings>
    <settings pass="auditUser"></settings>
    <settings pass="oobeSystem">
        <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
            <InputLocale>0405:00000405</InputLocale>
            <SystemLocale>cs-CZ</SystemLocale>
            <UILanguage>cs-CZ</UILanguage>
            <UserLocale>cs-CZ</UserLocale>
        </component>
        <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
            <OOBE>
                <ProtectYourPC>3</ProtectYourPC>
                <HideEULAPage>true</HideEULAPage>
                <HideWirelessSetupInOOBE>false</HideWirelessSetupInOOBE>
            </OOBE>
        </component>
    </settings>
    <Extensions xmlns="https://schneegans.de/windows/unattend-generator/">
        <ExtractScript>
param(
    [xml] $Document
);

$scriptsDir = 'C:\Windows\Setup\Scripts\';
foreach( $file in $Document.unattend.Extensions.File ) {
    $path = [System.Environment]::ExpandEnvironmentVariables(
        $file.GetAttribute( 'path' )
    );
    if( $path.StartsWith( $scriptsDir ) ) {
        mkdir -Path $scriptsDir -ErrorAction 'SilentlyContinue';
    }
    $encoding = switch( [System.IO.Path]::GetExtension( $path ) ) {
        { $_ -in '.ps1', '.xml' } { [System.Text.Encoding]::UTF8; }
        { $_ -in '.reg', '.vbs', '.js' } { [System.Text.UnicodeEncoding]::new( $false, $true ); }
        default { [System.Text.Encoding]::Default; }
    };
    [System.IO.File]::WriteAllBytes( $path, ( $encoding.GetPreamble() + $encoding.GetBytes( $file.InnerText.Trim() ) ) );
}
        </ExtractScript>
        <File path="C:\Windows\Setup\Scripts\unattend-01.cmd">
reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd /c C:\Windows\Setup\Scripts\SetupComplete.cmd &amp; exit /b 0 " /f
        </File>
    </Extensions>
</unattend>

Currently; trying my own autounattend.xml with your suggestion:

XML:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>cs-CZ</UILanguage>
            </SetupUILanguage>
            <InputLocale>0405:00000405</InputLocale>
            <SystemLocale>cs-CZ</SystemLocale>
            <UILanguage>cs-CZ</UILanguage>
            <UserLocale>cs-CZ</UserLocale>
            <UILanguageFallback>en-US</UILanguageFallback>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Size>1024</Size>
                            <Type>Primary</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>2</Order>
                            <Size>100</Size>
                            <Type>EFI</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>3</Order>
                            <Size>16</Size>
                            <Type>MSR</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Extend>true</Extend>
                            <Order>4</Order>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Format>NTFS</Format>
                            <Label>WinRE</Label>
                            <Order>1</Order>
                            <PartitionID>1</PartitionID>
                            <TypeID>DE94BBA4-06D1-4D40-A16A-BFD50179D6AC</TypeID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Format>FAT32</Format>
                            <Label>System</Label>
                            <Order>2</Order>
                            <PartitionID>2</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Order>3</Order>
                            <PartitionID>3</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Format>NTFS</Format>
                            <Label>Windows</Label>
                            <Letter>C</Letter>
                            <Order>4</Order>
                            <PartitionID>4</PartitionID>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <WillWipeDisk>true</WillWipeDisk>
                    <DiskID>0</DiskID>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>4</PartitionID>
                    </InstallTo>
                </OSImage>
            </ImageInstall>
            <UserData>
                <AcceptEula>true</AcceptEula>
                <ProductKey>
                    <Key>NPPR9-FWDCX-D2C8J-H872K-2YT43</Key>
                    <WillShowUI>OnError</WillShowUI>
                </ProductKey>
            </UserData>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <RunSynchronous>
                <RunSynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Path>reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd.exe /c C:\Windows\Setup\Scripts\SetupComplete.cmd & exit /b 0 " /f</Path>
                </RunSynchronousCommand>
            </RunSynchronous>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim:d:/iso_files/sources/install.wim#Windows 11 Enterprise" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>

Hopefully this will do the trick!
 

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender
I hate when people echo diskpart commands, one line at a time...

The only part you would modify is the "shrink minimum=800".
Code:
                                <RunSynchronousCommand wcm:action="add">
                                        <Order>1</Order>
                                        <Description>Create diskpart script, Recovery Partition (800 MB)</Description>
                                        <Path>cmd /c @echo off &amp; (echo select disk 0 &amp; echo clean &amp; echo convert gpt &amp; echo create part efi size=260 &amp; echo format quick fs=fat32 label="System" &amp; echo create part msr size=16) &gt; X:\UEFI.txt</Path>
                                </RunSynchronousCommand>
                                <RunSynchronousCommand wcm:action="add">
                                        <Order>2</Order>
                                        <Path>cmd /c @echo off &amp; (echo create part primary &amp; echo shrink minimum=800 &amp; echo format quick fs=ntfs label="Windows" &amp; echo create part primary &amp; echo format quick fs=ntfs label="Recovery") &gt;&gt; X:\UEFI.txt</Path>
                                </RunSynchronousCommand>
                                <RunSynchronousCommand wcm:action="add">
                                        <Order>3</Order>
                                        <Path>cmd /c (@echo off &amp; (echo set id=de94bba4-06d1-4d40-a16a-bfd50179d6ac &amp; echo gpt attributes=0x8000000000000001) &gt;&gt; X:\UEFI.txt) &amp; diskpart /s X:\UEFI.txt</Path>
                                </RunSynchronousCommand>
 

My Computer

System One

  • OS
    Windows 7
Hmmm...

For whatever reasons Schneegans answer file DOES work, while mine does not. What the hell did I do wrong?
If Schneegans answer file would not skip in the OOBE the language and keyboard layout selection, it would be perfect!

... as for echo diskpart commands - it's not like we are writing that code by hand (at least I do not).
 

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender
My bad. You got to escape the & with &amp; in autounattend.xml.

Schneegan is hiding raw text inside an XML block which gets away with literals (which is handy if you got complicated expressions and don't want to waste a half hour escaping them).
Code:
<Path>reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd.exe /c C:\Windows\Setup\Scripts\SetupComplete.cmd &amp; exit /b 0" /f</Path>
 

My Computer

System One

  • OS
    Windows 7
If you want borrow his script extension without resorting to his site:
Code:
    <settings pass="specialize">
        <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <RunSynchronous>
                <RunSynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Description>Copied from Schneegan</Description>
                    <Path>powershell -NoProfile -Command "$xml = [xml]::new(); $xml.Load('C:\Windows\Panther\unattend.xml'); $sb = [scriptblock]::Create( $xml.unattend.Extensions.ExtractScript ); Invoke-Command -ScriptBlock $sb -ArgumentList $xml;"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>2</Order>
                    <Path>reg import "C:\Windows\Setup\Scripts\ReservedStorage.reg"</Path>
                </RunSynchronousCommand>
                <RunSynchronousCommand wcm:action="add">
                    <Order>3</Order>
                    <Path>cmd "/c C:\Windows\Setup\Scripts\RemoveStore_Task.bat &gt; C:\Windows\Setup\Scripts\RemoveStore_Task.log 2&gt;&amp;1"</Path>
                </RunSynchronousCommand>
            </RunSynchronous>
        </component>
    </settings>
    <Extensions xmlns="https://schneegans.de/windows/unattend-generator/">
        <ExtractScript>
param(
    [xml] $Document
);

$scriptsDir = 'C:\Windows\Setup\Scripts\';
foreach( $file in $Document.unattend.Extensions.File ) {
    $path = [System.Environment]::ExpandEnvironmentVariables(
        $file.GetAttribute( 'path' )
    );
    if( $path.StartsWith( $scriptsDir ) ) {
        mkdir -Path $scriptsDir -ErrorAction 'SilentlyContinue';
    }
    $encoding = switch( [System.IO.Path]::GetExtension( $path ) ) {
        { $_ -in '.ps1', '.xml' } { [System.Text.Encoding]::UTF8; }
        { $_ -in '.reg', '.vbs', '.js' } { [System.Text.UnicodeEncoding]::new( $false, $true ); }
        default { [System.Text.Encoding]::Default; }
    };
    [System.IO.File]::WriteAllBytes( $path, ( $encoding.GetPreamble() + $encoding.GetBytes( $file.InnerText.Trim() ) ) );
}
        </ExtractScript>
        <File path="C:\Windows\Setup\README.txt">
Hello world.

        </File>
        <File path="C:\Windows\Setup\Scripts\ReservedStorage.reg">
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager]
"MiscPolicyInfo"=dword:00000002
"PassedPolicy"=dword:00000000
"ShippedWithReserves"=dword:00000000
        </File>
        <File path="C:\Windows\Setup\Scripts\RemoveStore_Task.bat">
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v DisableAutomaticRestartSignOn /t REG_DWORD /d 1 /f
schtasks /create /sc ONLOGON /tn RemoveStoreApp /tr "powershell -nop -C """if (Get-Process StartMenuExperienceHost) { Get-AppxPackage -AllUsers *Store* ^| Remove-AppPackage -AllUsers; Unregister-ScheduledTask RemoveStoreApp -Confirm:$false }"""" /ru SYSTEM /rl HIGHEST /f
        </File>
    </Extensions>
</unattend>
 

My Computer

System One

  • OS
    Windows 7
There's a huge amount if irony that I stumbled across this thread, today, after searing for something different, although related.

I use a PoSH script on a USB drive that has Windows 11 installed on it. Included on that drive is Office, Adobe, a drivers WIM, WiFi Profile XML, etc, all handled by the script, alongside verbose logging to Event Viewer, registry tags, optimisations from VDOT, etc.

In the autounattend.xml I simply call that script during the FirstLogon phase. There's probably a better way to do it, but it works for me. The issue I am facing that bought me here is that the script runs as the logged on user (elevated) and I need it to run as SYSTEM. Partly because I thought I would be clever and move from the perfectly fine and adequate additional Chocolately app installs (7-zip, Azure CLI, VSCode, etc) to WinGet, and I've hit a blocker, which, as I say, can only seemingly be resolved by running the script as SYSTEM.

My solution therefore is to now change the script that autounattend see's to simply "provision.ps1". This contains a script to set my monolithic PS script as a scheduled task, which will then run under SYSTEM, and hopefully resolve my WinGet conundrum.

Anyway, if there's anything useful about what I've done that might work for you, please let me know. Additionally, if there is a better way to run what I have using auditSystem or SetupComplete, I would love to know.
 

My Computer

System One

  • OS
    11
My bad. You got to escape the & with &amp; in autounattend.xml.

Schneegan is hiding raw text inside an XML block which gets away with literals (which is handy if you got complicated expressions and don't want to waste a half hour escaping them).
Code:
<Path>reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd.exe /c C:\Windows\Setup\Scripts\SetupComplete.cmd &amp; exit /b 0" /f</Path>

Thank you for your suggestion; however it still does not work (dang it!). I mean - setup automation does work, however the last part - driver installation via script - does not.

When I lookep differences between my answer file code and Schneegan's site generated code, I noticed that in Schneegan's answer file code it is dynamically generating and processing unattended.xml file in C:\Windows\Panther\ ; that seems to be the only difference, not sure what that answer file does.

@Lucero79: I am afraid that this would not work for me, as I need the device ready for Autopilot and then for user device handover.

So close! Schneegan's file would work nicely if only it would not select language and keyboard layout in OOBE, as I have a few users, who wants different keyboard layout.

Will try to fidle around and copy / paste parts of his code into mine; maybe I will get it running somehow through luck.

Ultimately I will either give up and use other means (cloning + SetupComplete.cmd combo is the most sure way to resolve this, but it means building my own cloning server, which must work via PXE in UEFI mode and Secure Boot enabled, ................... not really way I want to go through).
 

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender
When Setup finds an autounattend.xml, it begins processing and copies a transformed version to C:\Windows\Panther on the system drive so later install phases can read the specialize & OOBEsystem passes.

The reason he looks for the Pather copy is he can't guarantee the drive letter of the USB media after WinPE exits and reboots. So he uses the Panther copy to extract the embedded files or commands, because it's always there. Otherwise you need another script to search through the mounted drives, looking for your USB drive and the original autounattend.xml.

Your script make a bad assumption. Get-Location returns where your script is starting, normally it's the default folder for SYSTEM's profile. Which is "C:\Windows\System32", just like if you opened a CMD shell as Admin.

Did you really intend to use "$PSScriptRoot", which is the path of the running PS script?
 

My Computer

System One

  • OS
    Windows 7
When Setup finds an autounattend.xml, it begins processing and copies a transformed version to C:\Windows\Panther on the system drive so later install phases can read the specialize & OOBEsystem passes.

The reason he looks for the Pather copy is he can't guarantee the drive letter of the USB media after WinPE exits and reboots. So he uses the Panther copy to extract the embedded files or commands, because it's always there. Otherwise you need another script to search through the mounted drives, looking for your USB drive and the original autounattend.xml.

Your script make a bad assumption. Get-Location returns where your script is starting, normally it's the default folder for SYSTEM's profile. Which is "C:\Windows\System32", just like if you opened a CMD shell as Admin.

Did you really intend to use "$PSScriptRoot", which is the path of the running PS script?
Garlin, do these scripts run under SYSTEM context? If so, for my issue, I could probably run the script here.
 

My Computer

System One

  • OS
    11
Your script make a bad assumption. Get-Location returns where your script is starting, normally it's the default folder for SYSTEM's profile. Which is "C:\Windows\System32", just like if you opened a CMD shell as Admin.

Did you really intend to use "$PSScriptRoot", which is the path of the running PS script?
It works like this:

1. SetupComplete.cmd executes script, which has been copied into %WinDir%\Setup\Scripts folder; this script more or less just executes other script (might be not necessary, can cut this middle-man from the chain and just execute from SetupComplete.cmd) like this:

Batch:
Set path=%~dp0
CD /D "%path%"

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -executionpolicy bypass -file .\Driver_Update.ps1

2. Main script launches and does it's thing.

As far as I've checked, it does work as intended otherwise, when launched manually. Unless I missed here something?

\\edit: Now I see it ...
Set path=%~dp0
CD /D "%path%"

That second line - CD /D - this is probably wrong.

Could it really be, that the error is in sight ..? (between chair and keyboard)
 

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender
Oukej, it seems like IT FINALLY WORKS !

The issue was in the end - like always - between chair and keyboard; the middle script launching the main script was the issue. So - I've removed the middle man and have the SetupComplete.cmd launch the main script:

Batch:
Set path=%~dp0
CD "%path%"

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -executionpolicy bypass -file .\Driver_Update.ps1

And this is the final autounattend.xml file that I just used for testing:

XML:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
    <settings pass="windowsPE">
        <component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <SetupUILanguage>
                <UILanguage>cs-CZ</UILanguage>
            </SetupUILanguage>
            <InputLocale>0405:00000405</InputLocale>
            <SystemLocale>cs-CZ</SystemLocale>
            <UILanguage>cs-CZ</UILanguage>
            <UserLocale>cs-CZ</UserLocale>
            <UILanguageFallback>en-US</UILanguageFallback>
        </component>
        <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <DiskConfiguration>
                <Disk wcm:action="add">
                    <CreatePartitions>
                        <CreatePartition wcm:action="add">
                            <Order>1</Order>
                            <Size>1024</Size>
                            <Type>Primary</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>2</Order>
                            <Size>100</Size>
                            <Type>EFI</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Order>3</Order>
                            <Size>16</Size>
                            <Type>MSR</Type>
                        </CreatePartition>
                        <CreatePartition wcm:action="add">
                            <Extend>true</Extend>
                            <Order>4</Order>
                            <Type>Primary</Type>
                        </CreatePartition>
                    </CreatePartitions>
                    <ModifyPartitions>
                        <ModifyPartition wcm:action="add">
                            <Format>NTFS</Format>
                            <Label>WinRE</Label>
                            <Order>1</Order>
                            <PartitionID>1</PartitionID>
                            <TypeID>DE94BBA4-06D1-4D40-A16A-BFD50179D6AC</TypeID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Format>FAT32</Format>
                            <Label>System</Label>
                            <Order>2</Order>
                            <PartitionID>2</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Order>3</Order>
                            <PartitionID>3</PartitionID>
                        </ModifyPartition>
                        <ModifyPartition wcm:action="add">
                            <Format>NTFS</Format>
                            <Label>Windows</Label>
                            <Letter>C</Letter>
                            <Order>4</Order>
                            <PartitionID>4</PartitionID>
                        </ModifyPartition>
                    </ModifyPartitions>
                    <WillWipeDisk>true</WillWipeDisk>
                    <DiskID>0</DiskID>
                </Disk>
            </DiskConfiguration>
            <ImageInstall>
                <OSImage>
                    <InstallTo>
                        <DiskID>0</DiskID>
                        <PartitionID>4</PartitionID>
                    </InstallTo>
                </OSImage>
            </ImageInstall>
            <UserData>
                <AcceptEula>true</AcceptEula>
                <ProductKey>
                    <Key>NPPR9-FWDCX-D2C8J-H872K-2YT43</Key>
                    <WillShowUI>OnError</WillShowUI>
                </ProductKey>
            </UserData>
        </component>
    </settings>
    <settings pass="specialize">
        <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <RunSynchronous>
                <RunSynchronousCommand wcm:action="add">
                    <Order>1</Order>
                    <Path>reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd.exe /c C:\Windows\Setup\Scripts\SetupComplete.cmd &amp; exit /b 0" /f</Path>
                </RunSynchronousCommand>
            </RunSynchronous>
        </component>
    </settings>
    <cpi:offlineImage cpi:source="wim:d:/iso_files/sources/install.wim#Windows 11 Enterprise" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>

The way it works now; setup completes the system installation, reboots and then it hangs on "Just a moment ..." while it downloads all drivers. On my testing laptop it even performed BIOS update! So THAT works as intended!

BIG THANK YOU to @garlin who have provided invaluable insight and advice into this little problem of mine. Garlin - if you ever happen to be around Czech Republic, area close to České Budějovice; you're promised quite a few of Czech beers on me!
 

My Computer

System One

  • OS
    Windows 10
    Computer type
    PC/Desktop
    CPU
    Ryzen 7 5800X3d
    Motherboard
    Gigabyte X570S UD
    Memory
    32 GB
    Graphics Card(s)
    Sapphire AMD Radeon RX 6800 XT NITRO+
    Sound Card
    ASUS Xonar Essence STX II
    Monitor(s) Displays
    2x HP Z27 G2
    Screen Resolution
    1440p
    Hard Drives
    1x Samsung SSD 970 PRO 1 TB, 2x Samsung SSD 830 PRO 128 GB RAID 0, 1x Seagate Barracude 2 TB
    PSU
    Seasonic Prime PX-1000 Platinum
    Case
    Fractal Design XL R2
    Cooling
    Noctua NH-D15 chromax.black
    Internet Speed
    WiFi 100/100
    Browser
    Firefox
    Antivirus
    Windows Defender
Garlin, do these scripts run under SYSTEM context? If so, for my issue, I could probably run the script here.


Command TypeContext
unattend.xml "specialize" pass: RunSynchronousCommandSYSTEM
unattend.xml "specialize" pass: RunSynchronousCommand kludge to create a Scheduled TaskWhoever is the task's owner as defined by "schtasks /create" (SYSTEM? Built-in Administrators Group?)
SetupComplete.cmd (called by Windows natively, or forced from PostOobe reg key)SYSTEM
unattend.xml "OOBEsystem" pass: FirstLogonYou (as Administrator)
RunOnce registry task (as HKLM)SYSTEM
RunOnce registry task (as HKCU)You (as Administrator)

Insert this (corrected) XML code snippet into your autounattend.xml:
Code:
        <settings pass="specialize">
                <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                        <RunSynchronous>
                                <RunSynchronousCommand wcm:action="add">
                                        <Order>1</Order>
                                        <Path>reg add "HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe" /v "00" /t REG_SZ /d "cmd /c C:\Windows\Setup\Scripts\SetupComplete.cmd &amp; exit /b 0 " /f</Path>
                                </RunSynchronousCommand>
                        </RunSynchronous>
                </component>
        </settings>

You can call multiple script or command instances as HKEY_LOCAL_MACHINE\SYSTEM\Setup\FirstBoot\PostOobe\00 or 01, 02, 03...
Normally you only need one run script, but you could have more.
 

My Computer

System One

  • OS
    Windows 7
Back
Top Bottom