Site icon Microsoft 365 for IT Pros

How to Record Long Term Statistics About Mail Flow Rule Reports

Azure Automation and Mail Flow Rules Reporting.
Advertisements

Mail Flow Rule Suppresses Email from Known Spammers

Recently I was asked about the article I wrote about a mail flow (transport) rule to suppress inbound email from known spammer domains. The mail flow rule continues to work well and currently suppresses email from 95 domains.

Spammers constantly change their tactics and domains, so maintaining the list of blocked domains requires some ongoing effort. That’s not a big issue compared to the annoyance of spam. Microsoft Defender for Office 365 usually does a good job of putting detected spam into quarantine. The advantage of the rule is that users don’t see the messages notifying them about quarantined messages because the known spam is deleted immediately.

Monitoring Mail Flow Rule Activity Beyond Ten Days

The question was how to monitor the volume of suppressed email and identify the domains responsible for the messages. My inquisitor was affected by the message the Exchange admin center recently introduced to warn administrators when they add or update a mail flow rule that affects mail delivery (Figure 1).

Figure 1: The cautionary warning about the effect of a mail flow rule

I’ve been down this path before and wrote some PowerShell to demonstrate how to use the Get-MailDetailTransportRuleReport cmdlet to fetch information about the processing done by mail flow rules. However, the cmdlet only generates results for the last ten days. Unlike the Get-MessageTraceV2 cmdlet, which retrieves ten days’ worth of message trace data at a time but can go back 90 days by fetching multiple chunks of data, there’s no way to go back that far for the mail flow report.

Gathering Information Over Time

The solution I came up with is an Azure Automation runbook running on a scheduled weekly basis to capture details of mail flow suppression for the last seven days. The information is stored in a CSV file in a SharePoint Online document library that’s updated by the Azure Automation job. Over time, the CSV file accumulates weekly counts of the messages suppressed for each spammer domain, so it’s easy to load the file into Power BI or another tool to generate statistics.

Graph SDK Files Issue

You can download the script code from the Microsoft 365 GitHub repository. As written, the code uses Microsoft Graph PowerShell SDK cmdlets to find, download, and update the CSV file in the target document library. The cmdlets work superbly when run interactively in a delegated or app-only session but fail in Azure Automation due to a known issue where cmdlets from the Microsoft.Graph.Files module don’t work in Azure Automation. The problem still exists in the latest “good” version of the Graph SDK (V2.40).

Converting the script to run as an Azure Automation runbook therefore involves:

For example, to create the CSV file to hold historical mail flow report data from SharePoint, the Graph SDK command:

$TargetLocation = "$FolderPath/$SpammyEmailHistoricalFile"
$SpamFileItem = Set-MgDriveItemContent -DriveId $Drive.Id -DriveItemId $TargetLocation -InFile $ExportedSpamDataFile -ErrorAction Stop

the Graph SDK cmdlet is converted to:

$Uri = "https://graph.microsoft.com/v1.0/drives/$($Drive.Id)/root:/$($TargetLocation):/content"
$SpamFileItem = Invoke-MgGraphRequest -Uri $Uri -Method PUT -InputFilePath $ExportedSpamDataFile -ContentType "application/octet-stream" -ErrorAction Stop

While the command to fetch the CSV file before updating it with new data is converted from:

Get-MgDriveItemContent -DriveId $Drive.Id -DriveItemId $SpamFileItem.id -OutFile $DownloadPath -ErrorAction Stop

To:

$Uri = "https://graph.microsoft.com/v1.0/drives/$($Drive.Id)/items/$($SpamFileItem.Id)/content"
Invoke-MgGraphRequest -Uri $Uri -Method GET -OutputFilePath $DownloadPath -ErrorAction Stop

A word of warning: replacing Graph SDK cmdlets with Graph API requests isn’t a matter of mechanical substitution of one format by another. Invariably, some trial and error is needed before everything works as expected.

SDK Cmdlets or Graph API Requests

The ongoing problems with some Microsoft Graph PowerShell SDK modules have led some professional developers to question whether using the SDK is worthwhile for production code. Some use Connect-MgGraph to connect a new Graph session and use Graph API requests thereafter. The advantage gained in this approach is that it’s easier to use Connect-MgGraph to acquire and manage access tokens. Other Graph SDK advantages such as the retry handler and easy pagination are not available, but the proponents of this approach say that the stability of the Graph requests over SDK cmdlets makes the strategy worthwhile.

I think that using Connect-MgGraph in combination with Graph API requests is reasonable for professional developers. However, my view is that Microsoft 365 administrators who are used to PowerShell are still better off taking advantage of the ease of use of Graph SDK cmdlets. But it’s a matter of personal taste. Do what makes sense to you, as long as you get the right results.


Support the work of the Microsoft 365 for IT Pros team by subscribing to the Microsoft 365 for IT Pros eBook. Your support pays for the time we need to track, analyze, and document the changing world of Microsoft 365 and Office 365. Only humans contribute to our work!

Exit mobile version