Notify Teams Channels When Specific MDE Alerts Occur

Disclaimer: The information posted in this blog and on this website are not necessarily reflective of the views or recommendations of Microsoft. Though I am an employee of Microsoft, this is considered a personal project of mine that is not intended to be a recommendation or guide from Microsoft the company.

Introduction

In this blog post I will examine how Microsoft Power Automate can be leveraged to notify Teams chats/channels whenever MDE alerts meeting certain criteria are triggered. For example, we can choose to notify Teams channels when an alert is triggered for a specific device group, or is a specific severity, or is related to specific CVEs, or is a specific category of alert, etc. There are many possibilities here so I’m excited to dive in.

Getting Started

You will need a Power Automate Premium license to be able to access the Microsoft Defender ATP connector in Power Automate. More information about Power Automate Premium licenses found here: Types of Power Automate licenses

To begin, head over to https://powerautomate.com and click Create.

We want this flow to run whenever a new alert is generated so that our flow can evaluate whether the alert meets our criteria for generating a Teams notification. So we will choose “Automated cloud flow”.

For the trigger, search for “Defender” then choose “Triggers – Trigger when new WDATP alert occurs” then click create.

Getting the Alert Data

Now that our flow has been created, we can start adding steps. Add a new step and search for “Get alert by ID”. This step is using the Microsoft Graph Security connector, you can check out this Microsoft public documentation for more info about this connector: Microsoft Graph Security

In the Alert ID field, simply choose the “Alert Id” dynamic content. Very simple – your flow should look like this so far:

This “Get alert by ID” step will provide you with tons of dynamic content which you can use to define the criteria for generating a Teams message. Below are some examples:

This already opens up a ton of possibilities and there is even more dynamic content available, but for demonstration purposes, I want to show how you can try to get even more options if one that you’d like isn’t available here. So, as an example, I want to generate a Teams notification for alerts, but only when those alerts occur on devices belonging to a specific device group.

With our flow in its current state, I don’t see any Device Group dynamic content, so let’s add another step to get us some more dynamic content to work with. Add a new step and look for “Alerts – Get single alert”.

Note that this is using the Microsoft Defender ATP connector. You can read more about this connector here: Microsoft Defender ATP – Connector

Just like in the previous step, add the Alert Id dynamic content into the Alert ID field like this:

In testing this flow, I can see the rbacGroupName value in the output of this step:

But there is one small problem. The rbacGroupName is data that is returned from this step, however it is not available as dynamic content for some reason. Fortunately, this is a small hurdle to overcome.

Parsing the JSON

rbacGroupName is not available as dynamic content, but the data is exposed to us. In order to make it workable data, we will add a new step and search for “Parse JSON”. In the Content field paste in the below:

@{body('Alerts_-_Get_single_alert')}

And for the Schema, paste in the below:

{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": [
                "string",
                "null"
            ]
        },
        "id": {
            "type": [
                "string",
                "null"
            ]
        },
        "incidentId": {
            "type": [
                "integer",
                "null"
            ]
        },
        "severity": {
            "type": [
                "string",
                "null"
            ]
        },
        "status": {
            "type": [
                "string",
                "null"
            ]
        },
        "investigationState": {
            "type": [
                "string",
                "null"
            ]
        },
        "detectionSource": {
            "type": [
                "string",
                "null"
            ]
        },
        "detectorId": {
            "type": [
                "string",
                "null"
            ]
        },
        "category": {
            "type": [
                "string",
                "null"
            ]
        },
        "title": {
            "type": [
                "string",
                "null"
            ]
        },
        "description": {
            "type": [
                "string",
                "null"
            ]
        },
        "alertCreationTime": {
            "type": [
                "string",
                "null"
            ]
        },
        "firstEventTime": {
            "type": [
                "string",
                "null"
            ]
        },
        "lastEventTime": {
            "type": [
                "string",
                "null"
            ]
        },
        "lastUpdateTime": {
            "type": [
                "string",
                "null"
            ]
        },
        "machineId": {
            "type": [
                "string",
                "null"
            ]
        },
        "computerDnsName": {
            "type": [
                "string",
                "null"
            ]
        },
        "rbacGroupName": {
            "type": [
                "string",
                "null"
            ]
        },
        "aadTenantId": {
            "type": [
                "string",
                "null"
            ]
        },
        "mitreTechniques": {
            "type": [
                "array",
                "null"
            ]
        },
        "relatedUser": {
            "type": "object",
            "properties": {
                "userName": {
                    "type": [
                        "string",
                        "null"
                    ]
                },
                "domainName": {
                    "type": [
                        "string",
                        "null"
                    ]
                }
            }
        },
        "loggedOnUsers": {
            "type": [
                "array",
                "null"
            ]
        },
        "comments": {
            "type": [
                "array",
                "null"
            ]
        },
        "evidence": {
            "type": [
                "array",
                "null"
            ],
            "items": {
                "type": "object",
                "properties": {
                    "entityType": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "evidenceCreationTime": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "sha1": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "sha256": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "fileName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "filePath": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "processId": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "processCommandLine": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "processCreationTime": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "parentProcessId": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "parentProcessCreationTime": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "parentProcessFileName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "parentProcessFilePath": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "ipAddress": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "url": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryKey": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryHive": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryValueType": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryValue": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "registryValueName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "accountName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "domainName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "userSid": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "aadUserId": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "userPrincipalName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "detectionStatus": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "entityType",
                    "evidenceCreationTime",
                    "sha1",
                    "sha256",
                    "fileName",
                    "filePath",
                    "processId",
                    "processCommandLine",
                    "processCreationTime",
                    "parentProcessId",
                    "parentProcessCreationTime",
                    "parentProcessFileName",
                    "parentProcessFilePath",
                    "ipAddress",
                    "url",
                    "registryKey",
                    "registryHive",
                    "registryValueType",
                    "registryValue",
                    "registryValueName",
                    "accountName",
                    "domainName",
                    "userSid",
                    "aadUserId",
                    "userPrincipalName",
                    "detectionStatus"
                ]
            }
        },
        "domains": {
            "type": [
                "array",
                "null"
            ]
        }
    }
}

Defining Alert Criteria

Now we’ve got access to all sorts of workable data from our alert so this is where we get to define the conditions to trigger the Teams notifications. I will simply be generating Teams notifications if the alert belongs to a device group named “Domain Controllers”, but please let your creative juices take control here. Look through all of the available dynamic content and workable data from our Parse JSON step when considering how to define your criteria.

Add a new step and search for “Condition”. To use data from the Parse JSON step as a condition, see my example below for using the rbacGroupName. If you also wish to use Device Groups as your condition, you can simply add the below expression into your condition:

@body('Parse_JSON')?['rbacGroupName']

Creating the Teams Notification

Now we’ve got our alert data in order and we’ve got our criteria defined for generating a Teams message, let’s go ahead and customize that Teams message. On the Yes side of the condition, add an action and search for “Post message in a chat or channel”.

You can choose to post the message as the Flow bot or as a specific user then you can choose to post the message in a channel or a group chat. Once you’ve chosen your chat or channel, you can begin crafting the message.

Some useful things could be the alert title, description, severity, creation time, category, and a hyperlink to the alert page. Here’s how mine turned out:

Thanks for reading! Hopefully you’ve enjoyed this blog post and gotten some ideas for your own MDE Power Automate flows! If you liked this, you may also enjoy some of my previous posts too!

Creating Custom Email Reports with Advanced Hunting and Power Automate

Taking Actions on MDE Devices via PowerShell and MDE API

One thought on “Notify Teams Channels When Specific MDE Alerts Occur

Leave a comment