Entra / Microsoft 365 · Compliance & audit
Check audit events runbook
Azure Automation runbook that searches the Office 365 audit log for high-priority events and emails a summary to administrators.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-AzAccount -Identity
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
param([int] $LookbackDays = 30,[string] $StartDate = (Get-Date).AddDays(-$LookbackDays),[string] $EndDate = (Get-Date).AddDays(1))Connect-AzAccount -Identity$AccessToken = Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com"Connect-MgGraph -AccessToken $AccessToken.Token#Define the desired graph endpointSelect-MgProfile Beta# Get tenant name$TenantName = (Get-MgOrganization).DisplayName# Connect to Exchange Online with the managed identity - update your organization name hereConnect-ExchangeOnline -ManagedIdentity -Organization xxxxx.onmicrosoft.com# Define the set of operations we're interested in picking up in the audit log[array]$Operations = "New-TransportRule", "New-InboundConnector", "Set-TransportRule"[array]$Records = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -ResultSize 5000 -Operations $Operations -Formatted# If no records are found, exitIf (!($Records)) { Write-Output "No records found - exiting" ; Break }$records | ft creationdate, operations, userids# Parse out audit information to make it useful$Report = [System.Collections.Generic.List[Object]]::new()ForEach ($Record in $Records) {$AuditData = $Record.AuditData | ConvertFrom-Json$P1 = $Null; $P2 = $NullSwitch ($Record.Operations) { # Process the audit record for each operation to extract important parameters"New-InboundConnector" {$P1 = $AuditData.Parameters | Where-Object {$_.Name -eq "EFSkipIPs"} | Select-Object -ExpandProperty Value$P2 = $AuditData.Parameters | Where-Object {$_.Name -eq "ConnectorType"} | Select-Object -ExpandProperty Value}"New-TransportRule" {$P1 = $AuditData.Parameters| Where-Object {$_.Name -eq "Name"} | Select-Object -ExpandProperty ValueForEach ($V in $AuditData.Parameters) {If ($V.Name -ne "Name") { $P2 += " " + $V.Name + ": " + $V.Value } }$P2 = $P2.SubString(1) # Trim first leading space}"Set-TransportRule" {$P1 = $AuditData.Parameters| Where-Object {$_.Name -eq "Name"} | Select-Object -ExpandProperty ValueForEach ($V in $AuditData.Parameters) {If ($V.Name -ne "Name") { $P2 += " " + $V.Name + ": " + $V.Value } }$P2 = $P2.SubString(1) # Trim first leading space}}$UserDisplayName = Get-Exomailbox -Identity $Record.UserIds | Select-Object -ExpandProperty DisplayName$ReportLine = [PSCustomObject] @{TimeStamp = Get-Date($Record.CreationDate) -Format gUser = $UserDisplayNameOperation = $Record.OperationsObject = $AuditData.Parameters | Where-Object {$_.Name -eq "Name"} | Select-Object -ExpandProperty ValueParameter1 = $P1Parameter2 = $P2}$Report.Add($ReportLine)}# Define variables for the mailbox used to send the message, the recipient, and the message subject# Change these values to match your own tenant$MsgFrom = "Azure.Management.Account@mydomain.com"$ToAddress = "AdminDL@mydomain.com"$MsgSubject = "High-Priority Audit Events Found for $($TenantName)"# Define HTML header with styles$htmlhead="<style>.UserTable {border:1px solid #C0C0C0;border-collapse:collapse;padding:5px;}.UserTable th {border:1px solid #C0C0C0;padding:5px;background:#F0F0F0;}.UserTable td {border:1px solid #C0C0C0;padding:5px;}</style>"# Build the message including the audit details in a table$HtmlBody = "<body><p><font size='2' face='Segoe UI'><p><strong>Generated:</strong> $(Get-Date -Format g)</p><h2><u>Please Check Audit Events</u></h2><p><b>We've discovered some high-priority events in the unified audit log.</b></p><p>Please investigate the details of these events.</p><p></p><table class='UserTable'><caption><h2><font face='Segoe UI'>High-Priority Audit Events for Review</h2></font></caption><thead><tr><th>Timestamp</th><th>User</th><th>Operation</th><th>Object</th><th>P1</th><th>P2</th></tr></thead><tbody>"ForEach ($A in $Report) {$HtmlBody += "<tr><td><font face='Segoe UI'>$($A.Timestamp)</font></td><td><font face='Segoe UI'>$($A.User)</td></font><td><font face='Segoe UI'>$($A.Operation)</td></font><td><font face='Segoe UI'>$($A.Object)</td></font><td><font face='Segoe UI'>$($A.Parameter1)</td><td><font face='Segoe UI'>$($A.Parameter2)</td></tr></font>"}$HtmlBody += "</tbody></table><p>"$HtmlBody += '</body></html>'$EmailAddress = @{address = $ToAddress}$EmailRecipient = @{EmailAddress = $EmailAddress}$HtmlHeaderUser = "<h2>High Priority Audit Events</h2>"$HtmlMsg = "</html>" + $HtmlHead + $htmlbody + "<p>"# Construct the message body$MessageBody = @{content = "$($HtmlBody)"ContentType = 'html' }# Create a draft message in the mailbox used to send the message$NewMessage = New-MgUserMessage -UserId $MsgFrom -Body $MessageBody -ToRecipients $EmailRecipient -Subject $MsgSubject# Send the messageSend-MgUserMessage -UserId $MsgFrom -MessageId $NewMessage.Id
Parameters
ParameterDefaultNotes
-LookbackDays30How many days back to search for newly created mailboxes or recent activity.-StartDate(Get-Date).AddDays(-30)Start of the reporting window.-EndDate(Get-Date).AddDays(1)End of the reporting window.Attribution
Author
Office365itpros