Intune app lifecycle: install, detect, update, uninstall
Overview
When you assign a Win32 app in Intune, the service does not just push an installer and hope for the best. It follows a defined lifecycle: it checks who and what the app is assigned to, confirms the device meets the requirement rules, runs detection to see if the app is already present, executes the install command, interprets the return code, and then re-checks detection to confirm the result. The same machinery drives updates and uninstalls.
This article walks through that lifecycle end to end so you can reason about why an app installed, skipped, retried, or failed. You will learn the exact order Intune evaluates things, the role of the Intune Management Extension on the device, how detection and return codes decide the final status, and how install, update, and uninstall behavior is controlled by the commands and assignments you configure.
What is the Intune Win32 app lifecycle?
The lifecycle is the repeatable sequence Intune runs every time it evaluates a Win32 app against a device. It is the same loop whether the app is brand new, already installed, or being removed. Each pass moves through six logical stages:
- Assignment check — is this app targeted to the user or device, and with what intent (Required, Available, or Uninstall)?
- Requirement evaluation — does the device satisfy every requirement rule? If not, the app is “not applicable” and nothing else happens.
- Detection — using the configured detection rules, is the app already in the desired state?
- Command execution — if action is needed, Intune runs the install or uninstall command.
- Return-code interpretation — the process exit code is mapped to Success, Failed, Soft reboot, Hard reboot, or Retry.
- Post-action detection — Intune re-runs detection to confirm the app reached the expected state and reports the result.
Understanding this order is the single most useful troubleshooting skill, because almost every “it didn’t install” case is really a failure at one specific stage — usually requirements or detection, not the installer itself.
Which engine runs the lifecycle on the device?
All Win32 app and PowerShell-script processing happens on the client through the Intune Management Extension (IME), the “Microsoft Intune Management Extension” Windows service. IME is installed automatically the first time a device is targeted with a Win32 app or a PowerShell script — you do not deploy it yourself.
Timing matters when you are waiting for an app. IME checks for new Win32 app and script policy roughly once an hour, and also after a device restart or whenever the service restarts. That is separate from the general Windows MDM device check-in, which runs on a variable schedule (commonly around every 8 hours, more frequently right after enrollment). So a freshly assigned Required app may not appear for up to an hour even though the MDM channel checked in sooner. To force the IME cycle immediately, trigger a manual sync from Settings > Accounts > Access work or school > Info > Sync, or from the Company Portal.
Everything IME does is written to logs under C:\ProgramData\Microsoft\IntuneManagementExtension\Logs. The two you will read most are IntuneManagementExtension.log (policy and overall flow) and AppWorkload.log (per-app detection, command, and return-code detail). Open them with CMTrace so the timeline is readable. You can force a sync from the command line as well:
Get-ScheduledTask | ? {$_.TaskName -eq "PushLaunch"} | Start-ScheduledTaskWhy are requirement rules evaluated before detection?
Requirement rules are the gate that decides whether an app is even applicable to a device, and Intune evaluates them before detection and before any content is downloaded or any command runs. If a device fails a requirement, the app shows as “not applicable” — not failed — and IME never touches the installer. This ordering keeps unsuitable devices from downloading multi-gigabyte packages they can never use.
You configure requirements on the Requirements tab of the app. The mandatory two are Operating system architecture (x86, x64, ARM64) and Minimum operating system. Optionally you can also require a minimum amount of disk space, physical memory, number of logical processors, or CPU speed, and you can add custom requirement rules based on a file, a registry value, or a PowerShell script. See Intune requirements for how to build these. Because requirements run first, a too-strict rule (for example the wrong architecture) is a common reason an app silently never installs.
How does detection decide whether the app is already installed?
Detection is how Intune answers a single question at two points in the lifecycle: before the command runs (“is action needed?”) and after it (“did the action succeed?”). If detection already reports the app as present before install, Intune skips the command and marks the app installed. After a successful command, detection must report present or the app is recorded as failed even when the installer exited 0.
There are four detection rule types you can mix under “Manually configure detection rules”:
- MSI — matches on the MSI product code; auto-populated for MSI-based installers.
- File — checks a file exists, or compares its version, size, or modified date.
- Registry — checks a key/value exists or compares its data.
- Custom script — a PowerShell script for logic the other types cannot express.
The custom-script contract trips people up: a detection script is treated as “detected” only when it both exits 0 and writes output to STDOUT. An exit code of 0 with no output means “not detected.” This is why a script that runs fine interactively can still report the app missing under IME.
What do install commands, contexts, and return codes do?
The install command is the exact command line IME runs from inside the extracted package, and the uninstall command is its counterpart used for the Uninstall intent. Configure both on the Program tab — see install and uninstall commands for reliable patterns. Each command runs in an install behavior context:
- System — runs as the local SYSTEM account, device-wide. This is the common default and works without a signed-in user.
- User — runs in the context of the signed-in user; the user must be logged on. Use this for installers that only register per-user.
When the command finishes, IME maps its exit code to a result. The defaults below apply unless you add your own mappings; any code not in the table defaults to Failed. See return codes and install behavior for the full picture.
| Return code | Default meaning | Effect on the lifecycle |
|---|---|---|
| 0 | Success | App treated as installed; post-install detection confirms. |
| 1707 | Success | Same as 0; proceeds to detection. |
| 3010 | Soft reboot | Success, but a restart is required to complete. |
| 1641 | Hard reboot | Installer is initiating a restart of the device. |
| 1618 | Retry | Another install is in progress; IME retries later. |
| Any other | Failed | Recorded as a failure unless you map the code. |
Restart handling is controlled separately on the Program tab via the device restart behavior: No specific action, App install may force a device restart, Determine behavior based on return codes (honors 3010/1641), or Intune will force a mandatory device restart.
How do assignments drive install, update, and uninstall?
The assignment intent tells Intune what the desired state is, and the lifecycle works toward it:
- Required — the app installs automatically on targeted users or devices. Required apps install in the background and may surface a toast notification.
- Available for enrolled devices — the app appears in Company Portal for user-initiated install. This intent needs a user, so it is not supported for device-only targeting.
- Uninstall — Intune runs the uninstall command and expects detection to report the app gone.
Choosing between the first two is covered in Required vs Available app assignments. Updates ride the same loop: when you replace the package or change the version, detection on the next cycle reports the old state as no longer matching, so IME re-runs the install command to bring the device current. For end users, the Company Portal shows install status for Available apps and lets them retry. A pilot rollout typically starts with a small Required or Available test group before broad assignment.
How do you read the lifecycle when something goes wrong?
Because each stage has a distinct outcome, the symptom usually points straight to the stage at fault. Use the table below to map what you see to where to look first.
| Symptom | Likely lifecycle stage | Where to look |
|---|---|---|
| App shows “not applicable” | Requirement evaluation | Requirements tab: architecture, minimum OS, custom rules |
| Install never starts, no error | Assignment or sync timing | Confirm intent and group; force an IME sync; wait the ~1h cycle |
| Marked installed but app missing | Pre-install detection | Detection rule matched the wrong file/key/code |
| Installer exits 0 but app fails | Post-install detection | Detection script needs exit 0 and STDOUT output |
| Status stuck or retrying | Return-code mapping | 1618 retry, or unmapped code defaulting to Failed in AppWorkload.log |
| Uninstall reports failure | Uninstall command / detection | Uninstall command syntax; detection still finds remnants |
Quick checklist
- Confirm the assignment intent (Required, Available, or Uninstall) and target group before anything else.
- Verify requirement rules are met — a failed requirement makes the app “not applicable,” never “failed.”
- Test detection rules independently; for custom scripts, ensure exit 0 and STDOUT output on success.
- Map any non-default return codes you expect; remember 3010 and 1641 mean reboot, 1618 means retry.
- Force an IME sync instead of waiting the ~1 hour cycle, then watch AppWorkload.log with CMTrace.
- Validate both the install and uninstall paths so future Uninstall assignments behave predictably.

Leave a feedback
Include versions, steps, and any error text if you have them.