[7.1.1] Deploying Win32 Applications

The full Win32 lifecycle on one sheet: packaging, install context, detection, requirements, dependencies and supersedence, and assignment, with the traps named.


Win32 is the packaging format that carries everything the Store and the Enterprise App Management catalog do not, which in most estates is still the majority of the software people actually run. Getting a Win32 deployment right is not hard, but it is unforgiving: four decisions the portal presents as routine, how you package, how you detect, what you require, and how you assign, are the difference between an app that lands silently on ten thousand devices and one that reports failed on all of them while sitting installed. This build sheet walks the full lifecycle for a single app with every setting named.


Step 1: Package the App

The unit of deployment is the .intunewin file, produced by the Microsoft Win32 Content Prep Tool. Point it at the folder that holds your installer and everything the installer needs, name the setup file inside that folder, and give it an output path. It compresses and encrypts the whole folder into one package Intune can deliver.

IntuneWinAppUtil.exe -c C:\Packages\App\v1.0 -s setup.exe -o C:\Packages\App\out -q

Two constraints matter before you wrap anything. The installer has to run completely silently, because Intune never shows a user interface and any prompt hangs the install until it times out. And the packaged content has a ceiling of 30 GB per app, raised from the old 8 GB, which is generous enough that hitting it usually means you are shipping something that should not be a single Win32 app in the first place.

Step 2: Install, Uninstall, and What Runs Them

You provide an install command and an uninstall command as plain command lines. The install can be a direct call like setup.exe /quiet or a PowerShell script you upload, capped at 50 KB; either way it must be non-interactive. The uninstall is almost always the product’s MSI removal, and it needs the full command because environment variables are not expanded in this field.

# Uninstall
msiexec /x "{12345A67-89B0-1234-5678-000001000000}" /qn

The install behavior setting decides the account the commands run under, and it is more consequential than it looks. System context installs the app for the machine, needs no one signed in, and is the right default for anything that belongs to the device rather than a person. User context installs for the signed-in user and only carries admin rights if that user already has them, which means a user-context app that needs elevation simply fails on a standard user. On a fleet that has taken local admin away, and it should have, System is almost always the answer. One trap worth knowing: calling powershell.exe from these fields launches the 32-bit engine, so a script that must run 64-bit has to invoke %SystemRoot%\Sysnative\WindowsPowerShell\v1.0\powershell.exe.

Device restart behavior governs what happens when an installer signals a reboot. The safe default, determine behavior based on return codes, lets the app’s own exit codes drive the decision, and those codes are the contract between the installer and Intune.

Return codeTypeWhat Intune does
0SuccessInstall succeeded.
1707SuccessInstall succeeded (the installer’s own success code).
3010Soft rebootSucceeded; a reboot finishes it, but the next app can still install first.
1641Hard rebootThe installer began a restart; nothing else installs until the device reboots.
1618RetryAnother install is already running; the agent retries up to three times, five minutes apart.

These five are pre-populated when you create the app, and you can add more. If an installer returns a nonstandard success code, map it here, or Intune will read a successful install as a failure and reinstall it on a loop.

Step 3: Detection, the Part That Actually Fails

Detection is how Intune decides whether the app is already present, and it is where most Win32 deployments quietly break. The rule has to match what the installer genuinely leaves behind, not what you assume it does. Intune supports four kinds, combined with AND, so every rule you add has to be true at once.

TypeDetects byUse when
MSIProduct code, optionally with a version checkThe installer is a single MSI and its product code is stable.
FileA file or folder’s existence, version, date, or sizeThe app writes a known binary you can version-check.
RegistryA key or value’s existence, or a string, integer, or version comparisonThe installer stamps a version into the registry.
Custom scriptA PowerShell script you writePresence is more complicated than one file or key can express.

The script option is the powerful one and the one with a contract people miss. Intune treats the app as detected only when your script exits with code 0 and writes something to standard output. Write nothing to STDOUT and the app reads as not installed even on a clean exit; write anything to standard error and it reads as not installed even if STDOUT has content and the exit code is 0. So a detection script emits a value on the success path and stays completely silent otherwise.

$v = (Get-ItemProperty 'HKLM:\SOFTWARE\Vendor\App' -Name Version -ErrorAction SilentlyContinue).Version
if ($v -ge [version]'1.0.0') { Write-Output 'Installed'; exit 0 } else { exit 1 }

