Skip to main content

Get Free, Multi-Tenant Security Alerts in Teams With a Graph API App and a PowerShell Webhook

Nick Ross3 min read
Getting Microsoft Security Alerts in Teams

TL;DR

  • A registered Azure AD app with delegated Microsoft Graph Security permissions provides the authentication token a PowerShell script uses to read security alerts.
  • An Incoming Webhook in a Teams channel plus a scheduled PowerShell script delivers M365 and Azure security alerts with no running cost, unlike the Azure Logic App approach.
  • You can run all alerts through one Teams channel using a single webhook (the script captures tenant IDs to tell customers apart) or use one channel per tenant.
  • Task Scheduler runs the script on whatever interval you choose; save a separate file per customer so each tenant's App ID is captured.

You can pipe every Microsoft 365 and Azure security alert into a Teams channel without paying for an Azure Logic App. The trade is a little setup: register an app for Graph authentication, add an Incoming Webhook to a Teams channel, then schedule a PowerShell script to do the posting. The result spans all your tenants and costs nothing to run. This guide walks through both halves, the app registration and the webhook, end to end.

Teams logo
Security alerts posted in a Teams channel feed

These alerts cover ALL SECURITY ALERTS reported in 365 and Azure, gathered through the Microsoft Security Graph API (opens in new tab) and posted with a webhook in Teams. The approach here was derived from ideas originally conceived by the blogger known as The Lazy Administrator; his site (opens in new tab) has some great articles.

The Microsoft Graph Security API connects multiple security solutions to make it easier to correlate alerts, get rich contextual information, and simplify automation and investigations. The benefits for MSPs:

  • Streamlined integration with security operations tools, workflows, and reporting.
  • Security alerts spanning both Microsoft 365 and Azure.
  • Reduced deployment and maintenance time and effort.
  • Automated response to alerts by taking action on threats.
  • Ability to deliver more value to customers.
  • Real-time alerts in Microsoft Teams.

Part 1: Register the app that authenticates to Graph

The Microsoft Graph API uses a registered app to generate authentication tokens into your tenants. First, create the app and give it permission to read security data.

Sign in to Azure AD

Go to the Azure AD portal (opens in new tab), sign in with a global admin, and click the Azure Active Directory tab.

Azure Active Directory tab in the portal

Register a new app

Click App Registrations, then +New Registration.

New app registration

Name the app and scroll to the Redirect URI section. Select Public Client from the dropdown and paste this into the text field: urn:ietf:wg:oauth:2.0:oob

Configuring the app redirect URI as a public client

Take note of the Application (Client) ID and paste it into a notepad.

Copying the application client ID

Click API Permissions > Add Permissions.

Add API permissions

Choose Microsoft Graph, then Delegated Permissions.

Choosing Microsoft Graph delegated permissions

Scroll to the Security section and select all permissions.

Selecting all security permissions

Click Grant Consent and confirm the success message.

Granting admin consent
Consent success confirmation

Part 2: Wire up the PowerShell webhook to Teams

The PowerShell webhook to Teams gives you:

  • Real-time security alerts spanning your tenants' M365 and Azure subscriptions
  • No cost to run
  • Name, Description, Severity, and the names of users causing the alerts where applicable
Security alert message format in Teams

Decide how you will organize alerts

First, configure the webhook in a Teams channel. Ideally that is a helpdesk or security channel dedicated to monitoring security alerts. Two ways to manage them:

  • One channel, one webhook, across all customers. The output captures tenant IDs, so you can differentiate customers.
  • One channel per tenant. This separates alerts by org rather than funneling everything through one channel, which is more ideal if you have many customers or many alerts. Use the multi-tenant functionality in Teams to toggle between tenants.

Create the Incoming Webhook

Once the team is created, click the + icon, then More Apps.

Adding an app to the Teams channel
Browsing more apps in Teams

Search for Webhook and select Incoming Webhook.

Selecting Incoming Webhook

Click Install, then Setup.

Installing the Incoming Webhook
Setting up the Incoming Webhook

Add a name and a custom image if you want, then click Create. On the page that follows, copy the URL.

Naming the webhook
Copying the generated webhook URL

Grab and modify the script

Now grab the script that pushes alerts to your Teams channel from GitHub here (opens in new tab).

The PowerShell script in GitHub

Make two edits:

  1. Line 73: enter your App ID for the app you created in Part 1.
  2. Line 247: enter the webhook you copied in this section.
Editing the App ID on line 73
Editing the webhook URL on line 247

Install modules and run

Open PowerShell as Admin and run the script. Install the two required modules if you do not already have them:

powershell
Install-Module AzureAD
Install-Module MicrosoftGraphSecurity

Run the script you modified from GitHub. You will be prompted for a UPN; enter a global admin UPN.

Running the script and entering a global admin UPN

When the script completes, it returns a new command line. Pop back to your Teams channel and you should see the alert messages in your feed.

Alert messages appearing in the Teams feed

Schedule it

Use Task Scheduler to run the command at whatever interval you choose: once a day, every 30 minutes, or whatever fits. Save a separate file name for each customer so you capture the different App IDs across tenants.

Creating a scheduled task to run the script

Frequently asked questions

Is this method really free?

Yes. Unlike the Azure Logic App approach, the registered app, the Teams Incoming Webhook, and a Task Scheduler job have no Azure consumption cost. The only inputs are the App ID and webhook URL you paste into the script.

Which PowerShell modules do I need?

AzureAD and MicrosoftGraphSecurity. Install them with Install-Module AzureAD and Install-Module MicrosoftGraphSecurity before running the script.

How do I separate alerts from different customers?

Either use one Teams channel with one webhook across all customers and rely on the tenant IDs the script captures in the output, or use a separate channel per tenant and toggle between them with multi-tenant Teams. For many customers or high alert volume, one channel per tenant is cleaner.

What permissions does the registered app need?

Microsoft Graph delegated permissions for the entire Security section, with admin consent granted.

Alerts tell you something already happened. Posture tells you what is about to.

A Teams feed of security alerts is reactive by design. CloudCapsule checks 250+ controls across every tenant you manage in about 60 seconds each, so you close the gaps before they generate the alert.

Run a free scan
Nick Ross

Written by

Nick Ross

CEO · Microsoft MVP · Founder, T-Minus 365

Nick is not just a CEO, he's a respected thought leader and influencer in the MSP space. Tens of thousands of MSPs learn through his YouTube channel, T-Minus365. Nick has been honored as a three-time Microsoft MVP for his educational content; his expertise and influence are the backbone of our mission, ensuring that you are in the best hands when it comes to security.

Nick joined Pax8 in 2017, where he would ultimately oversee product management for PSA and Microsoft integrations. Following his tenure at Pax8, Nick has continued to demonstrate his leadership prowess as an executive at various MSPs, culminating in his most recent role at Sourcepass.

Nick holds a Bachelor's Degree in Business Management from Florida State University, as well as a Minor Degree in Entrepreneurship. In his free time, Nick is an avid hiker, reader, and fitness-junkie.

Keep reading