Skip to content
June 5, 2026 Mid-Level (3-5 years) Error Reference

Fix Intune Win32 App Timeout 0x87D300C9

Troubleshoot Intune Win32 app deployments that show The unmonitored process is in progress, however it may timeout, error 0x87D300C9, in Company Portal or the Intune admin center.

Fix Intune Win32 App Timeout 0x87D300C9

Intune Win32 app error 0x87D300C9 usually appears when Company Portal or the Intune admin center reports this message:

The unmonitored process is in progress, however it may timeout. (0x87D300C9)

Do not start by rebuilding the .intunewin package. This error usually means the Intune Management Extension started your command, but the process it launched did not return control in the way Intune expects. In practice, that often comes from an installer that spawned another process, waited on user input, opened a child setup engine, wrote logs to a blocked path, or ran with switches that work interactively but not as SYSTEM.

Use this runbook when a Win32 app installs manually, but fails from Company Portal, required assignment, or ESP with 0x87D300C9.

Quick Fix checklist

Work in this order on one affected test device:

  1. Confirm the Intune failure is 0x87D300C9, not a detection-only failure such as 0x87D1041C.
  2. Copy the exact install command from the Win32 app properties in Intune.
  3. Test the command locally as SYSTEM, not only from an elevated admin PowerShell prompt.
  4. Make the installer fully silent. Remove any switch that can open a prompt, restart dialog, browser window, or licensing screen.
  5. If the installer spawns a child process, wrap it with a script that waits for the real setup process and exits with the final code.
  6. Set a sane Intune install behavior and install timeout. Do not hide a broken command by setting an extreme timeout.
  7. Write logs to C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\VendorApp or another machine-wide path that SYSTEM can create.
  8. Check IntuneManagementExtension.log, AppWorkload.log, and AgentExecutor.log under C:\ProgramData\Microsoft\IntuneManagementExtension\Logs.
  9. Confirm the command exits with 0 or a return code mapped in Intune, such as 3010 for soft reboot.
  10. Sync the device, restart the Microsoft Intune Management Extension service if needed, then retry the assignment.

Root Cause

0x87D300C9 is a process monitoring problem during Win32 app enforcement. Intune calls the install command through the Intune Management Extension. The extension expects the command to run, finish, and return a code that can be interpreted against the app’s return-code table.

The failure usually falls into one of these buckets:

  • The install command starts a bootstrapper and exits before the real installer finishes.
  • The install command starts a bootstrapper that never exits because it is waiting on a child process.
  • A supposedly silent installer is showing a hidden prompt in session 0.
  • The command works as a signed-in admin but fails as SYSTEM.
  • The installer writes logs or temp files to a user profile path that does not exist for SYSTEM.
  • A wrapper script uses Start-Process without -Wait or without passing the child process exit code back to Intune.
  • The app needs network content, proxy access, or a mapped drive that is not available to the Intune Management Extension.
  • The install timeout is shorter than the real install time for that package on slow hardware.

Microsoft’s Win32 troubleshooting guidance points admins to the Intune Management Extension logs for app check-in, installs, applicability, detection, and PowerShell execution. Microsoft also documents that Win32 app processing includes detection, applicability, content download, install command execution, and post-install detection. 0x87D300C9 sits in the install execution part of that chain.

Logs and where to check

Start in the Intune admin center:

Intune admin center > Apps > Windows > select the Win32 app > Monitor > Device install status

Open the affected device record and confirm the status text includes 0x87D300C9 or the unmonitored process message.

On the Windows endpoint, collect these logs:

C:\ProgramData\Microsoft\IntuneManagementExtension\Logs

Focus on:

Log fileWhat to look for
IntuneManagementExtension.logPolicy check-in, app assignment, command execution flow, enforcement state
AppWorkload.logWin32 app install, applicability, detection, and reporting details
AppActionProcessor.logApp action processing and detection/applicability checks
AgentExecutor.logPowerShell execution when install or requirement scripts are involved
ClientHealth.logIntune Management Extension health issues that can confuse app retries

Use this PowerShell to pull the useful lines:

$LogRoot = 'C:\ProgramData\Microsoft\IntuneManagementExtension\Logs'
$Terms = @(
  '0x87D300C9',
  'unmonitored process',
  'timeout',
  'install command',
  'process',
  'exit code',
  'enforcement'
)

