Back to script library
Entra / Microsoft 365 · Compliance & audit

Report mailbox auditing configuration

A script to report the audit configuration for all user and shared mailboxes.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-ExchangeOnline -SkipLoadingCmdletHelp

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

[array]$Modules = Get-Module | Select-Object -ExpandProperty Name
If ("ExchangeOnlineManagement -notin $Modules") {
Write-Host "Hold on while we connect to Exchange Online..."
Connect-ExchangeOnline -SkipLoadingCmdletHelp
}
[array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox,SharedMailbox -ResultSize Unlimited `
-Properties DefaultAuditSet, AuditOwner, AuditDelegate, AuditAdmin, AuditEnabled |`
Sort-Object RecipientTypeDetails -Descending
Write-Host ("{0} mailboxes found" -f $Mbx.Count)
# Define the default audit set
[array]$DefaultAuditSet = "Admin", "Delegate", "Owner"
[string]$DefaultAuditSetReport = $DefaultAuditSet -join ", "
# Define the auditable actions that we want to check for
[array]$CriticalAuditActionsOwner = "MailItemsAccessed", "Send", "SearchQueryInitiated"
[array]$CriticalAuditActionsDelegate = "SendAs", "SendOnBehalf", "MoveToDeletedItems", `
"SoftDelete", "HardDelete", "MailItemsAccessed"
Write-Host "Checking mailboxes..."
$Report = [System.Collections.Generic.List[Object]]::new()
[int]$CustomAuditConfigurations = 0
ForEach ($M in $Mbx) {
# Check if the mailbox uses a custom audit configuration
$CustomAuditSet = $null; $UsesDefaultAuditSet = $true; [array]$MissingActions = $null
If ($null -ne (Compare-Object -ReferenceObject $DefaultAuditSet -DifferenceObject $M.DefaultAuditSet)) {
$CustomAuditSet = $M.DefaultAuditSet -join ", "
$UsesDefaultAuditSet = $false
$CustomAuditConfigurations++
}
ForEach ($Action In $CriticalAuditActionsOwner) {
If ($Action -notin $M.AuditOwner) {
$MissingActions += ($Action + " (Owner)")
}
}
ForEach ($Action In $CriticalAuditActionsDelegate) {
If ($Action -notin $M.AuditDelegate) {
$MissingActions += ($Action + " (Delegate)")
}
}
# create formatted strings for the actions audited in each set
$AuditOwner = $M.AuditOwner -join ", "
$AuditDelegate = $M.AuditDelegate -join ", "
$AuditAdmin = $M.AuditAdmin -join ", "
# if the mailbox uses a custom configuration, report that, otherwise report the default set
If ($null -ne $CustomAuditSet) {
$MailboxAuditSet = $CustomAuditSet
} Else {
$MailboxAuditSet = $DefaultAuditSetReport
}
# This command is to make sure that mailbox auditing is enabled and audit events are being ingested by
# the audit log. It does slow things down, so you can comment it out if you feel it's not necessary.
If ($M.AuditEnabled -eq $true) {
Set-Mailbox -Identity $M.UserPrincipalName -AuditEnabled $true -WarningAction SilentlyContinue
}
# Generate the report line
$ReportLine = [PSCustomObject]@{
UserPrincipalName = $M.UserPrincipalName
Name = $M.displayName
RecipientTypeDetails = $M.RecipientTypeDetails
AuditEnabled = $M.AuditEnabled
DefaultAuditSet = $MailboxAuditSet
'Uses default audit set' = $UsesDefaultAuditSet
'Missing actions' = $MissingActions -join ', '
AuditOwner = $AuditOwner
AuditDelegate = $AuditDelegate
AuditAdmin = $AuditAdmin
}
$Report.Add($ReportLine)
}
[array]$NotEnabledforAuditing = $Report | Where-Object { $_.AuditEnabled -eq $false }
Write-Host ("All done. Of the {0} mailboxes, {1} are audit enabled, and {2} use custom audit configurations" -f $Report.Count, ($Mbx.count - $NotEnabledforAuditing.count), $CustomAuditConfigurations)
# if the ImportExcel module is available, use it to generate an Excel worksheet, otherwise create a CSV file
Write-Host "Generating output file..."
If (Get-Module ImportExcel -ListAvailable) {
Import-Module ImportExcel -ErrorAction SilentlyContinue
$ExcelOutputFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\MailboxAuditingReport.xlsx"
$Report | Export-Excel -Path $ExcelOutputFile -WorksheetName "Mailbox Audit Configurations" `
-Title ("Mailbox Audit Configurations {0}" -f (Get-Date -format 'dd-MMM-yyyy')) -TitleBold -TableName "MailboxAuditConfiguration"
$OutputFile = $ExcelOutputFile
} Else {
$CSVOutputFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\MailboxAuditingReport.csv"
$Report | Export-Csv -Path $CSVOutputFile -NoTypeInformation -Encoding Utf8
$Outputfile = $CSVOutputFile
}
Write-Host ("Output data is available in {0}" -f $OutputFile)
Attribution