HomeNewsletterCommunityToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog

The Enrollment Status Page Isn't Blocking What You Think It's Blocking

IA
Imran Awan
23 July 2026

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 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.

Straight from Microsoft's documentation: disabling an ESP profile does not remove the ESP policy from a device that's already received it — users still get shown ESP the next time they sign in for the first time, because the policy isn't retracted just because the profile is disabled. If you're trying to "turn off ESP" mid-incident to unblock a user, that alone won't do it for a device that already has the policy cached.

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:

Note on security policies: Microsoft's own documentation is explicit that ESP does not track general security policies such as device restriction profiles — those are applied silently in the background. The only policy types ESP does track and surface progress for are Microsoft Edge policies, Assigned Access, and Kiosk Browser policies. When those finish, ESP shows a generic "(1 of 1) completed" line for security policies — it isn't itemising every configuration profile you've assigned.

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.

Gotcha: if you're on Microsoft Entra hybrid join, Win32 and UWP apps that are assigned to the device but use a user installation context are not tracked during Account Setup at all. If you're relying on ESP to block until one of those installs, it simply won't — the app installs later, silently, after the user is already on the desktop.

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:

  1. 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 TrustedInstaller service, 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.
  2. 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."
Tip: if you're deploying Microsoft 365 Apps during ESP, deploy it as a Win32 app type rather than the dedicated "Microsoft 365 Apps (Windows 10 and later)" app type. Microsoft's own guidance recommends this specifically to avoid the ESP hang caused by the Click-to-Run/Win32 install-order conflict. Also: never mix LOB (MSI) apps and Win32 apps in the same blocking set if you can avoid it — if you must, Windows Autopilot device preparation doesn't use ESP at all and therefore doesn't hit this conflict, so it's worth considering for that specific app mix.

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 Viewer — checking the ModernDeployment log remotely
# Pull the last 50 Autopilot/ESP-relevant entries from a remote device, oldest problems first Get-WinEvent -ComputerName $deviceName -LogName "Microsoft-Windows-ModernDeployment-Diagnostics-Provider/Autopilot" -MaxEvents 50 | Sort-Object TimeCreated | Select-Object TimeCreated, Id, LevelDisplayName, Message | Format-Table -AutoSize -Wrap

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.

Intune Admin Center — checking Autopilot device state
  1. Sign in to the Microsoft Intune admin center.
  2. Select Devices > Windows > Windows devices.
  3. Under Device onboarding, select Enrollment.
  4. Under Windows Autopilot, select Devices, then search by serial number.
  5. Check for a Fix pending or Attention required status — this indicates a hardware change was detected, not an app failure.
  6. 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.
Gotcha: a device only shows up in Devices > Windows > Windows devices once it has both a successful Autopilot registration and a licensed user has actually signed in on it. If a device is stuck early in Device Setup, before anyone has signed in, you won't find it in that list at all — only in the Windows Autopilot devices list.

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.

Intune Admin Center — Devices > Enrollment > Windows > Windows Autopilot > Enrollment Status Page
  1. Go to Devices > expand Device onboarding > Enrollment.
  2. Select the Windows tab, then under Windows Autopilot select Enrollment Status Page.
  3. Select Create, give the profile a name and description, then select Next.
  4. Set Show app and profile configuration progress to Yes — without this, none of the following settings apply.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. 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.
  10. 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.
  11. 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.
Warning: the blocking apps list is a filter, not an install instruction. If you add App 1, App 2, and App 3 to the blocking list, but App 3 and App 4 are actually assigned to the device, ESP only waits for App 3 — App 4 still installs, just without ESP blocking on it. Adding an app to this list that isn't actually assigned to the device or user does nothing.

Two settings deserve their own callout because they change the ESP timeout math in ways that aren't obvious from the profile UI:

Note — hybrid join adds real time on top of your timeout. On Microsoft Entra hybrid-joined Autopilot deployments, ESP can take roughly 40 minutes longer than the timeout value you set in the profile, because the on-premises Active Directory connector needs that extra window to create the new device record in Microsoft Entra ID. If you set a 30-minute timeout expecting a 30-minute cap, hybrid-joined devices can legitimately run to around 70 minutes before anything is actually wrong.

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:

  1. 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.
  2. 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.

Download the script — GitHub

Get-EspDeviceProvisioningReport.ps1 is free and open source. It's a genuinely read-only script — no writes to Autopilot, Intune, or Entra ID.

Get-EspDeviceProvisioningReport.ps1 View full repo →
PowerShell 7 — Get-EspDeviceProvisioningReport.ps1
# Read-only fleet triage report: managed device state cross-referenced against Autopilot enrollment state .\Get-EspDeviceProvisioningReport.ps1 -StaleSyncHours 8 -OutputPath C:\Reports\esp-fleet-check.csv
Example output below is illustrative, not a live-tenant capture. It matches the script's real structure and message wording, with fictional device values, so you can see what a run looks like before testing it yourself.
Get-EspDeviceProvisioningReport.ps1 — example output (illustrative)
.\Get-EspDeviceProvisioningReport.ps1 -StaleSyncHours 8 -OutputPath C:\Reports\esp-fleet-check.csv Retrieved 214 Windows managed device(s). Retrieved 342 Autopilot device identity record(s). Total Windows devices reported on : 214 Devices flagged for review : 4 DeviceName SerialNumber UserPrincipalName ReviewReasons ---------- ------------ ----------------- ------------- WKS-00019X4 4G7-KL2-9903 (not yet signed in) AutopilotEnrollmentState=notContacted; StaleSync>8h FIN-LAPTOP-88 PF3ABC12 jsmith@contoso.onmicrosoft.com ComplianceState=noncompliant; StaleSync>8h SALES-TAB-14 9KX-22P-0071 rpatel@contoso.onmicrosoft.com AutopilotEnrollmentState=failed OPS-DESKTOP-22 7YB-41Q-1188 (not yet signed in) StaleSync>8h Full report exported to: C:\Reports\esp-fleet-check.csv
Tip: this script only calls read (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

Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Autopilot
Windows Autopilot: Complete Device Lifecycle Management Guide
The full deployment lifecycle from registration through retirement, with the deployment modes and ESP explained.
Windows
Windows Hello for Business Provisioning Failure — Complete Fix
Another provisioning-time failure that shows up during Autopilot deployment, with the full root-cause breakdown.
Intune
Get a PRT Fleet Health Report in 5 Minutes Using Graph Explorer
Another fast, read-only Graph triage script for spotting fleet-wide problems before they become tickets.