Get-ChildItem $LogRoot -Filter '*.log' |
  Select-String -Pattern $Terms -SimpleMatch |
  Select-Object Path, LineNumber, Line |
  Format-List

Then search by app name or app ID:

$AppName = 'Contoso VPN Client'
Get-ChildItem 'C:\ProgramData\Microsoft\IntuneManagementExtension\Logs' -Filter '*.log' |
  ForEach-Object {
    Select-String -Path $_.FullName -Pattern $AppName -Context 8,12
  }

A typical broken flow looks like this:

Install command line: setup.exe /silent
Process started.
Child installer launched.
Parent process is still running or no final exit code is returned.
The unmonitored process is in progress, however it may timeout.

That tells you the fix is the command wrapper, not the assignment group.

Test the install command as SYSTEM

An elevated admin console is not enough. Intune installs Win32 apps through the Intune Management Extension, which runs as SYSTEM for system-context apps. A command can pass as your admin account and fail for Intune because environment variables, certificates, network access, and profile paths are different.

Use PsExec from Microsoft Sysinternals on a test device:

# Run from an elevated PowerShell prompt after downloading PsExec.
.\PsExec.exe -i -s powershell.exe

In the new SYSTEM PowerShell window, move into the extracted test folder and run the exact Intune command:

whoami
Set-Location 'C:\Temp\ContosoApp'
.\install.cmd
$LASTEXITCODE

If the command hangs, opens a UI, waits for input, or returns a code Intune does not accept, you have reproduced the failure outside Intune.

Fix silent switch and child process problems

Many vendor installers are bootstrappers. setup.exe /quiet might start msiexec.exe, installshield.exe, update.exe, or another vendor process. If your wrapper exits too early, Intune can start detection while the real install is still running. If your wrapper never exits, Intune eventually reports timeout behavior.

Use a wrapper that waits and returns the real code. For an MSI, keep it simple:

$Msi = Join-Path $PSScriptRoot 'ContosoClient.msi'
$Log = 'C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\ContosoClient-install.log'

$Process = Start-Process -FilePath 'msiexec.exe' `
  -ArgumentList "/i `"$Msi`" /qn /norestart /L*v `"$Log`"" `
  -Wait `
  -PassThru

exit $Process.ExitCode

For an EXE bootstrapper, test the vendor’s documented silent switches and still wait for completion:

$Installer = Join-Path $PSScriptRoot 'ContosoSetup.exe'
$Log = 'C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\ContosoClient-setup.log'

