Cloud & infrastructure

Package Win32 Apps for Intune with IntuneWinAppUtil and Detection Rules

Wrap an MSI or EXE installer into an .intunewin file, set silent install and uninstall commands, return codes and detection rules, then deploy and verify it with Intune.

13 min read
On this page

To deploy a Win32 app with Intune, put the installer and its files in a clean source folder, run IntuneWinAppUtil.exe -c <source> -s <setup file> -o <output> to produce an .intunewin file, and upload it in the Intune admin center under Apps > All Apps > Create > Windows app (Win32). On the device, the Intune Management Extension runs your silent install command, maps the exit code through the return codes you defined, and then runs your detection rule; only when the rule finds the app is the installation reported as successful.

Who this is for and what you will have at the end

This guide is for Intune administrators deploying desktop software that isn't available as a Microsoft Store or Enterprise App Catalog app: line-of-business MSIs, vendor EXE installers, or installers with extra configuration files.

At the end you will have:

  • A repeatable folder layout and command for building .intunewin packages.
  • A Win32 app in Intune with silent install and uninstall commands, sensible return codes and requirement rules.
  • A detection rule that reliably reports the app's state, including a custom script you can adapt.
  • An assignment with availability, deadline and restart settings, and a way to verify each step from the client logs.

How Win32 app deployment works

Win32 apps are delivered by the Intune Management Extension (IME), an agent that Intune installs automatically when you assign a PowerShell script, a Win32 app, a Microsoft Store app, a custom compliance setting or a remediation to a user or device. The IME runs as the IntuneManagementExtension service, checks in with Intune independently of the MDM channel, downloads the package and processes it in this order:

  1. Requirements are evaluated. If the device doesn't meet them, the app isn't installed.
  2. Detection runs. If the app is already detected, nothing is installed.
  3. The install command runs in the context you chose (System or User) and its exit code is compared with your return codes.
  4. Detection runs again. If the rule doesn't find the app, the installation is reported as failed even if the installer returned success.

That last step is why detection rules matter so much: a loose rule hides failed installs, and a strict rule reports failures for correct ones.

The four detection rule types compare like this:

Rule typeDetectsGood fitWatch out for
MSIMSI product code, optionally the product versionPlain MSI installersSelf-updating MSIs change version outside Intune
FileFile or folder existence, date, version or sizeEXE installers with a known main binary32-bit vs 64-bit path expansion
RegistryKey or value existence, string, integer or version comparisonInstallers that write a reliable uninstall or version key32-bit vs 64-bit registry view
Custom scriptAnything PowerShell can checkSeveral conditions, version ranges, per-user installsSTDOUT, STDERR and exit code rules

When you add several manual rules, the conditions of all rules must be met for the app to be detected.

Prerequisites

  • Devices: a supported Windows version in the Enterprise, Pro or Education edition, enrolled in Intune and Microsoft Entra registered, Microsoft Entra joined or Microsoft Entra hybrid joined. Windows in S mode isn't supported by the IME.
  • IME version: Microsoft requires Intune Management Extension 1.58.103.0 or later. The agent updates itself, so this mainly matters for devices that haven't synced for a long time.
  • Size: each Win32 app is capped at 30 GB.
  • Silent installer: Intune doesn't support interactive installations. The installer must run without dialog boxes or prompts. Workarounds that push UI into the signed-in user's session, such as serviceui.exe, are explicitly unsupported.
  • Content Prep Tool: the latest Microsoft Win32 Content Prep Tool from GitHub. Packages built with an older version produce a warning in the admin center.
  • Co-managed devices: set the Configuration Manager Apps workload to Pilot Intune or Intune.

Step 1: Prepare and test the source folder

The Content Prep Tool compresses every file and subfolder in the setup folder. Keep the tool itself, old builds and any test output outside that folder, or they end up in the package.

A layout that keeps things separate:

