Intune & Endpoint

Intune Win32 app deployment: the parts that actually break

Intune Win32 app deployment: the parts that actually break. Intune & Endpoint article banner on grbadhon.com

Intune Win32 app deployment has one property that makes it harder to debug than it looks: the install usually works, and the reporting usually disagrees. A device runs the installer, the software appears under Program Files, and the admin centre still says Failed or Pending. The install command is rarely the fault. Detection logic, execution context and a log file that no longer holds the answer account for most of it. Every fact below was verified against Microsoft Learn on 11 September 2026.

None of it happens without the agent. Win32 content is downloaded, unpacked and executed by the Intune management extension, which Microsoft installs automatically the first time a PowerShell script or a Win32 app is assigned to a user or a device. A tenant with neither has no agent anywhere, and a device that never received one reports nothing rather than reporting a failure.

What Intune Win32 app deployment actually reports on

The installer exit code is not the app state. Intune decides whether an app is installed by running the detection rules, and the detection result is what the console shows. An installer can return 0, write every file it was meant to write, and still leave the app sitting at Failed because the rule that was supposed to find it looked in the wrong place.

Two behaviours in Microsoft’s guidance on adding and assigning Win32 apps to Intune matter more than the rest. The conditions for all detection rules must be met, so three rules are an AND and not an OR, and adding a second rule to catch an edge case quietly narrows the match instead of widening it. And when Intune detects that the app is not present, it offers the app again within approximately 24 hours, for required assignments only. That second behaviour is why a broken detection rule looks like an install loop: the device reinstalls a piece of software it already has, once a day, indefinitely.

The detection script rule that costs the most time

A custom detection script is judged on three channels at once. The app counts as installed when the script exits with 0 and writes a string to STDOUT. If any data reaches STDERR, the result is evaluated as not installed, even when the exit code is 0 and STDOUT has data. Microsoft states this plainly, and it is the single most expensive line in the documentation, because a non terminating error record from a cmdlet you did not think about is enough to poison an otherwise correct script.

Microsoft also recommends encoding detection scripts as UTF-8 BOM. A script that works in the ISE and fails on the client is usually an encoding problem rather than a logic problem.

Detect-AcmeAgent.ps1
# Detection script. Intune reads three things: the exit code, STDOUT and STDERR.
# Exit 0 with data on STDOUT means installed. Anything on STDERR means NOT
# installed, even with exit code 0 and data on STDOUT.
$target = "7.4.1"
$exe    = "C:\Program Files\Acme\Agent\acme.exe"

# -ErrorAction Stop keeps a non terminating error off STDERR. Silencing it is
# not cosmetic here: a stray error record marks the app as not installed.
if (-not (Test-Path -LiteralPath $exe)) { exit 1 }

$found = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($exe).FileVersion
$found = $found.Trim()

if ([version]$found -ge [version]$target) {
    Write-Output $found
    exit 0
}

exit 1

32 bit and 64 bit context, in four separate places

The same choice appears four times in a single app definition, defaults to 64 bit in three of them, and defaults to 32 bit in the one that catches everybody. Calling powershell.exe in the install or uninstall command launches a 32 bit PowerShell instance. To force the 64 bit host, Microsoft’s documented path is %SystemRoot%\Sysnative\WindowsPowerShell\v1.0\powershell.exe.

Where the choice appearsDefaultWhat goes wrong
powershell.exe in the install command32 bitThe script sees the WOW64 view. Registry writes land under Wow6432Node and file writes land in Program Files (x86), so a 64 bit detection rule then finds nothing.
File detection, Associated with a 32-bit app on 64-bit clientsNo, meaning 64 bitPath environment variables expand in the 64 bit context. A genuinely 32 bit app installed to Program Files (x86) is not found unless this is set to Yes.
Registry detection, same toggleNo, meaning 64 bitThe rule searches the 64 bit hive. Most third party installers write their uninstall key to the 32 bit hive.
Detection script, Run script as 32-bit process on 64-bit clientsNo, meaning 64 bitUsually correct, and worth setting deliberately rather than inheriting, because it decides which registry view the script reads.