$Process = Start-Process -FilePath $Installer `
  -ArgumentList "/quiet /norestart /log `"$Log`"" `
  -Wait `
  -PassThru

exit $Process.ExitCode

If the vendor bootstrapper exits before a child process finishes, wait for the child by name after launch. Keep the wait bounded so a broken installer cannot run forever:

$Installer = Join-Path $PSScriptRoot 'setup.exe'
$Process = Start-Process -FilePath $Installer -ArgumentList '/silent' -PassThru
$Process.WaitForExit()

$Deadline = (Get-Date).AddMinutes(20)
do {
  $Child = Get-Process -Name 'ContosoSetup','msiexec' -ErrorAction SilentlyContinue
  if (-not $Child) { break }
  Start-Sleep -Seconds 5
} while ((Get-Date) -lt $Deadline)

if (Get-Process -Name 'ContosoSetup' -ErrorAction SilentlyContinue) {
  Write-Error 'Contoso setup process did not finish before timeout.'
  exit 1603
}

exit $Process.ExitCode

Do not use Start-Process without -Wait unless you have a deliberate reason and a follow-up wait. This is one of the most common causes of Intune app timing failures.

Fix log path and temp path issues

Avoid writing installer logs to the current user’s desktop, downloads folder, or %TEMP% when packaging for Intune. In system context, those paths are not the admin profile you tested with.

Use a machine-wide folder:

$LogDir = 'C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\ContosoClient'
New-Item -Path $LogDir -ItemType Directory -Force | Out-Null
$Log = Join-Path $LogDir 'install.log'

If the vendor installer insists on a temp folder, set one explicitly:

$TempDir = 'C:\ProgramData\ContosoClient\Temp'
New-Item -Path $TempDir -ItemType Directory -Force | Out-Null
$env:TEMP = $TempDir
$env:TMP = $TempDir

Then rerun the command as SYSTEM. If it only fails when the log path points to a user folder, the package was never safe for Intune deployment.

Check Intune return codes and timeout

In the Win32 app properties, review:

Apps > Windows > select app > Properties > Program
Apps > Windows > select app > Properties > Return codes

Make sure common installer return codes are mapped correctly:

Return codeMeaningIntune handling
0SuccessSuccess
3010Soft reboot requiredSoft reboot
1641Hard reboot initiatedHard reboot
1603Fatal MSI errorFailed
1618Another install in progressRetry or failed depending on policy

If the installer normally takes 25 minutes on older hardware, set the Intune install timeout above that reality. But use this carefully. Extending the timeout is valid for slow installs; it is not a fix for a command that never returns.

Validate detection after the install finishes

After solving 0x87D300C9, run detection. Intune still needs proof that the app installed. If detection is wrong, the next failure may look like a different error.

Check the same evidence your detection rule uses:

# File detection example
Test-Path 'C:\Program Files\Contoso\ContosoClient.exe'

# Registry detection example
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' |
  Where-Object DisplayName -like '*Contoso*' |
  Select-Object DisplayName, DisplayVersion, PSChildName

# 32-bit app on 64-bit Windows example
Get-ItemProperty 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' |
  Where-Object DisplayName -like '*Contoso*' |
  Select-Object DisplayName, DisplayVersion, PSChildName

If the install now exits cleanly but Intune still reports failure, switch to a detection-rule investigation.

Graph and PowerShell checks for blast radius

Use Microsoft Graph PowerShell to identify whether this is one device or a broader package issue. The exact app reporting endpoints can change, but the workflow is consistent: find the app, inspect device install states, then compare failures by OS build, device model, and assignment group.

Connect-MgGraph -Scopes 'DeviceManagementApps.Read.All','DeviceManagementManagedDevices.Read.All'

$AppName = 'Contoso VPN Client'
$App = Get-MgDeviceAppManagementMobileApp -Filter "displayName eq '$AppName'"
$App | Select-Object Id, DisplayName, CreatedDateTime, LastModifiedDateTime

For a quick local export from the Intune admin center, use:

Apps > Windows > select app > Monitor > Device install status > Export

Look for patterns:

  • Only Company Portal installs fail, but required installs succeed.
  • Only standard users fail, but ESP or system context succeeds.
  • Only one hardware model fails because the installer waits on a driver prompt.
  • Only remote users fail because the package tries to reach an internal share.
  • Only devices with another install in progress fail because MSI is locked.

Those patterns tell you whether to fix the package, the assignment, prerequisites, network access, or install timing.

Prevention

To avoid 0x87D300C9 in future Intune Win32 deployments:

  • Test every install command as SYSTEM before uploading the final package.
  • Prefer MSI packages with explicit msiexec /i, /qn, /norestart, and /L*v logging when available.
  • For EXE installers, document the vendor’s silent switches in the package folder.
  • Always return the child process exit code from wrapper scripts.
  • Never call installers from a user profile, mapped drive, or temporary download path.
  • Log to C:\ProgramData so the Intune Management Extension can write and admins can collect the file later.
  • Keep detection rules separate from install fixes. Fix one failure mode at a time.
  • Pilot to a small dynamic group before assigning broadly.
  • Export failed device states after the pilot and group failures by model, OS build, user context, and network location.
  • Keep the .intunewin source folder under version control with install, uninstall, and detection scripts.

Field-tested remediation plan

Use this sequence when production users are blocked:

  1. Pause expansion of the assignment. Do not delete the app unless the package is unsafe.
  2. Pick one failed device with the exact 0x87D300C9 message.
  3. Reproduce the install as SYSTEM using the exact command from Intune.
  4. Add a wrapper script that waits, writes logs to C:\ProgramData, and returns the real exit code.
  5. Verify the wrapper returns 0 or another mapped code.
  6. Confirm detection succeeds locally.
  7. Replace the Intune install command or upload a revised .intunewin package.
  8. Deploy to a test group first.
  9. Review AppWorkload.log and the Intune device install status.
  10. Resume broad assignment only after the test group reports installed.

Sources

  • Microsoft Learn: Troubleshoot Win32 Apps in Microsoft Intune.
  • Microsoft Learn: Support Tip - Understanding the flow behind deployment, delivery, and processing of a Win32 application through Intune.
  • Microsoft Q&A: The unmonitored process is in progress, however it may timeout. (0x87D300C9) for Intune Win32 app deployment through Company Portal.
Was this helpful?

Comments

Comments are coming soon. Have feedback? Reach out via the About page.