C:\Packaging\
  Tools\
    IntuneWinAppUtil.exe
  ContosoAgent\
    4.2.0\
      Source\
        ContosoAgent.msi
        config\
          settings.xml
      Output\

Reference any extra files with paths relative to the setup folder. In the layout above the installer would refer to config\settings.xml, not to a full path on your packaging machine.

Before packaging, run the exact command you plan to use in Intune on a test device, as SYSTEM if you will install in System context, and confirm three things: it finishes with no UI, it returns the exit code you expect, and it leaves behind something stable you can detect. For an MSI, msiexec gives you a quiet, no-restart install with verbose logging:

msiexec /i "ContosoAgent.msi" /qn /norestart /l*v "C:\Windows\Temp\ContosoAgent-install.log"

/qn suppresses all UI, /norestart stops Windows Installer restarting the device itself (Intune handles restarts through return codes), and /l*v writes a verbose log you can read when something goes wrong. For an EXE, use the silent switches the vendor documents.

Step 2: Create the .intunewin package

Run the Content Prep Tool with the setup folder, the setup file and an output folder:

C:\Packaging\Tools\IntuneWinAppUtil.exe -c C:\Packaging\ContosoAgent\4.2.0\Source -s C:\Packaging\ContosoAgent\4.2.0\Source\ContosoAgent.msi -o C:\Packaging\ContosoAgent\4.2.0\Output -q
ParameterPurpose
-cSetup folder; everything in it is compressed into the package
-sSetup file inside that folder, such as setup.exe or setup.msi
-oOutput folder; created if it doesn't exist
-qQuiet mode; an existing output file is overwritten
-hHelp

Without parameters, the tool prompts for each value. For an MSI, it reads the product information Intune needs, which pre-fills the MSI detection rule and uninstall command later.

Step 3: Add the app and configure the program

  1. In the Microsoft Intune admin center, go to Apps > All Apps > Create.
  2. Under Select app type, choose Windows app (Win32) and select Select.
  3. Select Select app package file, browse to the .intunewin file and select OK.
  4. On App information, complete Name, Description and Publisher. Keep names unique; if two apps share a name, only one appears in the Company Portal.

On the Program page:

  • Installer type: Command line for a normal command, or PowerShell script to upload a script (maximum 50 KB) that runs in place of the install command, in the same context, with its return code driving the result. If Multi-Admin Approval is enabled, you can't upload scripts while creating the app; create the app first and add the script afterwards.
  • Install command: the command you tested in Step 1.
  • Uninstall command: for an MSI, msiexec /x "{product-code}" /qn. Environment variables aren't expanded in this field; if you need them, wrap the uninstall in a script inside the package.
  • Installation time required: defaults to 60 minutes, maximum 1,440. Installs that run longer are failed.
  • Allow available uninstall: lets users uninstall from the Company Portal. It's hidden for apps that have dependencies or are dependencies.
  • Install behavior: System for machine-wide installs; User for per-user installs. Choose System for Microsoft Entra registered devices.
  • Device restart behavior: Determine behavior based on return codes, No specific action, App install may force a device restart or Intune will force a mandatory device restart.

If your install command calls powershell.exe, be aware that it starts 32-bit PowerShell. Use %SystemRoot%\Sysnative\WindowsPowerShell\v1.0\powershell.exe to force 64-bit.

Return codes

Intune adds a set of return codes when you create the app. Each code maps to one of five types: Success, Failed, Soft reboot (restart needed to finish, but the next app can install), Hard reboot (no further Win32 app installs until restart) or Retry (three attempts, five minutes apart). Compare the list with what your installer actually returns. The common Windows Installer codes are:

CodeWindows Installer meaningSuggested Intune code type
0ERROR_SUCCESSSuccess
1603ERROR_INSTALL_FAILURE, fatal error during installationFailed
1618ERROR_INSTALL_ALREADY_RUNNING, another installation in progressRetry
1641ERROR_SUCCESS_REBOOT_INITIATED, installer started a restartHard reboot
3010ERROR_SUCCESS_REBOOT_REQUIRED, restart needed to finishSoft reboot

