There are few things worse for an IT Administrator than discovering a major Exchange Online or Microsoft Teams outage because the helpdesk phone is ringing off the hook. In a modern IT environment, reactive support is a recipe for frustrated users and stressed support teams.
You need to know about Microsoft 365 service degradations before your users do. By combining the power of the Microsoft Graph PowerShell SDK and Power Automate Teams Alerts (Workflows), you can build a fully automated, proactive monitoring system. When Microsoft reports an issue, your IT Operations channel will ping instantly.
In this guide, we will walk you through setting up an automated pipeline that queries Microsoft 365 Service Health and pushes real-time Adaptive Card alerts to a Teams channel.
The Proactive Alert Workflow
Here is how we transform a silent backend API update into an actionable, real-time alert for your IT team:
Benefits of Automated Microsoft 365 Service Health Monitoring
- Detect outages before users report them: Shift from reactive helpdesk tickets to proactive communication.
- Reduce MTTR for Microsoft 365 incidents: Instantly know if an issue is localized to your network or a global Microsoft outage.
- Improve helpdesk communication: Arm your tier-1 agents with the exact Microsoft Incident ID to provide users.
- Centralize Microsoft 365 alerts in Teams: Keep all operational awareness in a single pane of glass.
- Eliminate manual dashboard checks: Stop wasting time refreshing the Admin Center portal.
Prerequisites: Workflows & Managed Identities
With the retirement of legacy Office 365 Connectors (Incoming Webhooks), Microsoft requires all new integrations to use Power Automate Workflows. Additionally, for Azure Automation, Managed Identities are the standard over Certificate Authentication.
- Teams Workflow Webhook: In Teams, add the Workflows app. Search for the template “Post to a channel when a webhook request is received”. Follow the wizard to generate your unique HTTP POST URL.
- Graph API Permissions: Ensure your Azure Automation Managed Identity is granted the
ServiceHealth.Read.Allapplication permission.
# Connect seamlessly inside an Azure Automation Runbook using Managed Identity
Connect-MgGraph -Identity
Step 1: Querying M365 Service Health
Using the Graph PowerShell SDK, we query the Get-MgServiceAnnouncementIssue endpoint. We process the data client-side to filter out resolved or restored issues to ensure we only capture active problems.
Write-Host "Fetching active service health issues..." -ForegroundColor Cyan
# Retrieve all issues and filter for active ones
$AllIssues = Get-MgServiceAnnouncementIssue -All
$ActiveIssues = $AllIssues | Where-Object {
$_.IsResolved -eq $false -and
$_.Status -ne 'ServiceRestored'
}
Write-Host "Found $($ActiveIssues.Count) active issues." -ForegroundColor Yellow
Step 2: Preventing Duplicate Notifications
If your Runbook executes every 15 minutes, you do not want it spamming Teams 96 times a day for the same ongoing incident. A robust script must maintain state. In Azure Automation, we can use an Automation Variable to store IDs of alerts we have already sent.
# Retrieve previously alerted IDs from an Azure Automation Variable (JSON Array)
$SentAlertsVarName = "SentHealthAlerts"
try {
$AlreadySentIssues = Get-AutomationVariable -Name $SentAlertsVarName -ErrorAction Stop | ConvertFrom-Json
} catch {
$AlreadySentIssues = @() # Initialize if it doesn't exist
}
$NewIssues = @()
foreach ($Issue in $ActiveIssues) {
if ($Issue.Id -notin $AlreadySentIssues) {
$NewIssues += $Issue
$AlreadySentIssues += $Issue.Id
}
}
# Update the variable for the next run
Set-AutomationVariable -Name $SentAlertsVarName -Value ($AlreadySentIssues | ConvertTo-Json)
Step 3: Pushing Adaptive Cards to Teams
MessageCards are a legacy format. Microsoft highly recommends using Adaptive Cards (version 1.5) for Teams Workflows. The script below formats the active incident, extracts the absolute latest update, creates a deep link to the Admin Center, and POSTs it.
# Your Teams Workflow Webhook URL
$WebhookUrl = "https://prod-123.westus.logic.azure.com:443/workflows/..."
foreach ($Issue in $NewIssues) {
# Sort posts to guarantee we grab the most recent update
$LatestUpdate = ($Issue.Posts | Sort-Object CreatedDateTime -Descending | Select-Object -First 1).Description.Content
$ServiceName = $Issue.Service
$IssueId = $Issue.Id
# Construct a Modern Adaptive Card payload
$AdaptiveCard = @{
type = "message"
attachments = @(
@{
contentType = "application/vnd.microsoft.card.adaptive"
content = @{
"`$schema" = "http://adaptivecards.io/schemas/adaptive-card.json"
type = "AdaptiveCard"
version = "1.5"
body = @(
@{
type = "TextBlock"
text = "⚠️ M365 Service Degradation: $ServiceName"
weight = "Bolder"
size = "Large"
color = "Attention"
},
@{
type = "TextBlock"
text = "**Issue ID:** $IssueId"
wrap = $true
},
@{
type = "TextBlock"
text = "**Latest Update:**"
weight = "Bolder"
},
@{
type = "TextBlock"
text = $LatestUpdate
wrap = $true
}
)
actions = @(
@{
type = "Action.OpenUrl"
title = "View in Admin Center"
url = "https://admin.microsoft.com/Adminportal/Home#/servicehealth"
}
)
}
}
)
}
# Convert hashtable to JSON
$JsonString = $AdaptiveCard | ConvertTo-Json -Depth 10
try {
Invoke-RestMethod -Uri $WebhookUrl -Method Post -Body $JsonString -ContentType 'application/json'
Write-Host "Successfully alerted Teams for issue $IssueId" -ForegroundColor Green
} catch {
Write-Host "Failed to send alert. Error: $_" -ForegroundColor Red
}
}
Conclusion
Automating your Microsoft 365 Outage Notification system using Graph API and Teams Workflows transforms your IT department from reactive troubleshooters to proactive communicators. By employing Managed Identities and state management (to avoid spam), this architecture is truly production-ready for the enterprise.
While monitoring the health of Microsoft’s servers is critical, monitoring the hygiene of your own tenant is equally important. A healthy tenant is free of dormant users, orphaned external guests, and abandoned SharePoint sites that consume resources and bloat your administrative overhead. To automate your internal tenant hygiene alongside your external monitoring, consider utilizing SPClean. SPClean works silently in the background to identify and remediate digital waste, ensuring your M365 environment runs as efficiently as your new monitoring pipeline.



