In one of my earlier blogs, I discussed the IME installation flow and the global retry schedule. I showed you how the retry schedule looks at the Exit Code / ExitCode to determine whether the app was installed successfully.
Troubleshooting failed Intune Win32 Apps installation | IME (call4cloud.nl)
Trigger IME to retry to install a failed Win32app | Intune (call4cloud.nl)
I decided to remove the “ExitCode” part of those blogs and dedicate a separate blog to it.
1. The ExitCode
If you have read other blogs, you know by now how we could trigger the reinstallation. If you understand how the installation flow works, looking at some Win32 installation issues will become much easier. Let’s take a look first at the Win32app installation ExitCode
This exit code from the above picture will be used to determine if the Win32App has been installed successfully. When looking at the Win32App installation flow, you will notice that this is done at the Post Detection Phase as I showed you earlier.
Besides the important ExitCode itself, how does it detect if the Win32App has been successfully installed? It all depends on how you configured your detection rule while you uploaded your nice Win32App!
There are many options to choose from: MSI, Registry, File/Folder, or just your own custom-cooked PowerShell script to detect the app after and before installation.
2. PowerShell Detection Rules and the STDOUT
As shown above, multiple detection rules are available. I will start with the PowerShell Detection Rule first.
The famous STDOUT comes into play when looking at detection rules and a custom PowerShell script. First, let’s take a look at how the STDOUT looks inside the IME log when the install fails.
LOG[[Win32App] Checked Powershell script exitCode: -1 EnforceSignatureCheck: 0 RunAs32Bit: 0 InstallExRunAs: 0, result of applicationDetected: False]
When the app is installed the Intune Agent will check the results/exit code from the script. The Intune agent will read the values that were written to the STDOUT stream. When the PowerShell detection script exits with everything EXCEPT a nice zero value, the script will fail and the Win32 App will be marked as not detected.
Let me give you an example
if((get-process "Winword" -ea SilentlyContinue) -eq $Null)
{
Write-Host "Winword is running"
exit 0
}else
{
exit 0
}
If Winword is running, it will exit the script with exit code 0 and will perform a “write-host”
*Detection method sees this as “Application is installed” because the exit code is zero BUT the STDOUT is NOT Empty
If Winword is not running, it will only exit the script with exit code 0 and nothing more
*Detection method sees this as “Application is not installed” because the exit code is zero and the STDOUT is Empty
To put it all down in a nice, simple overview
Exit code | Data read from STDOUT | Detection state |
0 | Empty | Not detected |
0 | Not empty | Detected |
Not zero | Empty | Not detected |
Not zero | Not Empty | Not detected |
3. File Detection Rule
Now that we have seen the ExitCode and the STDOUT, let’s take a look at the File and Registry Detection Rule. That’s a little bit easier. It checks if the path exists, which you configured in the detection rule.
For example, a simple File-Based detection rule to make sure OneDrive (x64) is detected after installation
After installation, the DetectionManager will check if the path you configured in the detection rule exists.
As shown above, it mentions ApplicationDetected:True, which means that the application is successfully detected after installation.
The same goes for the Registry detection rule.
4. Registry Detection Rule
In this example below, I have configured a Registry detection rule to detect if the Office 365 Apps are installed
You could wonder why I used this example. I decided to use a Win32App to deploy the Office365 Apps to our devices
Deploy the Office 365 Apps in Intune with a Win32App (call4cloud.nl)
If it detects the file path successfully it will save the Installation Status Service report in the registry:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\IntuneManagementExtension\SideCarPolicies\StatusServiceReports\
As shown above, the Win32App is successfully detected and the ErrorCode / Error Code will be zero.
5. MSI Detection Rule
It is always best practice to convert your MSI to a Win32App because mixing those could lead you into trouble. When you want to ensure your MSI converted to a Win32 app is detected successfully, you could also use the MSI detection rule. As shown below, I am using the Teams MSI product code as an example
It’s very easy to find the MSI Product code on an existing device by using PowerShell
$Installer = New-Object -ComObject WindowsInstaller.Installer; $InstallerProducts = $Installer.ProductsEx("", "", 7); $InstalledProducts = ForEach($Product in $InstallerProducts){[PSCustomObject]@{ProductCode = $Product.ProductCode(); LocalPackage = $Product.InstallProperty("LocalPackage"); VersionString = $Product.InstallProperty("VersionString"); ProductPath = $Product.InstallProperty("ProductName")}} $InstalledProducts
If you want to fetch the MSI product code from a not installed app, you could use the Applocker File information command.
Get-AppLockerFileInformation -Path 'c:\install\supportcenterinstaller.msi' | select -ExpandProperty Publisher | select ProductName,BinaryVersion,BinaryName
Conclusion
Knowing where to look for the Win32App ExitCode is very important as it could tell you a lot about how the installation itself and if it was successful or if it didn’t work!