One of the more confusing situations in enterprise software deployment is when an application installs successfully, but the deployment platform reports it as failed.
The application is present on the device, the detection rule confirms the installation, and the user can launch it without any issues. From every practical perspective, the deployment was successful. Yet Microsoft Intune, Configuration Manager, or another deployment solution still displays a failed status.
In many cases, the problem is not the package itself.
It is the installer’s exit code.
Understanding Installer Exit Codes
Every installer returns an exit code after it finishes running. Deployment solutions use these return codes to determine whether the installation was successful, requires a reboot, or failed.
The most common exit codes are familiar to every packaging engineer:
- 0 – Installation completed successfully.
- 3010 – Installation completed successfully, but a restart is required.
These codes are recognized by deployment platforms and processed correctly without any additional configuration.
However, not every installer follows these conventions.
The challenge with custom exit codes
Software vendors are free to define their own exit codes.
Instead of returning 0, an installer may return a vendor-specific value even though the installation completed successfully. For that installer, the exit code represents an expected outcome rather than an error.
The deployment platform, however, has no way of knowing that.
Unless it has been explicitly configured otherwise, any unknown non-zero exit code is typically interpreted as a failed installation.
This creates a misleading situation. For administrators, this often means unnecessary troubleshooting, repeated deployment attempts, and time spent investigating an issue that does not actually exist.
How we handle custom exit codes
Handling installer exit codes is an important part of the application packaging process.
Before finalizing a package, we verify how the installer behaves and which exit codes it returns. This includes reviewing the vendor’s documentation, validating installation logs, and confirming the actual installation result rather than relying solely on the deployment status.
When using PSAppDeployToolkit v4, the most common approaches are -SuccessExitCodes and -IgnoreExitCodes.
If an installer returns a vendor-specific exit code that has been verified as a successful installation result, it can be explicitly added to the list of accepted success codes:
Start-ADTProcess -FilePath "$($adtSession.DirFiles)\Setup.exe" -ArgumentList "/S" -SuccessExitCodes 1,2This tells PSAppDeployToolkit to treat exit codes 1 and 2 as successful process results instead of reporting them as failures.
PSAppDeployToolkit also supports the -IgnoreExitCodes parameter. Unlike -SuccessExitCodes, it allows ignoring not only specific exit codes, but also all exit codes by using an asterisk (*):
Start-ADTProcess -FilePath "$($adtSession.DirFiles)\Setup.exe" -ArgumentList "/S" -IgnoreExitCodes '*'This prevents any installer exit code from failing the wrapper and should therefore be used with caution.
Always verify custom exit codes through testing and vendor documentation before treating them as successful or ignoring them. Because every installer behaves differently, assumptions can easily lead to incorrect deployment results.
Accurate reporting is part of a successful package
A deployment package should do more than install an application silently. It should also communicate the installation result accurately to the deployment platform.
Properly handling custom exit codes eliminates false deployment failures, improves reporting accuracy, and reduces unnecessary troubleshooting for IT administrators. It also ensures that deployment dashboards reflect the actual state of the environment, allowing teams to focus on genuine installation issues instead of investigating misleading deployment results.
Sometimes, the difference between a successful deployment and a reported failure is not the installation itself.
It’s simply how the installer’s exit code is interpreted.
Author
Liudmyla Boldak
