It installs when I run it, but fails from Intune: SYSTEM vs user context
You double-click the installer on a test machine and it works first time. You package it as a Win32 app, deploy it from Intune, and it fails — often with no useful error in the portal. The most common root cause is not the package. It is the security context the installer runs in: Intune runs Win32 installs as SYSTEM by default, while your manual test ran as a logged-on user. Those are two very different worlds, and this article maps the differences and how to test for them before you deploy.
The problem
The symptom is maddeningly consistent: an installer that succeeds every time when run interactively fails when delivered as an Intune Win32 app. Typical signatures include:
- A generic failure code in the portal such as
0x80070643(fatal error during installation), with nothing obviously wrong in the package. - The install reports success but Intune then shows \"the application was not detected after installation completed successfully\" (
0x87D1041C) — the app went somewhere, just not where the detection rule is looking. - The install hangs until the Intune Management Extension times it out, because a dialog box is waiting for a click nobody can see.
- Files or registry settings turn up in the wrong profile — under
C:\\Windows\\System32\\config\\systemprofileinstead of the user's profile.
This is one of the most frequently asked Win32-app questions on Microsoft Q&A, and the accepted diagnosis there is blunt: \"A frequent root cause is context mismatch: Intune runs installs under SYSTEM by default, while manual testing likely runs under user context\" — installers that expect HKCU, %APPDATA%, mapped drives, or a visible UI \"may install to the wrong profile or fail entirely\". If you tested as a user and deployed as SYSTEM, you tested a different scenario from the one you shipped.
Why it happens
When you set a Win32 app's Install behavior to System (the common default choice), the Intune Management Extension runs your install command as NT AUTHORITY\\SYSTEM in session 0. That account can do almost anything to the machine — but it perceives the machine very differently from a logged-on user:
| Resource | Logged-on user context | SYSTEM context |
|---|---|---|
HKCU | The user's own hive | SYSTEM's hive (HKEY_USERS\\S-1-5-18). Writes intended for the user land in a profile no human ever loads. |
%APPDATA%, %LOCALAPPDATA%, %USERPROFILE% | C:\\Users\\<name>\\... | C:\\Windows\\System32\\config\\systemprofile\\... |
| Mapped drives | Visible (they belong to the user's logon session) | Invisible. Drive letters are per-logon-session; SYSTEM has none of yours. UNC paths may also fail because access is evaluated against the computer account. |
| Interactive UI | Dialogs appear and can be clicked | Session 0 is non-interactive. Any prompt, EULA screen or message box hangs invisibly until the install times out. |
Three follow-on traps compound this:
- Per-user installers. Plenty of modern installers (many Electron-based apps, per-user MSIs where
ALLUSERSis not set to 1) are designed to install into%LOCALAPPDATA%for the current user. Run as SYSTEM, they either fail or install perfectly — into SYSTEM's profile, where no user will ever find them. - Detection runs in a context too. Custom detection scripts for Win32 apps run as SYSTEM regardless of the install behaviour you chose. A detection script that checks
HKCUis reading SYSTEM's hive, so a genuinely successful user-context install can still be reported as \"not detected\". - No clear error surfaces. The portal shows a generic hex code; the truth is in
IntuneManagementExtension.logandAppWorkload.logon the device, which most people only find after a long detour.
The fix
The theme is simple: test in the same context you deploy in, and match the install behaviour to what the installer actually is.
1. Classify the installer: per-machine or per-user?
- Installs to
%ProgramFiles%/ writesHKLM→ per-machine. Deploy with install behaviour System. - Installs to
%LOCALAPPDATA%/ writesHKCU→ per-user. Deploy with install behaviour User (note: the install then runs with the logged-on user's rights, so it must not require local admin on standard-user estates). - For MSIs, check the
ALLUSERSproperty:ALLUSERS=1is per-machine; absent or empty is per-user. Many vendor MSIs acceptALLUSERS=1on the command line to force a per-machine install — test that it genuinely works.
2. Rehearse the deployment in a real SYSTEM shell
Before anything goes near Intune, reproduce the exact conditions with Sysinternals PsExec from an elevated prompt:
psexec.exe -s -i cmd.exe— then confirm withwhoami(expectnt authority\\system) andecho %APPDATA%(expect the systemprofile path).- Run the exact install command line you put in the Win32 app, silent switches and all. If it prompts, hangs, or lands files in
systemprofile, you have just caught the field failure in the lab. - Run your detection logic in the same shell. If it cannot see what the install just did, Intune will not either.
3. Make it genuinely silent
SYSTEM cannot click anything. Verify the silent switches (/qn, /S, /verysilent /suppressmsgboxes, or the vendor's documented equivalent) suppress every dialog, including EULA and reboot prompts — in the SYSTEM shell, not just in your user session.
4. Getting HKCU settings onto machines from SYSTEM
When you must deliver per-user registry settings or files via a SYSTEM deployment, use a pattern built for it rather than hoping:
- Active Setup: register a
StubPathunderHKLM\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\<your GUID>; Windows runs it once per user at their next logon, in their context. The call4cloud article in the sources walks through this in depth. - Enumerate loaded hives: a SYSTEM script can iterate
HKEY_USERS(and load profile hives withreg load) to write to every existing user profile — remembering to also handle the default hive for future users. - Intune remediations in user context: remediation scripts can be set to run using the logged-on credentials, a clean way to apply and verify per-user state on a schedule.
5. Remove dependencies SYSTEM cannot satisfy
Never reference mapped drive letters in an install command. Package all content inside the .intunewin file, or use UNC paths that grant read access to Domain Computers / the device identity, not just users.
6. When it still fails, read the real logs
On the device, open %ProgramData%\\Microsoft\\IntuneManagementExtension\\Logs\\ and read IntuneManagementExtension.log and AppWorkload.log (CMTrace makes them legible). The actual installer exit code and command line are recorded there, which beats guessing from a portal hex code.
How Decolla handles it
Decolla is a zero-touch Windows provisioning service (from The Cloud Platform Ltd) that runs over your own Intune/Autopilot tenant. The context-mismatch problem is exactly the class of failure its library exists to remove: every app, policy, script and fix in the curated catalogue — 260+ items across 21 sections — is pre-built and industry-tested, and the library records the verified install context and delivery method for each item. Before anything runs, you approve a written, itemised plan that states the delivery method and reversibility class per item, so a per-user installer never silently ships as a SYSTEM deployment, and anything Decolla changes can be rolled back per item (Decolla's own changes, that is — it does not undo third-party state it never created).
To be clear about the boundary: Decolla does not repackage or context-test your bespoke line-of-business installers. For anything outside the catalogue, the PsExec-as-SYSTEM rehearsal above remains the right discipline — Decolla simply means the standard estate-building layer arrives already tested, so your context debugging is confined to the apps only you own. Decolla is pre-launch; there is a waitlist at decolla.app.
Sources
- Microsoft Q&A — Why do some Win32 apps fail to install via Intune?
- cybernerds.io — Intune app install troubleshooting
- call4cloud.nl — Deploying HKCU registry settings (Active Setup pattern)
See it on a real device.
Decolla is in private build — early-access members see a build defined, deployed and rolled back first.
Get early access