Primer: Running Audit Searches and Sending Email from Azure Automation
Use Azure Automation for Audit Searches
In the past, I published articles covering the basics of using Azure Automation to process Microsoft 365 data. The articles cover the basics of using an automation account to execute runbooks (PowerShell scripts based on the Microsoft Graph PowerShell SDK), how to output results to a SharePoint Online list, and how to attach runbooks to automation schedules to make sure that processes execute automatically and reliably.
This article covers how to execute Microsoft 365 audit searches in runbooks and how to send the results extracted from the audit searches via email. I’m going to use the scenario discussed on 24 January about a flaw found in Entra ID that allowed users to change their user principal names. Microsoft has since addressed the problem, but the fact still remains that changes to user principal names can have consequences for services other than authentication. Any change like this deserves oversight. The purpose is to explore the principles rather than the details of a solution, and the techniques used here can be applied to any audit log search.
Basic Outline to Create a Runbook for a Microsoft 365 Audit Search
Two methods are available to search the unified audit log.
- Synchronous searches performed by the Search-UnifiedAuditLog cmdlet from the Exchange Online module.
- Asynchronous searches performed by the AuditLogQuery Graph API. The API is in still in beta but it’s how the Purview Audit search solution works. SDK cmdlets are also available for the API.
Opting for the Graph API makes sense for an Azure Automation job. Asynchronous searches take longer but that doesn’t matter when the job executes in the background, especially if it’s a scheduled run. In terms of the code, Microsoft has temporarily withdrawn the Get-MgBetaSecurityAuditLogQuery cmdlet and the Get-MgBetaSecurityAuditLogQueryRecord sometimes doesn’t work, so we use Graph API requests in this example. I used V2.25 of the Graph SDK and the cmdlets might have returned by the time you read this text.
The basic processing steps are:
- Construct the parameters for the audit log search. The Update User operation captures changes made to user accounts, so that’s what the search looks for over the last seven days.
- Submit the search and monitor its progress until completion.
- Retrieve the audit records.
- Process the audit records to check if any are for changes to the userPrincipalName property and capture details of these events.
- Create a HTML fragment containing the events and use it to create the HTML content for a message.
- Run the Send-MgUserMail cmdlet to send the message to a predetermined recipient. This can be any valid email address. In production, it’s likely that the recipient would be a distribution list, but it could be a Microsoft 365 group, or even a Teams channel.
Testing the Runbook for a Microsoft 365 Audit Search
As always, it’s wise to test the runbook code by running it interactively in a Microsoft Graph PowerShell SDK session. The automation account must have the AuditLogsQuery.Read.All application permission to access audit logs and Mail.Send to be able to send email. See my earlier post for how to assign Graph permissions to automation accounts. In production scenarios, you should use RBAC for Applications to restrict access for the automation account to specific mailboxes.
To mimic what happens when Azure Automation executes the runbook, use an app-only session by signing in with an app identifier, tenant identifier, and a certificate uploaded to the app. The app must have consent to use the two permissions listed above. Once everything works interactively, copy the code and create a new Azure Automation runbook and test that the code runs in that environment (Figure 1).

When everything checks out, you can register the runbook with an automation schedule. This check is a good example of something that should be done bi-weekly. Of course, what the recipients do when they receive the message (Figure 2) is up to them.

Better than Microsoft 365 Audit Policies?
Similar functionality in terms of sending email notifications for events found by Microsoft 365 audit searches available through Microsoft 365 audit policies. The reason why a DIY version might be preferable is that you have full control over the content presented in messages and the advice given to recipients, plus any associated processing you might want to do. For instance, you could log the highlighted audit events in a SharePoint Online list and require administrators to attest that they checked each event to make sure that it’s appropriate. That might be too much, but it’s possible.
The code I used for testing can be downloaded from the Office 365 for IT Pros GitHub repository.
Insight like this doesn’t come easily. You’ve got to know the technology and understand how to look behind the scenes. Benefit from the knowledge and experience of the Office 365 for IT Pros team by subscribing to the best eBook covering Office 365 and the wider Microsoft 365 ecosystem.