Set the install command and the detection rule to the same bitness on purpose. Most detection failures that survive a rewrite of the script are a mismatch between these two, not a fault in either one.

The numbers that decide your packaging

These are the documented limits as they stand today. They are worth knowing before you design a dependency chain rather than after, because two of them are graph limits and they are counted in a way that is easy to breach by accident.

LimitValueWhy it bites
App package size30 GB per appGenerous, and not the constraint people assume it is. Delivery optimisation priority, set per assignment, matters more on a thin link than the package size does.
Installation time required60 minutes by default, 1440 maximumThe system fails the install when the program outlives the timeout. Large suites and anything that pulls content from the internet mid install need this raised before the first pilot, not after.
Retry return code3 attempts, 5 minutes apartFixed. A transient failure that clears in an hour is not retried into success, and the app waits for the next evaluation instead.
Dependencies100 apps per graph, parent includedCounted across the whole graph including recursive sub dependencies, and a shared dependency sums the graphs it appears in. Three modest chains that share one runtime can exceed 100 while no single chain looks large.
Supersedence10 nodes per relationship graphTen is small. A product updated monthly and superseded in place runs out of nodes inside a year unless old versions are retired from the graph.
PowerShell script as installer50 KBThe newer installer type, in place of a command line. Multi Admin Approval blocks uploading the script during app creation, so the app has to be created first and the script added afterwards.

Microsoft’s Win32 app management overview for Intune carries the size cap and the prerequisites. Note that the Intune documentation was reorganised earlier this year: the old /intune/intune-service/apps/ paths now return a 301 to /intune/app-management/deployment/, so most third party guides on this subject are still linking through a redirect.

Read the right log

Agent logs live in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs. The advice to open IntuneManagementExtension.log and search for the app name is now wrong, and it is wrong in the worst way, because the search succeeds and returns nothing. Microsoft’s Win32 app troubleshooting reference lists AppWorkload.log as the main app workload log, covering app check ins, app installs, applicability and detection. IntuneManagementExtension.log is now agent check in, policy request, policy processing and reporting.

Log fileWhat is in it
AppWorkload.logApp check ins, installs, applicability and detection. Start here for anything about a Win32 app.
AppActionProcessor.logDetection and applicability checks from the application action processor.
IntuneManagementExtension.logAgent check in, policy request, policy processing, reporting. Start here when the app never arrives at all.
AgentExecutor.logPowerShell script execution detail.
HealthScripts.logRemediation scripts, custom compliance scripts, managed installer and on demand remediations.
ClientHealth.logAgent client health activity.
Get-Win32AppLog.ps1
# Win32 app activity is in AppWorkload.log, not IntuneManagementExtension.log.
# Searching the old file for an app name returns nothing on a current agent,
# which reads exactly like an app that was never targeted.
$logs = "C:\ProgramData\Microsoft\IntuneManagementExtension\Logs"

Get-ChildItem -Path $logs -Filter "AppWorkload*.log" |
    Select-String -Pattern "Acme Agent" -Context 0,2 |
    Select-Object -Last 40

One configuration item belongs with the logs because it produces failures that look like nothing else: antimalware scanning of the content folders. Microsoft asks for C:\Program Files (x86)\Microsoft Intune Management Extension\Content and C:\windows\IMECache to be excluded, and on x86 clients the same Content path under Program Files. A scanner holding a file open during extraction produces intermittent, machine specific failures that never reproduce on the test device.

The failure modes

Nearly every Intune Win32 app deployment problem that reaches a service desk is one of nine things, and the symptom rarely names the cause. The column on the right is what to check first, not the only possible explanation.