Vendor EXE installers often use their own codes. Add each code the vendor documents as a success, reboot or retry condition, so that a successful install isn't reported as a failure.

Step 4: Set requirements

On Requirements, choose the Operating system architecture and Minimum operating system. Optional fields cover disk space, physical memory, logical processors and CPU speed. You can also add File, Registry or Script requirement rules, for example to install only where a prerequisite runtime is present. For a script requirement, Intune reads the script's STDOUT when it exits with 0, and you choose the output data type to compare against.

Step 5: Configure detection rules

On Detection rules, choose Manually configure detection rules or Use a custom detection script. You need at least one rule.

MSI rule

Select MSI and keep the pre-filled MSI product code. Set MSI product version check to Yes only if you deploy each version as a separate app. The MSI rule can be added only once.

File rule

Use Path, File or folder and a Detection method such as file or folder exists, or a version comparison against the main executable. The path must not contain characters such as , or ". Associated with a 32-bit app on 64-bit clients defaults to No, which expands variables like %ProgramFiles% in the 64-bit context. Set it to Yes for 32-bit apps that install under Program Files (x86).

Registry rule

Enter a Key path such as HKEY_LOCAL_MACHINE\Software\Contoso\Agent (or HKLM\Software\Contoso\Agent) and a Value name. If the value name is empty, detection runs against the key. The 32-bit setting decides whether Intune reads the 32-bit or 64-bit registry view on 64-bit clients; a 32-bit installer writing under WOW6432Node needs Yes.

Custom detection script

A script gives you full control. Intune treats the app as installed only when the script exits with 0 and writes something to STDOUT. A nonzero exit code means not installed, and any data on STDERR also means not installed, even with exit code 0. Intune doesn't look for a particular string. Microsoft recommends saving the script as UTF-8 with BOM.

This example detects version 4.2.0 or later of a 64-bit executable:

$path    = 'C:\Program Files\Contoso\Agent\ContosoAgent.exe'
$minimum = [version]'4.2.0.0'
 
if (Test-Path -LiteralPath $path) {
    $info = (Get-Item -LiteralPath $path).VersionInfo
    $installed = [version]::new($info.FileMajorPart, $info.FileMinorPart, $info.FileBuildPart, $info.FilePrivatePart)
    if ($installed -ge $minimum) {
        Write-Output "ContosoAgent $installed detected"
        exit 0
    }
}
exit 1

Leave Run script as 32-bit process on 64-bit clients at No unless the paths you check only exist in the 32-bit view. Enforce script signature check requires the script to be signed by a trusted publisher.

Step 6: Dependencies, supersedence and assignments

Dependencies can be added once the app exists. A dependency must itself be a Win32 app, and the dependency graph is limited to 100 apps including the app itself. With Automatically install set to Yes, Intune installs the dependency even if it isn't assigned.

Supersedence updates or replaces older apps. Turn off Uninstall previous version when the new installer upgrades in place, and turn it on when the new app replaces a different one. A supersedence graph is limited to 10 apps.

On Assignments, choose Required, Available for enrolled devices or Uninstall and add groups. For each assignment you can set:

  • End user notifications: show all toasts, only restart toasts, or hide all.
  • App availability and App installation deadline: as soon as possible or a specific date and time, in UTC or device time. Content downloads at availability and installs at the deadline.
  • Restart grace period: only offered when restart behavior is Determine behavior based on return codes or Intune will force a mandatory device restart. The default grace period is 1,440 minutes, the countdown dialog appears 15 minutes before restart by default, and snoozes default to 240 minutes.

Microsoft notes that when a Win32 app is assigned to users and needs administrator privileges or other permissions the standard user doesn't have, the installation fails. Test user-targeted assignments with a standard account before you widen them.

