It's a new hire's first day. IT handed over a laptop still in its box, the plan was "power it on, sign in, go" — that's the entire point of Autopilot. Instead the screen has been sitting on a spinning dial under "Just a moment" for eleven minutes, the new hire is refreshing their personal phone for something to do, and the helpdesk ticket that just landed on your desk says nothing more useful than "laptop broken." It isn't broken. Something specific failed during OOBE or the Enrollment Status Page, and there's almost always a real signature behind it — an Event ID, a HRESULT, or a documented error string. This post is a field guide to the ones that actually show up in real tenants, where they come from, and how to fix them without guessing.
This is not registration, deregistration, or hardware eligibility — that's covered elsewhere. This is what happens after a device is already registered and assigned a profile, and the deployment itself goes wrong during OOBE or ESP.
The problem
"Autopilot is broken" almost always means one of a small number of specific, observable states:
- The device sits at the network/OOBE screen and never gets past it — the Windows Autopilot profile never downloads.
- The device reaches the sign-in screen but errors with Something went wrong and a code like
80180018or0x80180014. - The Enrollment Status Page (ESP) hangs on an app install and either times out or shows Another installation is in progress, please try again later.
- The device signs in fine, but the wrong policies, apps, or wallpaper show up — the assigned Windows Autopilot profile silently didn't apply.
- In the Intune admin center, the device's Windows Autopilot record shows Fix pending or Attention required instead of a clean assigned state.
Each of these has a distinct cause. Treating "Autopilot is stuck" as one problem is exactly why the same ticket gets reopened three times before someone actually reads the event log.
Why it happens
Real Autopilot deployment failures fall into four buckets. Knowing which bucket you're in cuts most of the guesswork out of the fix.
1. Network / identity failures
The device can't reach the Windows Autopilot service, or it reaches it but the tenant match fails. Windows Autopilot downloads its profile as soon as a network connection is available, and again after every reboot — if that download never lands, nothing downstream can happen. The device's registry key HKLM\SOFTWARE\Microsoft\Provisioning\Diagnostics\Autopilot holds the evidence: a value called IsAutopilotDisabled set to 1 means the profile couldn't be downloaded — commonly a firewall, proxy, or captive-portal issue — and TenantMatched set to 0 means the signed-in user's Entra tenant doesn't match the tenant the device was registered against, which forces the user back to the start of OOBE. On the licensing side, users signing in without a valid Intune, EMS, or Microsoft 365 license will see Something went wrong — Can't connect to the URL of your organization's MDM terms of use. — a licensing error, not a network one, despite how it reads.
2. Profile-sync / assignment failures
The device is registered, but the specific profile assignment is broken or hasn't landed yet. This is the category that produces the Event Viewer entries ZtdDeviceIsNotRegistered (Event ID 807), ZtdDeviceHasNoAssignedProfile — Assigned profile does not exist (Event ID 809, meaning the profile that was assigned got deleted without being cleaned up first), and ZtdDeviceHasNoAssignedProfile — No profile assigned to the device, and no default profile found in the tenant (Event ID 815). It's also where you'll see SerialNumberMismatch / ProductKeyIdMismatch (Event ID 908) after a motherboard swap, and the Fix pending / Attention required status that appears after a hardware change, with the exact message: "We've detected a hardware change on this device. We're trying to automatically register the new hardware. You don't need to do anything now; the status will be updated at the next check in with the result."
3. App-timeout / ESP conflicts
The profile applied correctly and the device is trying to configure itself, but the Enrollment Status Page gets stuck waiting on an app install that will never finish. The single most common trigger: mixing line-of-business (LOB) apps and Win32 apps in the same ESP profile. Both install types run through TrustedInstaller, which refuses to run two installs at once — when that happens you get exactly this message on screen: Another installation is in progress, please try again later. A close cousin of this is the Microsoft 365 Click-to-Run install of Office, whose Teams Machine-Wide Installer component runs its own untracked MSI — ESP doesn't monitor that install, so it can silently collide with other Win32 MSI installs running at the same time and cause either one to fail. It's a timing issue, so it won't reproduce on every device.
4. Policy conflicts that block sign-in or force reboots mid-ESP
Certain device-targeted policies are actively incompatible with ESP and will either stall it or break sign-in entirely. Documented offenders include DeviceLock CSP settings like minimum password length or password complexity (breaks kiosk-style autologon during ESP), the AppLocker CSP (triggers an unexpected reboot when applied during ESP), the AutoAdminLogon registry value under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon being forced to 0, the PreferredAadTenantDomainName policy (breaks autologon when it populates DefaultUser0), and Security Baseline settings around UAC elevation prompts and virtualization-based security, which force extra reboots and extra credential prompts mid-ESP. Any of these can look identical to "the device is just stuck."
How to verify
Don't fix blind. Confirm which bucket you're actually in first.
That's the exact path Microsoft's own troubleshooting guidance points to for reading Autopilot's OOBE-time log entries. Event IDs 100/101/103/109/111 are informational — normal profile retrieval. Event IDs 171/172 (with an HRESULT) point at a TPM attestation failure, relevant only to self-deploying mode. Event IDs 807/809/815/908 are the ones worth treating as real incidents.
If IsAutopilotDisabled is 1 or CloudAssignedTenantDomain is blank, the profile never downloaded — go check network/firewall requirements before touching anything else. If TenantMatched is 0, the person signing in used the wrong account or the device is registered to a different tenant than expected.
On Windows 11 user-driven deployments signed in with a Work or School account, there's also a built-in diagnostics page: enable Show app and profile configuration progress and Turn on log collection and diagnostics page for end users on the ESP profile, then on the device press Ctrl+Shift+D during OOBE or select View Diagnostics. It won't work with a personal Microsoft account, and it's Windows 11 + user-driven mode only.
Cannot convert the literal '[DEVICEHASH]' to the expected type 'Edm.Binary' — the device hash is captured as unpadded Base64 but Windows Autopilot expects it padded. If the decode above throws Invalid length for a Base-64 char array or string, add or trade "=" padding characters at the end (max two) until it decodes cleanly, then re-import.The fix
Match the fix to the bucket you confirmed above.
Network / identity — confirm connectivity and licensing first
Re-check firewall/proxy access to the Windows Autopilot networking endpoints, confirm the signing-in user has a valid Intune/EMS/M365 license (this alone fixes the MDM-terms-of-use error), and if a fresh profile needs to be pulled mid-OOBE, force it with Shift+F10 to open a command prompt and run shutdown.exe /r /t 0 to restart immediately.
Profile-sync / assignment — the 0x80180014 unblock walkthrough
- Sign in to the Microsoft Intune admin center.
- Select Devices in the left pane, then under By platform select Windows.
- Under Device onboarding, select Enrollment.
- Under Windows Autopilot, select Devices.
- Find the affected device and select its checkbox.
- In the toolbar, select Unblock device. No success message may appear — that's expected, not a failure.
- Redeploy the Windows Autopilot deployment profile to the device.
If that doesn't clear it, the second known cause is Windows MDM enrollment itself being blocked: go to Devices > Windows > Windows devices > Enrollment > Enrollment options > Device platform restriction, open the relevant restriction, and confirm Windows (MDM) is set to Allow, not Block.
For Event ID 809 (assigned profile no longer exists) or 815 (no profile assigned, no default profile), assign a valid Windows Autopilot deployment profile to the device and re-attempt enrolment. For the hardware-change "Fix pending" state, no manual action is needed unless it persists — if it does, deregister and re-register the device.
App-timeout / ESP conflicts — stop mixing install types in the same ESP window
- Don't target LOB and Win32 apps at the same ESP profile — pick one type for anything that must block ESP.
- Deploy Teams as a standalone Win32 app after Autopilot completes, rather than bundled inside Click-to-Run Office during ESP — or move Office itself to post-deployment.
- If neither is practical, enable Continue anyway for ESP app-install failures so a stalled non-critical app can't block the whole device — some apps may then not install and need to be pushed afterward.
- On Windows 11, consider Windows Autopilot device preparation, which doesn't use ESP at all and therefore doesn't hit this conflict.
Policy conflicts — target users instead of devices where you can
For UAC elevation and virtualization-based-security policies from the Security Baseline, target the policy to a user group instead of a device group so it applies after ESP rather than during it. For password/DeviceLock policies breaking autologon, set them to Not Configured during OOBE or move them to user scope. Confirm AutoAdminLogon hasn't been forced to 0 by an unrelated hardening script, and don't enable PreferredAadTenantDomainName on devices that also need OOBE autologon.
Proof it worked
"It's gone from the error list" is not proof. Microsoft's own device-object behaviour after registration changes depends on prior MDM enrollment history, so the only reliable proof is reading the device's actual state back from Microsoft Graph — not assuming from a portal refresh. That's what the companion script Get-AutopilotDeploymentHealthCheck.ps1 does: for a given serial number, it reads the Windows Autopilot device identity object, the matching Intune managed device, and the Entra device object, and cross-references the profile assignment status, sync detail, and enrollment state against the failure signatures covered above — entirely read-only.
Get-AutopilotDeploymentHealthCheck.ps1 is free and open source. It's a genuinely read-only script — no writes to Autopilot, Intune, or Entra ID.
windowsAutopilotDeviceIdentity, not v1.0. The script calls the beta endpoint explicitly and says so — treat any output from those specific fields as informational, not committed API surface, and re-verify if Microsoft changes it.A clean result looks like: enrollmentState = enrolled, deploymentProfileAssignmentStatus = assignedInSync, and the Intune managed device's enrollmentProfileName matching the Windows Autopilot profile name you expected — not OfflineAutoPilotProfile-<guid>, which would mean the existing-devices JSON profile applied instead of your assigned online profile because the online one timed out.
References
- Windows Autopilot troubleshooting FAQ — Microsoft Learn
- Windows Autopilot Enrollment Status Page — Microsoft Learn
- Windows Autopilot for existing devices — Microsoft Learn
- Set up the Enrollment Status Page — Microsoft Learn
- Troubleshooting Windows device enrollment errors in Intune — Microsoft Learn
- windowsAutopilotDeviceIdentity resource type (beta) — Microsoft Graph