Troubleshoot Intune Win32Apps with multiple detection rules

If you’re using Win32 apps with more than one detection rule, it’s advantageous to quickly determine which detection rule is failing. We get this information by inspecting the IME log on an affected device, but you need to know what to look for. The Intune Management Extension log is located in %programdata%\Microsoft\IntuneManagementExtension\logs\IntuneManagementExtension.log. It contains tons of great information on intune-related activity. Among that information are details on app deployments and their detection rules. Before we take a look, let’s quickly review the two ways we can create detection rules:

  1. The built-in rule types of MSI, File/Folder, and Registry. You can use any combination of these to create detection rules for an MSI product code presence, if a file/folder exists, or if a reg key/value exists. In most cases, you can use these built-in rules to satisfy your app detections.
  2. Custom detection scripts. These are exactly what they sound like. A custom PowerShell script you write to detect one or more properties and return an Exit code of 0 or 1 with some output text. This lets Intune know if the detection rule passed or failed (0 being passed, and 1 being failed).

Often times you only need a single detection rule and it can be satisfied easily with an MSI or Registry detection rule. However, if you need to get more detailed, like detecting the date stamp on a file, or detecting a registry value in a hive that doesn’t have a native drive mapping in PowerShell, then we need to use a custom detection script. We will go over how to pull details from the IME log using both methods.

Troubleshooting native detection rules (File/Registry/MSI)

There are a few shortcuts you can use to quickly find your detection rule details in the IME log. You can search for “[Win32App] Processing App” and scroll through the results until you find your app, or you can search by your app’s name, everything after the entry starting with “[Win32App] Processing app” will contain details on the installation and detection. This will get you to the proper starting point in the log:

Next, you can manually look at the log entries coming after your app. In this example, I am looking for a reg value. You’ll want to look for entries starting with “Got Reg Value” and “Checked Reg Path” to see if those show as detected. File rules are similar and you want to look for “checked under path:”, and MSI detection rules start with “Checked ProductCode”. You can also search directly for those phrases and sort through your log until you find anywhere you suspect they failed. Additionally, you can search for “applicationdetected: false” to look for failed detection entries. You can then sort through the detection rules for your app to determine which individual rule is failing.

Here is an example of a detection failure:

And a file path example:

And an MSI example:

Troubleshooting custom detection scripts:

Custom Detection rules don’t give us as much data (unless you get more creative with your scripts). Here is an example of a custom detection script I recently created. We have it looking for several files and reg values, and returning some basic output with exit codes of 0 or 1 for successfully detected, or values missing.

$file1 = Test-Path "C:\ProgramData\Toast\ToastScript.cmd"
$file2 = Test-Path "C:\ProgramData\Toast\NotificationXML.xml"
$file3 = Test-Path "C:\ProgramData\Toast\Button1-Downloads.ps1"
$file4 = Test-Path "C:\ProgramData\Toast\Button2-Gridview.ps1"
$file5 = Test-Path "C:\ProgramData\Toast\Button3-Delete.ps1"
$file6 = Test-Path "C:\ProgramData\Toast\smb.png"
$file7 = Test-Path "C:\ProgramData\Toast\missingfile.png"
New-PSDrive -PSProvider Registry -Name HKCR -Root HKEY_CLASSES_ROOT
$reg1 = Get-ItemPropertyValue "HKCR:\PowerShell" -Name "(Default)"
$reg2 = Get-ItemPropertyValue "HKCR:\PowerShell\defaulticon" -Name "(Default)"
$reg3 = Get-ItemPropertyValue "HKCR:\PowerShell\shell\open\command" -Name "(Default)"
If (((( $file1 -and $file2 -and $file3 -and $file4 -and $file5 -and $file6 -and $file7 -eq 'True' ) -and ($reg1 -eq "URL:PowerShell Protocol")) -and ($reg2 -eq "powershell.exe,1")) -and ($reg3 -eq "C:\ProgramData\toast\ToastScript.cmd %1"))
{
    Write-Output "Files and Reg values exist"
    exit 0
}
else {
    Write-Output "Missing Files or Registry Values"
    exit 1
}

