Monday morning, a fleet of forty new laptops goes out to a remote office. By 9:15am the helpdesk queue has fourteen tickets that all say roughly the same thing: "my new laptop is stuck on a blue setup screen and won't let me in." Half of those devices aren't actually stuck — they're two minutes from finishing. The other half genuinely are stuck, on an app that's already sitting on disk, fully installed, doing nothing wrong except failing to report back in time. Nobody at the helpdesk can tell the two groups apart just by looking at the screen, because the Enrollment Status Page shows the same generic spinner for both.
That gap — between what the ESP shows you and what it's actually enforcing — is where almost every "ESP is stuck" ticket comes from. This post walks through what ESP really blocks versus what it just displays, the real difference between the Device Setup and Account Setup phases, why a perfectly installed app can show up as failed, and how to configure a timeout policy that doesn't leave you choosing between users locked out forever or users logging into a half-configured machine.
The problem — a stuck ESP screen tells you almost nothing about what's actually wrong
Here's the trap. A user calls in and says the enrollment status page has been sitting on "Please wait while we set up your device" or "Installing required apps" for twenty minutes. As the admin, you have three genuinely different situations that all look identical from the outside:
- The device is legitimately still working — a Win32 app is 80% through a large install and just needs more time.
- An app the ESP is tracking has actually failed to install, and the device is correctly blocked.
- An app installed successfully, but the ESP never received a timely success signal from it, so it's sitting there reporting the app as failed or still in progress — even though, if you RDP'd into the machine right now, you'd find the app fully installed and working.
The third scenario is the one that eats the most support time, because the obvious troubleshooting instinct — reinstall the app, redeploy the profile, reset the device — is exactly the wrong move when the app was never actually broken.
Why it happens — ESP tracks a specific, documented list of things, and blocks on an even smaller list
The Enrollment Status Page tracks three phases of provisioning: device preparation, device setup, and account setup. Only the last two are where apps and policies live, and each phase tracks a completely different set of targets.
Device Setup phase — device-targeted, happens before anyone signs in
During Device Setup, ESP tracks:
- Certificate profiles — SCEP certificate profiles targeted at the device.
- Network connections — VPN and Wi-Fi profiles targeted at the device.
- Apps — per-machine LOB MSI apps, LOB store apps installed in device context, Win32 apps, and WinGet apps, all targeted to the device.
Account Setup phase — user-targeted, happens after sign-in
Once the user signs in, ESP moves into Account Setup and tracks the same categories again, but this time scoped to what's assigned to the user: user-targeted SCEP certificates, user-targeted Wi-Fi profiles, and apps assigned to the user (per-user LOB MSI apps, per-machine LOB MSI apps, and LOB/online/offline store apps, plus Win32 apps for Windows 10 1903 and later). Before this phase starts tracking anything, the device has to calculate the full list of what needs tracking — while that calculation runs, ESP shows subtasks in an "Identifying" state, which is itself a common place for ESP to appear stuck when a user's Intune license hasn't actually been assigned yet.
Why an app can show "failed" when it actually installed fine
This is the specific timing/tracking gap most teams hit sooner or later, and Microsoft documents at least two concrete mechanisms for it:
- TrustedInstaller contention between LOB (MSI) and Win32 apps. Both LOB MSI installs (via the OMA-DM agent) and Win32 app installs (via the Intune Management Extension) use the Windows
TrustedInstallerservice, which does not allow simultaneous installs. If both kick off at nearly the same time, one of them fails with "Another installation is in progress, please try again later" — and because ESP is watching for a completion signal that never arrives cleanly, the app can show as failed on the ESP screen even on a device where the underlying package eventually does land. - The Microsoft 365 Apps / Teams Machine-Wide Installer conflict. The Click-to-Run installer for Microsoft 365 Apps includes an embedded MSI install for the Teams Machine-Wide Installer, and ESP does not track that embedded MSI. If another Win32 app using an MSI-based installer happens to run at the same moment, the same TrustedInstaller conflict occurs — and depending on timing, it's often the other app that reports the failure, not Office. This is described by Microsoft as a timing issue: it doesn't always happen, and it's not predictable which install "wins."
How to verify — check what phase and state a device is actually in before you touch anything
Before you reset a device or reinstall an app because "ESP failed," confirm what actually happened. There are three places to look, in order of speed.
That keystroke — or the View Diagnostics button if it's visible on the ESP screen — opens the built-in Windows Autopilot diagnostics page, which lists every tracked profile and app with its live status. It only works on Windows 11, in user-driven mode, when signing in with a work or school account (not a personal Microsoft account), and it requires the ESP profile setting Show app and profile configuration progress and Turn on log collection and diagnostics page for end users both set to Yes.
Event IDs worth recognising in that output: 153 (profile state changed, usually Unknown to Available, meaning the device got its Autopilot profile), 161 (settings retrieved successfully), and 171/172 (TPM attestation or profile-availability failures, both errors with an HRESULT). If you see repeated 100 warnings ("Autopilot policy [name] not found"), the device is still waiting on its profile to download — that's a networking or timing issue, not an app failure.
- Sign in to the Microsoft Intune admin center.
- Select Devices > Windows > Windows devices.
- Under Device onboarding, select Enrollment.
- Under Windows Autopilot, select Devices, then search by serial number.
- Check for a Fix pending or Attention required status — this indicates a hardware change was detected, not an app failure.
- Separately, go back to Devices > Windows devices and open the device's own page to see its current compliance state and last check-in time — a device that's actually stuck on ESP won't have completed a normal Intune sync yet.
The fix — configure a timeout and failure policy instead of leaving the defaults
The out-of-the-box ESP defaults are not "safe." Left alone, they either let a stuck device sit for a very long time with no escape for the user, or — if you go the other direction and disable blocking entirely — let users log in to a desktop that's still missing half its required apps and policies. The fix is a deliberate, documented ESP profile configuration, not a default.
- Go to Devices > expand Device onboarding > Enrollment.
- Select the Windows tab, then under Windows Autopilot select Enrollment Status Page.
- Select Create, give the profile a name and description, then select Next.
- Set Show app and profile configuration progress to Yes — without this, none of the following settings apply.
- Set Show an error when installation takes longer than specified number of minutes to a realistic value. The default is 60 minutes — raise it if you're deploying a heavy app stack, but don't leave it unconsidered.
- Set Show custom message when time limit or error occur to Yes, and write a message that names your helpdesk contact method — the generic Microsoft default just says "contact your support person," which wastes time when a stuck user can't tell who that is.
- Set Turn on log collection and diagnostics page for end users to Yes. This is what enables the Ctrl+Shift+D diagnostics page and the "collect logs" button for the user.
- Set Block device use until all apps and profiles are installed to Yes — this is the setting that actually turns ESP from a progress display into an enforced gate. Leaving it No means users can walk straight past ESP regardless of what's still installing.
- With blocking enabled, set Allow users to reset device if installation error occurs to Yes so a genuinely broken device isn't a dead end for the user.
- Set Allow users to use device if installation error occurs deliberately, not by default. No keeps the device fully locked until fixed — appropriate for kiosk or regulated devices. Yes lets the user continue with a partially configured device after a failure — more appropriate for a general knowledge-worker fleet where a single non-critical app failing shouldn't cost someone a day of productivity.
- Set Block device use until these required apps are installed if they are assigned to the user/device to Selected, then choose Select apps and pick only the apps that genuinely must be present before anyone touches the desktop — for example, your endpoint protection agent or a compliance-critical LOB app. Leave everything else off the blocking list.
Two settings deserve their own callout because they change the ESP timeout math in ways that aren't obvious from the profile UI:
If you've also enabled Install Windows quality updates (might restart the device) on the same profile, be aware that Microsoft's own guidance says Block device use until all apps and profiles are installed needs to be set to Yes for that update installation to be guaranteed to run — with blocking set to No, a device can exit ESP before Windows Update for Business policies and the monthly security update release are even applied, regardless of what the quality-updates toggle says.
Proof it worked — verify the policy landed and get a fleet-wide read on provisioning health
After you've configured and assigned the profile, don't just wait for the next ticket to tell you whether it worked. Two checks:
- Reboot a test device (or wait for the next check-in cycle) and confirm the profile applied — the ESP screen should show your custom timeout message wording if you deliberately trigger a timeout on a test device by targeting an app you know is missing dependencies.
- Run a fleet-wide read-only report against Microsoft Graph so you have a triage list instead of waiting for individual tickets.
Graph v1.0 doesn't expose a single "ESP phase" or per-app ESP result property — that granular detail only lives in the on-device diagnostics and IME logs under C:\ProgramData\Microsoft\IntuneManagementExtension\Logs. What Graph does give you, cheaply and at fleet scale, is enrollmentProfileName, deviceRegistrationState, and lastSyncDateTime from the managed device object, cross-referenced against enrollmentState on the matching Windows Autopilot device identity (values: unknown, enrolled, pendingReset, failed, notContacted). That's enough to flag which specific devices are worth pulling logs from, without reading logs from every device in the fleet.
Get-EspDeviceProvisioningReport.ps1 is free and open source. It's a genuinely read-only script — no writes to Autopilot, Intune, or Entra ID.
Get-Mg*) cmdlets — it doesn't sync, wipe, retire, or reassign anything. Run it the morning after any large Autopilot deployment wave to get a prioritised list of exactly which serial numbers are worth pulling on-device diagnostics from, instead of reading logs on all forty devices to find the four that actually need attention.References
- Windows Autopilot Enrollment Status Page — Microsoft Learn
- Set up the Enrollment Status Page — Microsoft Intune | Microsoft Learn
- Windows Autopilot troubleshooting FAQ — Microsoft Learn
- Troubleshoot the Windows Enrollment Status Page — Microsoft Learn
- windowsAutopilotDeviceIdentity resource type — Microsoft Graph | Microsoft Learn