Receive Teams Notifications with Details of Failed Custom Detection Scripts or Proactive Remediations

One big blog post I’ve been working on has spawned a couple of other smaller ideas, including this. There have been times when a complex custom application or customization needs to be deployed to endpoints. For applications and certain customizations, Win32 apps are usually the best way. However, this solution can also be applied to a proactive remediation script. This whole idea came to me by bending the rules of what a custom detection script is really supposed to do. Technically, a custom detection script is still executed on the endpoint itself. Therefore, can we have it do more than simply detect the presence of certain objects. I created a post several weeks ago that described how we troubleshoot custom detection scripts with multiple rules (Troubleshoot Intune Win32Apps with multiple detection rules – SMBtotheCloud). For example, you may want to detect the presence of a file, registry key, and also have some PowerShell output, which together made up the entire detection for your software/customization. Sure, we could look at the IME log on the affected devices to determine which portion of the rule is failing, but it is much more convenient to have that data sent to us when the detection rule fails right in Teams.

I also want to mention that this is not a perfect solution. Before a Win32 app is installed, the custom detection script runs to check for detection. This determines if Intune will proceed with the installation or not. So, you will always receive an initial failure for new machines or new apps. The notification for new apps and machines should be easy to point out since every custom detection rule will probably not be satisfied. We can cushion this a little by creating a dummy file somewhere on the initial run of the detection script. We could then craft our output differently if that file exists, so the notifications appear different after that initial detection script run. I didn’t go that deep here, but it would be an easy way to distinguish the initial detection script run versus subsequent runs if there is a failed rule. If I have more time down the road, I may try to polish this a little more. If anything, this can serve as a template for other ideas. Here’s how to set this all up.

Configuring the Teams Webhook:

At a high level, Teams incoming webhooks allow external services to send properly formatted JSON data directly to a Teams channel. If you’re interested in learning more, visit this link – Webhooks and connectors – Teams | Microsoft Learn. The first thing we need to do is create our webhook. From Teams, right-click on the channel where you want to receive the notifications and select connectors.

Search for and Create an Incoming Webhook:

Provide a name for the Webhook and add a custom image if you’d like. The name is what will appear on the Teams messages. Click Create.

Copy and Save the URL, and then click Done. The Webhook creation is finished.

The Custom Detection Script:

The custom detection script is no different than what we would normally use, but in the else statement, we add some additional actions. I had the idea of how I wanted to accomplish this, but I needed to figure out how to send a properly structured message via an incoming webhook with PowerShell. For that, I read through this post – How to Send a Message to Teams Channel with PowerShell? | Windows OS Hub (woshub.com). Now that I had a basic understanding and a good example, we can craft our custom detection script. I should note that this script is purely an example to show how this works. The script is meant to fail so we can generate the Teams message. There are some variables you will want to change before you test against your apps. It’s also available on github here.

  1. The three variables $program1, $file1, and $reg1 are example values for PowerShell output, a file, and a registry key you’re looking for. Adjust these for your rules.
  2. $application should be the name of your Win32 app, which will show in the Teams notification.
  3. Paste your webhook URL as the value of the $myTeamsWebhook variable
  4. You can customize everything under “Text” if you’d like. The way I have it formatted, it will display the hostname of the device, the name if the application based on the $application variable, and the details of the failure. We will see True/False if file and reg paths are detected, and also see the output of our $program variable. This allows you to determine which of the multiple rules has failed:
$program1 = $chrome = Get-Package -name '*zoom*' -ErrorAction SilentlyContinue | select -ExpandProperty "Name"
$File1 = "c:\temp\file1.txt"
$Reg1 = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP"
$filedetect = Test-Path $File1
$regdetect = Test-Path $Reg1
#
If (($filedetect -and $regdetect -eq $true) -and ($program1 -ne $null)) {
    Write-Output "App Detected"
    exit 0
}
else {
$hostname = hostname
$application = "MyWin32App"
$myTeamsWebHook  = "YOUR WEBHOOK URL"
$webhookMessage = [PSCustomObject][Ordered]@{
"themeColor" = '#0037DA'
"title"      = "Win32 App No Longer Detected"
"text" = "`n
Device: $Hostname `n
Application: $application `n
Failure Details: `n
$File1 = $filedetect `n
$Reg1 = $regdetect `n
Get-Package Name: $program1"
}
$webhookJSON = convertto-json $webhookMessage -Depth 50
$webhookCall = @{
"URI"         = $myTeamsWebHook
"Method"      = 'POST'
"Body"        = $webhookJSON
"ContentType" = 'application/json'
}
Invoke-RestMethod @webhookCall
exit 1
}

An Example Teams Notification:

Let’s do a test against the installation of Zoom and see what happens. We can see here the initial detection failure before the app gets installed, and then another one after the intentional failure of the detection script. As I mentioned earlier, you will receive at least one detection failure for new application installs, and then more if the app detection fails, like in the GIF below. If you want to distinguish between the initial detection run and subsequent runs that fail, you’ll need to get creative with some kind of indicator on the local machine and detection script that makes it known the script has already run at least once.