Home Breaking out of OOBE

Breaking out of OOBE

Recently I had a need to break out of the OOBE phase of the Windows setup and start a script. This is possible out of the box. You can use the Shift + F10 key combo to open a cmd window.
But that requires interaction from the engineer. And we like automation and set and forget. You could of course use an answer file to auto login and start a script but then the device would need a reset before sending it on to the customer so we had to find an alternative.
So off to Google we go!

Desktop View Furiously Googling insert more witty commentary here

That’s where I ran into a recent Michael Niehaus blog about using AutoHotKey to emulate the Shift + F10 key combo to break out of the OOBE. A few adjustments were needed, Michael was using it to bring a task sequence to the foreground and the OOBE windows title appears to have recently changed from “Microsoft Account” to “Microsoft-account”.

After making the needed adjustments this is what the script looks like:

#Requires AutoHotkey v2.0

WinWait "Microsoft-account"
    Send "+{F10}"

WinWait "Administrator: C:\Windows\system32\cmd.exe"
    pid := WinGetPID()
    ProcessClose pid

Run("powershell -NoExit -ExecutionPolicy Bypass -Command irm autopilot.ms | iex")

WinWait "Autopilot Hash Bootstrap"


First we wait until the OOBE window has been detected, we set focus to it using WinActivate and then we send the Shift + F10 combo. Its important to note that the key combo ONLY works when the OOBE window is in focus.
We don’t have a direct need for the CMD window so we close that. Then we use the Run functionality in AutoHotKey to open a PowerShell terminal and send a command.
For this blog post I’ve used irm autopilot.ms | iex. This loads in a script from a URL and executes it. The internal production version will of course be more customized.
Please do note that we’re telling AutoHotkey to focus on a window titled Autopilot Hash Bootstrap. You will have to fill in a title relevant to your own automation here otherwise the window will not be brought to the foreground.

As mentioned in the Niehaus blog post AutoHotKey provides a utility to wrap the AHK script into an EXE, I did the same. And that’s where we diverge, he used it in a task sequence, but I don’t have a task sequence. My larger goal is to be completely independent of any server infrastructure so I had to find an alternative.

Windows will automatically execute the file SetupComplete.cmd when it reaches the OOBE phase. By default this file is empty so we can do anything we want with it.
Now, I’m doing this in the context of OSDCloud so I’ve hijacked OSDClouds own processes which allows me to execute the following code AFTER installation but BEFORE the reboot to OOBE.

try {
    Invoke-RestMethod -Uri "https://github.com/rvdwegen/OSDCloud/raw/main/PostOOBEBootstrap.exe" -OutFile "C:\OSDCloud\PostOOBEBootstrap.exe"
    $SetupCompleteData = "powershell.exe -command Start-Process -FilePath C:\OSDCloud\PostOOBEBootstrap.exe"
    Set-Content -Path "C:\Windows\Setup\Scripts\SetupComplete.cmd" -Value $SetupCompleteData -Force
} catch {
    throw "$($_.Exception.Message)"

PostOOBEBootstrap.exe is the wrapped AutoHotkey script. First we copy it to the local filesystem of the newly installed machine and then we set the content of SetupComplete.cmd to a command string that will execute the file.

The end result is that we can execute any script we want during OOBE. I should mention that the powershell window will be opened in the SYSTEM context and lack some of the things one would expect in a normal powershell process. For example due to missing files in the user profile (which SYSTEM doesn’t have) we can’t install modules. But that is a problem for another day since this blog has been in a draft state since last year.

I hope this was educational and helpful for those looking automate their way out of tedious repeated user actions. Have a good day and have fun automating!

This post is licensed under CC BY 4.0 by the author.