First, you need to locate the log entries we are interested in. You can search for your app name, or by Win32app Processing app like we did in the previous section, and find the beginning entries for your app. In this case, “Toast Files – Downloads Folder Notification”. Here you can see where the app is being processed to see if it’s detected, and then shortly after in the log entries, you can see the custom detection script downloaded:

When using a custom detection script, it gets harder to see which rule is failing. Intune is simply using the script as a pass/fail, so if you have multiple rules in your script, but only one is failing, you won’t get details on which rule is failing (not without a little extra work at least). Here is an example where a custom detection script is checking for numerous files, and a few reg entries. I specifically changed the script to look for a file that doesn’t exist for this demonstration. We can see in the IME log the detection script is downloaded to the local machine:

Several entries down, we can see two entries starting with “Checked Powershell Script” where we can get the script output, and the exit code, which dictates if the app was detected or not. The important thing to see here is that we get the PowerShell output from our script, which is “Missing Files or Registry Values” in this example. We can adjust this output so we can get more details on which part is failing:

And the result showing the detection failed:

So, we don’t get details on the failure since our script is only giving limited output. However, with some additional work to your detection scripts, you can get more details. For example, if the app fails to be detected, you’ll want to know which items are not detected in your script. People who are more PowerShell savvy than me probably know cleaner or better ways to do this, but I used a hash table. With some additional lines in the PowerShell script, we can output what we are trying to detect, and the values of those items. Using this method, the IME log will return the specifics of each rule you have. In my case, I wanted to see a true/false if the files existed, and the values of some registry entries. This detection script has 10 items, so it allows us to see which of those items are failing. Here is our modified detection script:

$ToastScript = "C:\ProgramData\Toast\ToastScript.cmd"
$NotificationXML = "C:\ProgramData\Toast\NotificationXML.xml"
$Button1 = "C:\ProgramData\Toast\Button1-Downloads.ps1"
$Button2 = "C:\ProgramData\Toast\Button2-Gridview.ps1"
$Button3 = "C:\ProgramData\Toast\Button3-Delete.ps1"
$smb = "C:\ProgramData\Toast\smb.png"
$MissingFile = "C:\ProgramData\Toast\missingfile.png"
$regvalue1 = '"HKCR:\PowerShell" -Name "(Default)"'
$regvalue2 = '"HKCR:\PowerShell\defaulticon" -Name "(Default)"'
$regvalue3 = '"HKCR:\PowerShell\shell\open\command" -Name "(Default)"'

$file1 = Test-Path $ToastScript
$file2 = Test-Path $notificationxml
$file3 = Test-Path $button1
$file4 = Test-Path $button2
$file5 = Test-Path $button3
$file6 = Test-Path $smb
$file7 = Test-Path $missingfile

New-PSDrive -PSProvider Registry -Name HKCR -Root HKEY_CLASSES_ROOT
$reg1 = Get-ItemPropertyValue "HKCR:\PowerShell" -Name "(Default)"
$reg2 = Get-ItemPropertyValue "HKCR:\PowerShell\defaulticon" -Name "(Default)"
$reg3 = Get-ItemPropertyValue "HKCR:\PowerShell\shell\open\command" -Name "(Default)"

$HashTable = @{
$ToastScript = $file1
$NotificationXML = $file2
$Button1 = $file3
$button2 = $file4
$button3 = $file5
$smb = $file6
$MissingFile = $file7
$regvalue1 = $reg1
$regvalue2 = $reg2
$regvalue3 = $reg3
}

If (((( $file1 -and $file2 -and $file3 -and $file4 -and $file5 -and $file6 -and $file7 -eq 'True' ) -and ($reg1 -eq "URL:PowerShell Protocol")) -and ($reg2 -eq "powershell.exe,1")) -and ($reg3 -eq "C:\ProgramData\toast\ToastScript.cmd %1"))
{
    Write-Output "Files and Reg values exist"
    exit 0
}
else {
    Write-Output "Missing Files or Registry Values"
    Write-Output $HashTable
    exit 1
}

And how the IME displays the results of our custom detection script, showing us details on the detection of our files and registry values:

And just so you can see how it matches the PowerShell output if we manually run the script: