Table of Contents
Introduction
Modern Windows provisioning has evolved far beyond the days of traditional imaging and manual setup. Today, with cloud-driven technologies like Windows Autopilot, Intune, and Microsoft Entra ID, organizations can deliver a seamless, secure, and automated device experience — from the very first power-on to the moment a user reaches the desktop.
But modern windows provisioning isn’t a black box — it’s a carefully orchestrated sequence involving firmware, the Windows boot environment, the kernel, and finally the Out-of-Box Experience (OOBE).
If you have ever wondered what happens under the hood during this journey — what processes, security contexts, and orchestration layers transform an unmanaged device fresh from the OEM into a fully managed, enterprise-ready endpoint — this deep dive is for you.
In this series, we’ll unpack the internals of the Windows provisioning pipeline: from UEFI boot and kernel initialization, through OOBE, the classic Autopilot flow, and the Enrollment Status Page (ESP), all the way to the user’s first interactive session. We’ll explore process trees, registry transitions, and security boundaries that make modern provisioning robust and secure, and share practical troubleshooting tips for IT professionals.
Whether you’re an architect, admin, or a curious technologist, this guide will help you understand every critical step in the modern Windows device lifecycle.
For readability, this will be a two-part series.
- Part 1 (this blog post) traces the internals from first power-on to the moment the OOBE shell appears.
- Part 2 (coming soon!) will build on this foundation and follow through the rest of the provisioning journey: Autopilot, Entra ID Device join, MDM enrollment, and ESP milestones—right up to the first desktop.
Phase 1: UEFI OS Boot
User Power’s On the Device → Sequential steps that happen after Power-On
PI (Platform Initialization) boot flow
- SEC (Security) →
- Minimal, early CPU bring‑up.
- Establishes a temporary stack (often Cache‑as‑RAM) for execution.
- Establishes the Root of Trust for Measurement (for platforms that support Measured Boot).
- Hands off to PEI with a basic context (the HOB list, Hand‑Off Blocks).
- PEI (Pre-EFI Initialization) →
- Discovers and initializes permanent system memory (DRAM).
- Initializes memory controller to make RAM usable.
- Loads and runs PEIMs (PEI modules) to prepare the platform for DXE.
- Performs the earliest hardware checks—what many people colloquially lump into “POST,” though UEFI spreads POST duties across PEI/DXE.
- Hands off to DXE IPL with the HOB list.
- DXE (Driver Execution Environment) →
- Loads and runs DXE drivers to initialize the rest of the platform: chipset, ACPI tables, buses (PCIe), storage/network controllers, etc.
- Installs UEFI protocols and connects controllers to drivers.
- Initializes GOP (Graphics Output Protocol) to enable early graphics output.
- Enumerates bootable devices/partitions (finds the EFI System Partition, ESP).
- If Secure Boot is enabled, sets the verification policy (PK/KEK/db/dbx) for later boot apps.
- Provides Boot Services used by UEFI apps (like bootmgfw.efi).
- BDS (Boot Device Selection) →
- Consults UEFI NVRAM boot variables:
- BootOrder, Boot#### entries (each Boot#### points to a device/path/EFI app).
- BootNext (single‑use override if present).
- Selects the first viable boot option and loads the associated EFI application from the ESP.
- For Windows in UEFI mode, this is typically:
- \EFI\Microsoft\Boot\bootmgfw.efi (Windows Boot Manager).
- Fallback path if needed: \EFI\Boot\bootx64.efi (generic).
- If Secure Boot is enabled, the firmware authenticates the EFI app before running it.
- If Measured Boot is enabled, the firmware measures (hashes) components and extends TPM PCRs as it launches them.
- Consults UEFI NVRAM boot variables:
Control passes to Windows Boot Manager (bootmgfw.efi)
Firmware Boot Services continue to remain available at this point (they end later when Windows Boot Loader calls
ExitBootServices().
- Windows Boot Manager (bootmgfw.efi)
- Reads Boot Configuration Data (BCD) (on UEFI, store resides on the ESP under \EFI\Microsoft\Boot\BCD).
- Handles boot policy, chooses winload.efi for normal boot or (winresume.efi for resume from hibernation / Fast Startup).
- Loads Windows OS Loader (winload.efi) from the OS partition.
- Windows OS Loader (winload.efi)
- Verifies component signatures if Secure Boot/Code Integrity policy applies.
- Loads into RAM:
- NT Kernel (ntoskrnl.exe), HAL (hal.dll), and debugging modules (if enabled),
- SYSTEM registry hive from %SystemRoot%\System32\config\SYSTEM,
- Boot‑start drivers (services with Start=0, i.e., SERVICE_BOOT_START).
- If configured, loads Early Launch Anti‑Malware (ELAM) driver so the kernel can classify/allow/block drivers.
- Retrieves the final UEFI memory map and calls ExitBootServices() which terminates EFI Boot Services, thereby freeing up the memory being used so far.
- Transfers control to NT Kernel (ntoskrnl.exe) and terminates itself.

Phase 2: Kernel Initialization
SYSTEM registry hive (HKLM\System\*) is already loaded at this point.
NT Kernel (ntoskrnl.exe)
- Initializes core managers:
- HAL, Memory Manager, Object Manager, Process/Thread Manager, I/O Manager, Cache Manager, Power Manager, PnP Manager, and other required kernel components.
- Enforces Kernel Mode Code Integrity per policy (incl. Secure Boot path).
- Initializes boot‑critical drivers (already loaded by winload.efi).
- Mounts registry hives (SYSTEM already loaded; others as needed).
- Creates the System Idle Process (PID 0), a kernel-created, pseudo-process that keeps the CPU cores busy when they have no ready threads to run.
- Creates the System process (PID 4) to host kernel-mode worker threads.
- Starts Session Manager Subsystem process (smss.exe) as the first user‑mode process (under SYSTEM context) and passes control over to it.

Why I’m not over‑detailing kernel internals here? Because Microsoft doesn’t maintain a single canonical “step‑by‑step” public article for every kernel subsystem startup (that’s Windows Internals territory). Plus, I have it covered already, years back in this blog post of mine, which details the kernel initialization sub-phases.
Phase 3: Session Manager Subsystem → Creation of Session 0 & 1
Session Manager Subsystem process (smss.exe) runs in SYSTEM Context (NT AUTHORITY\SYSTEM privileges) [Parent process: System (PID 4)] and its job is to prepare Windows transition from kernel initialization to the GUI phase, for interactive logon session.
SMSS (smss.exe)
- Reads configuration from HKLM\SYSTEM\CurrentControlSet\Control\Session Manager
- SubSystems (e.g., Windows → CSRSS parameters),
- BootExecute (e.g., autochk.exe on boot volumes),
- KnownDLLs, PagingFiles, environment initialization.
- Creates
- Session 0 (SYSTEM session) → run SYSTEM services and processes that require kernel-mode access.
- Session 1 (first interactive) → run services and processes in the USER mode under the context of the logged-in user, which does not require kernel-mode access. Such processes interact with
- kernel-mode processes through SYSTEM calls exposed by the Windows API.
- other user-mode processes via COM
Why Two Sessions? For security isolation purpose → System services run in Session 0 which is a non-interactive session while user services runs in Session 1 which is interactive. This move to have separate sessions 0 was introduced in Windows Vista to mitigate GUI-based privilege escalation attacks (shatter attacks).
After getting invoked by the NT kernel, Session Manager Subsystem process (smss.exe) creates Session 0 and spawns itself within it to start
- Client/Server Runtime Subsystem process (csrss.exe) → Provides Win32 subsystem support
- Windows Initialization process (wininit.exe), which in its turn starts critical system services:
- Service Control Manager (services.exe)
- Local Session Manager (lsm.exe)
- Local Security Authority Subsystem (lsass.exe)
With Session 0 created and initialized, the Session Manager Subsystem process (smss.exe) then spawns itself to create another instance of smss.exe (child process) to create a new session, Session 1, which is the first interactive user session.
This child instance of smss.exe in Session 1 starts
- Another instance of csrss.exe → Provides Win32 subsystem support for the user-mode session.
- Winlogon process (winlogon.exe) and passes control over to it before terminating itself.
After completing its tasks in Session 1, the child instance of smss.exe terminates itself, thus leaving foundational session 1 processes like csrss.exe and winlogon as orphaned processes. You can see this via Process Explorer (from Sysinternals tools), where such orphaned processes appear either under the System process (PID 4) or as a Root process (no parent).

Which account is used for the very first Session 1 creation?
When smss.exe duplicates itself to create Session 1, it does not require a user account yet. Session 1 is created as an interactive session with no logged-on user initially. The system uses the Local System account (SID: S-1-5-18) to bootstrap processes in Session 1. As and when winlogon.exe gets functional, it then handles the actual user logon process and transitions the session to an interactive user context.
Phase 4: Winlogon → OOBE trigger
Winlogon process (winlogon.exe) runs in SYSTEM Context (NT AUTHORITY\SYSTEM privileges) and is responsible for:
- Displaying logon UI.
- Managing credential providers.
- Registering Secure Attention Sequence (Ctrl+Alt+Del).
- Handling user logon.
- Loading the user profile after successful authentication, which finally cascades to launching the Shell process to start the Desktop.
In addition to the core responsibilities as mentioned above, Winlogon has another important task, and that is to detect the system state to determine if it should show logon UI and proceed with normal interactive logon, or defer the logon process to do a handoff, which eventually cascades into the Out-of-Box Experience setup flow.
winlogon.exe always runs under Local System (S-1-5-18) because it needs full privileges to manage logon and security. It is only after a user logs in, it spawns processes under that user’s SID (e.g., S-1-5-21-<domain>-<user>) thus separating user session from system session.
Windows Setup (setup.exe) records the deployment/provisioning state of the device in %WINDIR%\Setup\State\State.ini and the registry as discussed below.
The value of reg_key ImageState at reg_path HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State can be considered as the primary source of truth for knowing the current device state as it is officially documented by Microsoft.
There’s also the registry keys under reg_path HKLM\SYSTEM\Setup that acts as signal for state detection.
HKLM\SYSTEM\Setup
SystemSetupInProgress→ Indicates whether Windows Setup is currently running.- 1 = Setup in progress,
- 0 = Setup complete
SetupPhase→ Indicates the current phase of the Setup process.- 0 = Not in setup (Normal operation; setup is complete.)
- 1 = WinPE phase (Windows Preinstallation Environment is running.)
- 2 = Offline servicing (Image is being serviced offline, e.g., DISM operations before boot.)
- 3 = Specialize phase (The specialize configuration pass is running during first boot.)
- 4 = Audit mode (System is in audit mode for OEM customization.)
- 5 = OOBE phase (Out-of-Box Experience is running (user setup, region, account creation.)
- 6 = Complete (Setup has finished; system is ready for normal use.)
SetupType→ Indicates the type of setup or boot scenario currently in progress.- 0 = Normal boot (no setup in progress)
- 1 = Mini-setup (used during Sysprep generalization or OOBE)
- 2 = Audit mode (OEM or IT admins customize the image before delivery)
- 3 = Recovery setup (Windows is booting into recovery environment)
- 4 = Upgrade setup (in-place upgrade scenario)
CmdLine→ Specifies the command line that will get executed during the next boot.
Always prefer ImageState as the primary source of truth for knowing the device state as it is officially documented and treat the rest, as in, SetupPhase/SetupType/SystemSetupInProgress as best-effort diagnostic hints. This is because Microsoft does not publish a stable, cross‑version mapping for the integer values for these keys. What is provided above is what is mostly observed in the field.
Winlogon process (winlogon.exe), upon getting invoked, checks the registry to determine the device setup state.
SystemSetupInProgress = 1→ indicates setup still in progress.SetupPhase = 2→ Indicates Offline Servicing pass is completed, next setup phase is Specialize/OOBE.SetupType = 1→ Indicates device is currently booted into Mini-setup flow, OOBE is expected.ImageState = IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE→ Indicates image is generalized, next boot goes to OOBEsystem configuration pass.
These values as above are left by the Windows Setup process (setup.exe) in its last run, and indicate that device is still in setup phase and should continue to OOBE in the next boot.
OEMs typically use
Sysprepwith/generalizeand/oobebefore shipping the device. This puts the image straight intoIMAGE_STATE_GENERALIZE_RESEAL_TO_OOBEstate, meaning the next boot goes straight into OOBE, not Specialize. This is because, the Specialize config pass is designed for applying hardware-specific configs and unattended settings. But OEMs already inject drivers and device-specific configurations during their factory process with the expectation that end-user personalization and provisioning will happen during OOBE manually or via a provisioning package, and not specialize pass. This is also true for vanilla images downloaded from Microsoft.
If SystemSetupInProgress != 0 and/or SetupPhase = {1..5} → Setup/OOBE is in progress; Winlogon will defer logon and execute CmdLine.
If SystemSetupInProgress = 0 and SetupPhase = 0 or 6 → Winlogon will continue with normal interactive logon.
If SetupType = 1 (mini‑setup) and ImageState = IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE → Indicates next boot should go straight to OOBE (OEM generalized images).
CmdLine should typically contain "oobe\windeploy.exe" (sometimes with parameters) as value. If it’s missing/incorrect while setup flags indicate “in progress,” the device can stall or loop pre‑OOBE.
Winlogon process (winlogon.exe) picks up device setup is still in progress and as observed in setup logs, defers execution of interactive logon UI and instead executes the command as specified in the CmdLine key, usually pointing to oobe\windeploy.exe which is the entry point to the oobeSystem config pass and passes control over to it.
Upon getting invoked by winlogon.exe, windeploy.exe also runs with SYSTEM privileges as inherited from winlogon.exe and continues with the same throughout its lifetime, staying alive as the SYSTEM‑context orchestrator for the OOBE throughout.
Windows Deployment process (windeploy.exe) upon getting initialized then checks the same registry flags again to confirm the device state and starts execution of oobeSystem config pass.
First, it checks for the presence of an answer file to drive the config pass. If not found, it starts the normal OOBE setup flow as below.
- Updates reg_key
SetupPhase = 2toSetupPhase = 5[Indicates system is in OOBE phase] underHKLM\SYSTEM\Setup - Creates reg_key
OOBEInProgress = 1[Indicates OOBE is running] underHKLM\SYSTEM\Setup - launches oobeldr.exe which in its turn invokes msoobe.exe and passes control over to it.
Microsoft Out-Of-Box Experience process (msoobe.exe) is the primary executable for OOBE. It works by utilizing the provisioning logic as implemented via the Windows Provisioning Runtime framework. During the OOBE flow, it is responsible for
- Account creation.
- Region and language settings.
- Finalizing setup.
- Clearing all registry flags and command-line arguments after successful completion of OOBE.

Upon getting invoked, msoobe.exe also runs with SYSTEM privileges as inherited from
windeploy.exe → oobeldr.exebut later gets re-spawned under the context ofdefaultuser0to drive the rest of the OOBE.
The Windows provisioning runtime is documented functionally (how/when packages apply), but Microsoft doesn’t publish a DLL‑by‑DLL list. In practice, Microsoft mostly references
provengine.dllas the core provisioning engine library for Windows, supporting modern windows provisioning scenarios.
The sequence —
windeploy.exe → oobeldr.exe → msoobe.exe— represents the core flow of Windows provisioning during OOBE (Out-of-Box Experience). This chain is critical for modern provisioning scenarios like Autopilot, where these processes integrate with cloud-based configuration and policy application.
Phase 5: Creation of DefaultUser0 & context switching
With control now with Microsoft Out-Of-Box Experience process (msoobe.exe), by utilizing provisioning logic as in provengine.dll, initiates the creation of a temporary placeholder account to run the next phases of OOBE to complete the device first-boot setup before an actual user account can be logged in to the system.
The temporary account in context here → defaultuser0
As mentioned above, defaultuser0 acts as a temporary placeholder account and is not a real user account. It gets created from the Default profile template located in C:\Users\Default. It is not interactive, has no password (blank password) and is marked as disabled after setup completes, to be subjected to cleanup.
Provisioning flow of the defaultuser0 account is explained below.
As msoobe.exe triggers the account provisioning
- The system creates
defaultuser0in the SAM database with a random SID. - The profile folder is generated as
C:\Users\defaultuser0based on the Default profile. - Registry keys under
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<SID>get created for this account.
With the account provisioned, it is Winlogon that is then responsible for getting the logon session created.
For defaultuser0, there is no interactive logon. Instead, Winlogon triggers a system logon (empty password).
- Winlogon calls LSASS for the logon request. [LsaLogonUser]
- LSASS upon receiving the logon request, checks the SAM database for defaultuser0 and validates the logon credentials (usually blank password).
- LSASS creates a logon session and generates:
- Access Token for defaultuser0.
- Links the token to the new session ID.
- Sends the token back to Winlogon.
- Winlogon uses the token returned by LSASS to create the interactive user session for the defaultuser0 account and then spawns msoobe.exe in that new user session [
CreateProcessAsUser] to complete the OOBE setup flow.
The visual OOBE thus inherits the same privileges as of defaultuser0 and is then associated with Winsta0 (interactive window station for Session 1).The session is marked as special setup session, not a normal interactive user session.
defaultUser0 acts like a local account with Administrator privileges, but NOT identical to SYSTEM; it operates under user-mode with elevated privilege, enough to ensure that the provisioning tasks prior to having the actual user account provisioned can run and complete.
This is a design choice by Microsoft to enforce the principle of least privilege during setup, as it ensures OOBE UI runs in the interactive desktop environment but under the context of a non-SYSTEM account for security isolation to prevent exposing SYSTEM privileges to the UI layer.
Why this design choice?
Security: SYSTEM is too privileged for UI interaction; switching to defaultuser0 reduces risk.
Reliability: Ensures setup tasks run in a controlled environment before user personalization.
Cleanup: Temporary accounts like defaultuser0 prevent clutter and reduce attack surface.
How to do the trace yourself:
- Event Viewer: Windows Logs → Security log → Look for Event ID 4624: Logon event of Logon Type 2 = Interactive/ Unlock with Account Name = defaultuser0 around the time OOBE pivots to UI. You should see the Logon ID/LUID that corresponds to the token LSASS created for the session. Because this context carries admin‑equivalent rights during setup, you will often also see Event ID 4672 “Special privileges assigned to new logon” correlated by the same Logon ID.
- Procmon: Run with filters like:
- Process Name is winlogon.exe OR lsass.exe
- Operation is Process Create OR Path contains \msoobe.exe
- Optionally enable Stack capture to see calls resolving into CreateProcessAsUser code paths.
Around the time OOBE pivots to UI, you’ll catch CreateProcessAsUser from winlogon.exe and the token duplication/creation activity in lsass.exe
Phase 6: Start of Interactive Shell & OOBE UI Rendering
With the OOBE now spawned under the defaultuser0 account, marks the point when the interactive GUI phase begins.
The provisioning runtime (provengine.dll) makes msoobe.exe to spin up the OOBE shell container (OobeShellHost.exe), which in turn hosts and launches the UWP system app CloudExperienceHost to render the OOBE experience.
OobeShellHost.exe
- Initializes the shell environment for setup tasks.
- Hosts the OOBE UI container.
- Launches and hosts CloudExperienceHost for UI rendering.
OobeShellHost triggering CloudExperienceHost can be treated as the beginning of interactive GUI phase.
CloudExperienceHost (UWP App) [renders and drives the screens we see as “OOBE”]
- Runs inside the OOBE shell context provided by OobeShellHost.exe by leveraging web technologies.
- Based on the OOBE stage, loads different webapps (HTML/JS components) to render the different OOBE screens and carry out the OOBE setup.
Historically, CHE used legacy EdgeHTML/WWAHost in older builds; but with recent builds, we have seen Windows is moving embedded web experiences toward WebView2.
Some example webapps and their functions:
- FireFirstOobeWebAppVisibleEvent → First Windows Animation
- OobeNetworkLogging → Checks for network connectivity and displays the network selection OOBE screen if no internet connectivity is detected.
CloudExperienceHost, upon launch, starts to render the initial setup screens that include the OOBE welcome graphics to the Region, Language, and Keyboard layout setup screens.

How CloudExperienceHost renders UI?
It combines local XAML resources (layout/styling) with HTML/JavaScript webapps for dynamic flows. The webapps live under the SystemApps package path and are loaded based on the current OOBE stage. On disk you’ll see content under:
C:\Windows\SystemApps\Microsoft.Windows.CloudExperienceHost_cw5n1h2txyewy\*

How to do the trace yourself:
- Event Viewer: Navigate to Applications and Services Logs → Microsoft → Windows → Shell-Core → Operational. This log records CloudExperienceHost web app activity—page navigations, Autopilot steps, and reboot decisions (e.g., CommercialOOBE_ESP entries and DeviceSetup.RebootCoalescing). It’s the best place to connect what users saw with the JS/flow behind OOBE pages.
Phase 7: OOBE Decision Pivot → Local vs Online Provisioning
During this phase of OOBE, Windows checks:
- Is there an active network connection?
- Is offline provisioning allowed?
Historically, if there was no network connection available during this stage, Windows allowed to proceed with offline provisioning, creating a local account without internet. But with recent builds, we have seen that Microsoft has been actively moving away from offline OOBE for consumer and enterprise devices.
MS official guidance makes network mandatory on Home SKUs. It has also tightened several known bypass paths in current Insider/24H2/25H2 branches (e.g., removal of OOBE\BYPASSNRO, blocking ms‑cxh:localonly) for Pro/Ent SKUs, enforcing online provisioning flow, so you can either use
- Microsoft Account (MSA) for consumer setup, or
- Work or School Account (Entra ID) for enterprise/education setup.
But in any of the above cases, it requires the device to have an active internet connectivity!
To be continued…
Modern Windows provisioning is a pipeline, not a mystery.
From UEFI through Winlogon’s decision point and into OOBE, each stage leaves reliable artifacts—process trees, registry values, and logs — that you can trace and troubleshoot.
If you’ve read this far, you now have a working mental model of how Windows gets from UEFI to OOBE—and, just as importantly, where to observe it.
What’s up next in Part 2?
We’ll pick up right where we left off → from the first OOBE screens through the classic Autopilot flow, diving into the details of profile retrieval, Microsoft Entra ID join, MDM enrollment, ESP phases (device and user), app and policy sequencing, and finally, the hand‑off to the desktop shell.
By the end, you’ll understand every critical step that turns a fresh device into a fully managed, enterprise-ready endpoint.
Stay tuned—the next part is where the real orchestration magic happens!