SymptomWhat it usually is
App installs correctly, console reports Failed, and it reinstalls dailyA detection rule that does not match reality. Remember the AND: every rule must be satisfied. Check bitness before you rewrite the script.
Detection script returns the right value by hand, app still not detectedSomething reached STDERR. Exit 0 and STDOUT data are not enough on their own.
Works on the pilot device, fails for most usersThe app was assigned to users, and it needs privileges the signed in standard user does not have. Microsoft calls this out twice in the documentation. Assign to devices, or set the install behaviour to System.
Install never starts and nothing appears in AppWorkload.logNo agent, or no applicable assignment. Confirm the device is checking in before anything else, and see the three problems that look exactly like a sync failure.
Install fails at exactly the same elapsed time on every deviceThe 60 minute default timeout. Raise Installation time required toward 1440 for large packages.
Apps fail during Autopilot enrolment but install fine afterwardsWin32 and line of business apps mixed during classic Autopilot. Microsoft supports mixing them under Autopilot device preparation but not during classic Autopilot enrolment, and the enrolment status page decides what blocks the desktop. See what the enrollment status page actually blocks.
MSI installs fail on a subset of devices with no useful errorWindows S mode. MSI installation is not supported there, and the requirement rules will not catch it for you.
An installer needs a dialog or a visible sessionInteractive installations are not supported. Microsoft explicitly names tools of the ServiceUI kind as unsupported workarounds with unpredictable results. Repackage for silent install instead.
Two apps fight over the same setting after installNot an app problem. Configuration profiles overlap, and policy conflict decides which value the device applies.

What I would do differently

My tenant is a lab with no enrolled devices, so I have not measured install success rates across a fleet and I am not going to pretend otherwise. What follows is judgement about design, and the documentation is the source for the mechanics.

Design the detection rule before the install command. The install command is usually decided by the vendor and takes ten minutes to find. The detection rule is the part you own, it is what the console reports on, and it is where almost all of the wasted time goes. Write it first and the rest of the app definition falls out of it.

Use one detection rule where one will do. The AND semantics mean each additional rule is another thing that can be false. A single file version check against the binary the product actually ships is more robust than a file check plus a registry check plus a script.

Prefer version comparison over equality. A rule that matches exactly one version reports every device on a newer build as not installed, and then reinstalls the older one over the top of it every day.

Keep dependency graphs shallow. The 100 app limit is counted across shared graphs, and a dependency relationship also blocks deletion of both apps until it is removed. Two levels is manageable. Four is a structure nobody will want to unpick in a year.

Raise the install timeout for anything that touches the internet during setup. The default 60 minutes is comfortable on a wired pilot device and marginal on a home connection, and the resulting failure is indistinguishable from an installer fault.

Last verified: 11 September 2026.

Common questions

Because the console reports the detection result, not the installer exit code. If the detection rule looks in the wrong place, or one rule out of several is false, the app reads as not installed. Intune then offers it again within approximately 24 hours for required assignments, which produces what looks like a daily reinstall loop.

In C:\ProgramData\Microsoft\IntuneManagementExtension\Logs. Win32 app installs, applicability and detection are now in AppWorkload.log, with further detection detail in AppActionProcessor.log. IntuneManagementExtension.log carries agent check in, policy request, policy processing and reporting, so it is the file to read when the app never arrives at all.

The app is treated as installed only when the script exits with 0 and writes a string to STDOUT. If anything reaches STDERR, Intune evaluates the result as not installed even when the exit code is 0 and STDOUT has data. One non terminating error record is enough to cause it.

30 GB per app. Size is rarely the binding constraint. The installation time required value matters more: it defaults to 60 minutes and the system fails the install when the program outlives it. The maximum is 1440 minutes, and large suites want it raised before the first pilot rather than after.

Three attempts, five minutes apart, and only for return codes mapped to the Retry code type. The interval is not configurable. A transient failure that clears after an hour is not retried into success, and the app waits for the next policy evaluation on the device instead.

No. Microsoft states that interactive installations are not supported, and that tools which force interaction with the signed in session, of the ServiceUI kind, are unsupported and may behave unpredictably. Repackage the installer for silent installation. An app assigned to users that needs rights the standard user lacks will also fail.