Proactive Exchange Online Monitoring: Alerts with Microsoft Graph & PowerShell
Table of Contents
Introduction
Staying informed of critical email delivery events in Exchange Online is essential for ensuring timely communication, troubleshooting issues, and safeguarding sensitive data. Microsoft Graph, combined with PowerShell, allows you to set up customized alerts for a variety of email tracking events.
Prerequisites
- Understanding of Exchange Online mail flow and event types
- Familiarity with PowerShell scripting
- Microsoft Graph Permissions:
- Permissions to subscribe to Graph change notifications (specifics can vary)
- A mechanism to receive alerts (e.g., email, webhook endpoint, integration with a monitoring tool)
Understanding Email Tracking Events
Microsoft Graph provides data on various email events, including:
- Delivery:Â Email successfully delivered to the recipient’s mailbox.
- Failure:Â Email delivery failed for various potential reasons.
- Read:Â Recipient opened the email (if read receipts are enabled).
Setting Up Alerts with PowerShell & Microsoft Graph
1: Install Modules:
Install-Module -Name Microsoft.Graph
2: Connect to Graph API:
Connect-MgGraph -Scopes # ... (Adjust scopes as needed)
3: Create Subscription:
$notificationUrl = "<your webhook endpoint or alert mechanism>"
$changeType = "updated"
$resource = "/me/messages"
New-MgSubscription -ChangeType $changeType -Resource $resource -NotificationUrl $notificationUrl
4: Handle Alerts:
- Your webhook or alert mechanism will receive notifications when subscribed events occur.
- Parse the notification payload to extract relevant details (message ID, event type, etc.).
Example Scenarios
1. Immediate Failure Notifications
Get alerted as soon as an important email delivery fails, allowing for quick troubleshooting.
# ... (Install, Connect to Graph, Create Subscription as in previous examples)
# Inside notification handling
foreach ($item in $notification.value) {
if ($item.resourceData.status -eq "Failed") {
$messageId = $item.resourceData.id
$failureReason = $item.resourceData -OtherProperties # Extract if available
Send-MailMessage -To "[email protected]" -Subject "Delivery Failure!" `
-Body "Message ID: $messageId failed to deliver. Reason: $failureReason"
}
}
2. Delayed Delivery Alerts
Set up alerts if an email hasn’t been delivered within a specific timeframe, indicating potential bottlenecks or routing issues.
# ... (Install, Connect to Graph, Create Subscription)
# Inside notification handling
foreach ($item in $notification.value) {
$sentDateTime = $item.resourceData.sentDateTime
$timeThreshold = (Get-Date).AddMinutes(-30) # 30-minute delay threshold
if ($sentDateTime -lt $timeThreshold -and $item.resourceData.status -ne "Delivered") {
$messageId = $item.resourceData.id
Send-MailMessage -To "[email protected]" -Subject "Delayed Delivery" `
-Body "Message ID: $messageId is undelivered past threshold"
}
}
3. High-Priority Read Notifications
Receive an alert only when high-priority emails marked for urgent attention are opened by their recipients.
# ... (Install, Connect to Graph, Create Subscription)
# Inside notification handling
foreach ($item in $notification.value) {
$sentDateTime = $item.resourceData.sentDateTime
$timeThreshold = (Get-Date).AddMinutes(-30) # 30-minute delay threshold
if ($sentDateTime -lt $timeThreshold -and $item.resourceData.status -ne "Delivered") {
$messageId = $item.resourceData.id
Send-MailMessage -To "[email protected]" -Subject "Delayed Delivery" `
-Body "Message ID: $messageId is undelivered past threshold"
}
}
4. Sensitive Data Monitoring
Get notified if emails containing sensitive keywords (e.g., “confidential,” “SSN,” etc.) fail to deliver, prompting security reviews.
# ... (Install, Connect to Graph, Create Subscription)
$sensitiveKeywords = "confidential", "SSN", "PII"
# Inside notification handling
foreach ($item in $notification.value) {
$messageBody = Get-MgUserMessage -MessageId $item.resourceData.id -Select Body
if ($messageBody.Body.Content -match $sensitiveKeywords -and $item.resourceData.status -eq "Failed") {
$messageId = $item.resourceData.id
Send-MailMessage -To "[email protected]" -Subject "Sensitive Data Delivery Failure" `
-Body "Message ID: $messageId (containing sensitive keywords) failed to deliver."
}
}
Remember:
- Adapt the email sending (
Send-MailMessage
) examples to your preferred notification method. - Expand with additional scenarios, more complex filtering, or integration with advanced monitoring systems.