The installer works perfectly when you double-click it. It works when you run it from an elevated PowerShell window. Then Intune deploys it and the app either never appears, installs for nobody, or hangs waiting for a dialog no one can see. The difference is the execution context: Intune runs Win32 app installs as NT AUTHORITY\SYSTEM or as the signed-in user, and a legacy EXE rarely behaves the same way in both.
Here is what actually changes between SYSTEM and user context, why wrapped EXE installers break on it, and how to make the context question disappear instead of testing it app by app.
Fast Verdict Matrix
| Context Behavior | Legacy EXE Behavior | Native MSI Behavior |
|---|---|---|
| Per-user paths and hives | Writes to %APPDATA%, %LOCALAPPDATA% and HKCU. Under SYSTEM these resolve to the SYSTEM profile, so the real user never gets the files or settings. | Per-machine by design: files go to Program Files, registry to HKLM. Same result under SYSTEM every time. |
| UI and prompts | A dialog, EULA or reboot prompt appears in Session 0, where no user can click it. The install hangs until Intune times it out. | /qn is honored by the Windows Installer engine, so no UI is created regardless of session. |
| Mapped drives and network paths | Installers that pull payloads from a UNC path or mapped drive fail under SYSTEM, which has no user drive mappings or credentials. | All payload is cached inside the package. Nothing is fetched at install time. |
The Rule of Thumb
- Test every install as SYSTEM, never as yourself. Launch
psexec -i -s cmd.exeand run the exact Intune install command line from that prompt before you upload anything. - If an app needs
HKCUor%APPDATA%to exist at install time, it is a user-context app. Everything else should be per-machine and installed as SYSTEM.
The Fix: Remove the Context Dependency
The common workaround is a PowerShell wrapper such as PSAppDeployToolkit that detects the logged-on user, relaunches pieces of the install in their session, and closes blocking processes. It works, but you now maintain a script per app and test it in both contexts on every vendor release.
InstallMage takes the context decision out of the installer. It converts the EXE into a native, per-machine MSI that runs silently under SYSTEM, carries its payload inside the package, and gets an MSI product-code detection rule that does not depend on who is logged in. No PSADT wrapper, no session juggling, and the same package behaves the same way on every device.
Deep Dive
What Actually Changes Under SYSTEM
When a Win32 app is set to Install behavior: System, the Intune Management Extension launches the install command as NT AUTHORITY\SYSTEM in Session 0. There is no desktop, no user profile of the person who owns the device, and no network identity beyond the machine account. %USERPROFILE% points to C:\Windows\system32\config\systemprofile and HKCU maps to the SYSTEM hive.
An installer that was tested by an admin double-clicking it assumed the opposite on every one of those points. It writes a shortcut to the current user's Start Menu, seeds HKCU\Software\Vendor, and reads a license file from a mapped drive. All three succeed on your desk and quietly do the wrong thing under SYSTEM. See the per-machine vs per-user guide for the packaging-side view of the same split.
Session 0 and the Hidden Dialog
Since Windows Vista, services and SYSTEM processes run in Session 0, isolated from the interactive desktop. If an EXE installer shows any window, such as a EULA prompt, a "close Outlook to continue" warning or a reboot question, that window is created in Session 0 and nobody can see or dismiss it. The process sits waiting for input until Intune's install timeout elapses, and the portal reports a failure or an unmonitored process. This is a frequent root cause behind 0x87D300C9, covered in the Intune status error codes guide.
To reproduce it, run psexec -i -s so the process is attached to your session and the hidden window becomes visible, then check the install log. If you see a dialog, the silent switch you were given is incomplete. A native MSI removes the class of problem, since msiexec /i package.msi /qn never draws UI.
User Context and Its Limits
Setting Install behavior: User runs the install as the signed-in user, which fixes HKCU and %APPDATA% writes, but it brings its own constraints. A standard user cannot write to Program Files or HKLM, so any installer that needs elevation fails with 0x80070005 (access denied). The install can only run while a user is signed in, so it will not complete during Autopilot device setup. Detection rules also run in the same context, so a rule that checks HKLM can disagree with what the install did.
The practical policy: package per-machine, deploy as SYSTEM, and keep user context for the small set of apps that genuinely install into the user profile. If a vendor EXE forces you into user context only because it stores settings in HKCU, convert it to a per-machine MSI and handle the per-user settings separately.
Frequently Asked Questions
Should Intune Win32 apps install in System or User context?
Use System context for almost everything. It installs per-machine, works before any user signs in, and runs elevated. Use User context only for apps that install entirely inside the user profile and need no administrator rights.
Why does my installer work manually but fail when deployed through Intune?
Your manual test ran as you, in your interactive session, with your profile and drive mappings. Intune runs it as SYSTEM in Session 0 with none of those. Reproduce the failure with psexec -i -s cmd.exe and run the exact install command from that prompt.
How do I test an Intune Win32 install as SYSTEM?
Download PsExec from Sysinternals, run psexec -i -s cmd.exe from an elevated prompt, then execute your install command line in the new window and check echo %errorlevel%. Because the window is attached to your session, any hidden dialogs are visible, which is the fastest way to find an incomplete silent switch.
Context bugs hide because the same command succeeds in one environment and fails in the other. Test as SYSTEM, package per-machine, and detect by product code and the problem stops being a per-app investigation. For the related exit-code side, see the Intune Win32 app exit codes guide.