Verify the deployment

  1. On a test device, open Company Portal > Settings > Sync, or restart the IntuneManagementExtension service, to trigger an IME check-in.
  2. Open the logs in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs with CMTrace:
    • AppWorkload.log covers download, install and detection for Win32 apps.
    • AppActionProcessor.log shows detection and applicability checks.
    • IntuneManagementExtension.log shows check-ins and policy processing.
    • AgentExecutor.log shows PowerShell script execution.
  3. In the admin center, go to Troubleshoot + support, select the user, select the device and then Managed Apps. Select the app to see its installation status and failure details.

Troubleshooting

Symptom or errorLikely causeFix
0x87D1041C, "The application was not detected after installation completed successfully"Detection rule doesn't match the installed app, or the app was removed or self-updatedCheck the path, registry view and version in the rule; run the detection script manually as SYSTEM
Install never finishes, then failsInstaller is waiting for inputFix the silent switches; interactive installs aren't supported
Failed with exit code 1618Another Windows Installer session was runningMap 1618 to Retry
Device restarts unexpectedly1641 mapped to Hard reboot with Determine behavior based on return codesUse a restart grace period or No specific action where appropriate
Script detection always failsScript writes to STDERR, or runs in the wrong bitnessRemove error output; adjust the 32-bit setting
Uninstall command failsUses environment variablesWrap the uninstall in a script inside the package
Nothing happens on the deviceIME not installed, device in S mode, or IME can't reach IntuneCheck the IME service, prerequisites and network endpoints

Checklist

  • Source folder contains only the installer and its files; the Content Prep Tool sits elsewhere.
  • Install command tested silently, as SYSTEM, with a known exit code.
  • .intunewin built with the latest Content Prep Tool.
  • Uninstall command tested; no environment variables in it.
  • Return codes reviewed against the vendor's documented codes, including reboot and retry codes.
  • Detection rule matches only a correct installation and uses the right 32-bit or 64-bit view.
  • Assignment deadline, notifications and restart grace period chosen deliberately.
  • Results verified in AppWorkload.log and the app's install status before broad assignment.

Once applications are packaged and detected reliably, the next layer of endpoint hygiene is patching Windows itself; Intune update rings and Windows hotpatch covers that.

References

Questions people ask

What does IntuneWinAppUtil.exe actually do?

The Microsoft Win32 Content Prep Tool compresses every file and subfolder in the setup folder you point it at into a single .intunewin file. For MSI installers it also reads the information Intune needs, such as the product code. It doesn't change the installer or make it silent; you still provide the silent command line yourself.

Why does Intune report "The application was not detected after installation completed successfully"?

This is error 0x87D1041C. The installer returned a success code, but the detection rule you configured didn't find the app afterwards. Check that the rule points at the right path, registry view (32-bit or 64-bit) and version, or that the app wasn't removed after installation.

How does a custom detection script tell Intune the app is installed?

The script must exit with code 0 and write something to STDOUT. A nonzero exit code means not installed, and any output on STDERR also makes Intune evaluate the app as not installed, even if the exit code is 0.

What is the maximum size of a Win32 app in Intune?

Microsoft documents a cap of 30 GB per Windows app. If you use a PowerShell script as the installer instead of a command line, that script is limited to 50 KB.

Microsoft IntuneWin32 AppsIntuneWinAppUtilIntune Management Extension
  1. Intune Enrollment Status Page stuck: fix app and policy timeouts

    Diagnose an Intune Enrollment Status Page that hangs or times out: find the stuck phase, read the EnrollmentStatusTracking registry and IME logs, and fix the documented causes.

  2. Autopilot device preparation vs classic Autopilot: choosing the right one

    Compare Windows Autopilot device preparation and classic Windows Autopilot on join types, modes, app limits, registration, ESP and reporting, and pick the right one for each device population.

  3. Azure point-to-site VPN with Entra ID sign-in, MFA and the Azure VPN Client

    Configure an Azure VPN Gateway point-to-site connection that signs users in with Microsoft Entra ID, enforce MFA, and deploy the Azure VPN Client profile with Intune.