On 64-bit clients the script runs 64-bit unless you set run as 32-bit, which matters when the value you are checking lives under the WOW6432Node view. The single most common failure code in this whole workflow, 0x87D1041C, means exactly one thing: the install ran but detection did not match afterward. It is almost never an install problem and almost always a detection rule pointed at the wrong version, path, or registry view.

Step 4: Requirements Are the Applicability Gate

Requirement rules decide which devices the app is even eligible for. A device that fails them is marked not applicable rather than failed, and that distinction is the point: you use requirements to scope, not to catch errors. The built-in checks cover operating system architecture (x86, x64, and Arm64, which is a first-class target now rather than an afterthought), minimum OS version, free disk space, physical memory, logical processor count, and minimum CPU speed. Beyond those you can add file, registry, or script requirements, and a script requirement can compare its output as a string, integer, version, date, boolean, or float, which lets you gate on anything you can measure. Keep the rules honest. An app that lands on a device it cannot run on becomes a support ticket, and one scoped too tightly is an app nobody receives.

Step 5: Dependencies and Supersedence

Two relationship types let one app pull in or replace another. Dependencies handle prerequisites: an app can require up to a graph of 100 apps, Intune installs them automatically by default without you targeting them separately, and a dependency can carry its own sub-dependencies that are evaluated first. You do not control the order among peers, so a prerequisite that must run before another belongs in the chain, not beside it.

Supersedence handles versions and replacements, and the behavior turns on a single toggle. Leave uninstall previous version off and Intune installs the new app over the old one, which is the update case where the installer handles the upgrade itself. Turn it on and Intune removes the old app first, which is the replacement case where the two are genuinely different software. The limits are real: a supersedence graph tops out at eleven nodes, a chain at ten, and one app can supersede at most ten others. Unlike dependencies, superseding apps are not auto-targeted, so if you do not assign the new version, the agent ignores it.

This is also the seam where the paid tier earns its place. Hand-built supersedence is a maintenance treadmill, and for anything in the Enterprise App Management catalog the auto-update service now detects a newer version and updates targeted devices for you. It is the same point I made in the Winget and Enterprise App Management articles: Win32 is the floor everyone has, and the catalog is what the money buys to get off the treadmill.

Step 6: Assign

Win32 has exactly three assignment intents, and the naming is precise. Required installs the app on the devices or users in the group. Available for enrolled devices publishes it to the Company Portal for users to install on demand, and there is no unenrolled equivalent, because Win32 delivery rides the Intune Management Extension and therefore requires enrollment. Uninstall removes it. One behavior to plan around: an app a user installed from Company Portal is not automatically reinstalled if they remove it, which is usually what you want and occasionally is not.

Everything else on the assignment is about friction and timing. You assign to user or device groups and can exclude as readily as include. Notifications run from showing every toast to hiding them all. Availability and deadline each take as-soon-as-possible or a specific time, and a deadline is what turns an available app into an enforced one. When a restart is in play, the grace period defaults to a full day and can stretch to two weeks, with a countdown dialog and an optional snooze, so an enforced install does not reboot someone mid-presentation. Delivery optimization priority decides whether content downloads in the background or competes in the foreground, and peer-to-peer sharing is on by default, which is what keeps a thousand devices from each dragging the full package across the WAN.


Validate With One App, End to End

Prove the whole chain on a pilot device before it touches a ring. Assign the app Required to a test group and watch it land in the Intune Management Extension logs under C:\ProgramData\Microsoft\IntuneManagementExtension\Logs: AppWorkload.log for the install and detection, IntuneManagementExtension.log for the agent’s check-ins. Confirm the app reports Installed, which proves detection matches the install, then confirm the uninstall assignment removes it cleanly. If your antimalware is aggressive, exclude the extension’s Content folder and C:\Windows\IMECache, or you will chase download failures that are really scanner interference. And if this app is going into an Autopilot build, do not mix classic MSI line-of-business apps and Win32 apps in the same enrollment, because they share the Windows installer service and collide; needing both during provisioning is itself a reason to move to Autopilot device preparation. Get one app through this loop and every app after it is the same six decisions with different values.


Intune Deployment Guide · Phase 7: Applications
‹ Previous: [7.1] App Strategy in an Intune-First Environment
Next: [7.1.2] Microsoft 365 Apps: Channels and Configuration