"Who removed that mailbox permission?" and "Who deleted mail from the CEO's mailbox?" are different questions, and Exchange Server answers them from two different logs. The admin audit log records configuration changes made through the shell or the Exchange admin center. Mailbox audit logging records what people do inside a mailbox. In this post I'll show how to check that both are capturing what you need, search them, and avoid the gaps that make an investigation come up empty.
How the two logs work#
| Admin audit log | Mailbox audit log | |
|---|---|---|
| Records | Cmdlets that change things, whether run in the shell or by the EAC | Actions inside a mailbox by admins, delegates and (optionally) the owner |
| Default state | Enabled in new installations; all cmdlets and parameters | Off until you enable it per mailbox |
| Stored in | A hidden arbitration mailbox | The mailbox itself: Recoverable Items\Audits |
| Kept for | 90 days (AdminAuditLogAgeLimit) | 90 days (AuditLogAgeLimit per mailbox) |
| Search with | Search-AdminAuditLog, New-AdminAuditLogSearch | Search-MailboxAuditLog, New-MailboxAuditLogSearch |
The admin audit log is about changes, not views: it won't tell you who ran a Get- cmdlet, and Test- cmdlets aren't logged by default. In mailbox auditing, someone with Full Access counts as a delegate; the admin logon type is reserved for eDiscovery searches, mailbox export requests and MAPI/CDO access.
Step-by-step: the admin audit log#
1. Check the configuration#
Get-AdminAuditLogConfig | Format-List AdminAuditLogEnabled, AdminAuditLogAgeLimit, AdminAuditLogCmdlets, AdminAuditLogParameters, AdminAuditLogExcludedCmdlets, LogLevel, TestCmdletLoggingEnabledGood looks like AdminAuditLogEnabled : True with * for cmdlets and parameters. To keep a year of history and record old and new values of every changed property:
Set-AdminAuditLogConfig -AdminAuditLogAgeLimit 365 -LogLevel VerboseOpen shells pick up configuration changes within 60 minutes; reopen the shell to apply them at once.
2. Search it#
Search-AdminAuditLog -Cmdlets Add-MailboxPermission,Remove-MailboxPermission,Set-Mailbox,Remove-Mailbox `
-StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) -ResultSize 5000 |
Where-Object { $_.ObjectModified -like "*Lina Haddad*" } |
Sort-Object RunDate | Format-Table RunDate, Caller, CmdletName, ObjectModified, Succeeded -AutoSizeWithout -ResultSize you get only the first 1,000 matches. RunDate is stored in UTC. The parameter values aren't shown in the default output, so expand them:
$hits = Search-AdminAuditLog -Cmdlets Set-Mailbox -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date)
$hits | ForEach-Object {
"{0} {1} {2} {3}" -f $_.RunDate, $_.Caller, $_.ObjectModified,
(($_.CmdletParameters | ForEach-Object { "-$($_.Name) $($_.Value)" }) -join ' ')
}With verbose logging on, $hits.ModifiedProperties also shows the old and new values.
3. Send big searches by email#
New-AdminAuditLogSearch -Name "Permission changes Q3" -Cmdlets Add-MailboxPermission,Remove-MailboxPermission `
-StartDate (Get-Date).AddDays(-90) -EndDate (Get-Date) -StatusMailRecipients auditor@contoso.comThe results arrive as an XML attachment (up to 10 MB) within about 15 minutes. Outlook on the web doesn't open XML attachments by default, so use Outlook. In the EAC, the same reports are under compliance management › auditing.
Step-by-step: mailbox audit logging#
1. Turn it on and choose the actions#
Get-Mailbox lina | Format-List AuditEnabled, AuditLogAgeLimit, AuditAdmin, AuditDelegate, AuditOwner
Set-Mailbox lina -AuditEnabled $true -AuditLogAgeLimit 180.00:00:00 `
-AuditOwner @{Add="HardDelete","SoftDelete","MoveToDeletedItems"}
# All user and shared mailboxes
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox,SharedMailbox | Set-Mailbox -AuditEnabled $trueOnce enabled, the main admin and delegate actions (such as Update, SoftDelete, HardDelete, SendAs and, for admins, FolderBind and Move) are audited by default. Owner actions aren't audited until you add them, which is why the example adds deletions. Exchange 2019 adds operations such as UpdateInboxRules and UpdateFolderPermissions; check your Audit* lists if you need them.
2. Search one mailbox#
Search-MailboxAuditLog -Identity lina -LogonTypes Admin,Delegate -ShowDetails `
-StartDate (Get-Date).AddDays(-14) -EndDate (Get-Date) -ResultSize 5000 |
Format-Table LastAccessed, Operation, LogonType, LogonUserDisplayName, FolderPathName, ItemSubject, ClientIPAddress -AutoSize
# What did the owner delete?
Search-MailboxAuditLog -Identity lina -LogonTypes Owner -ShowDetails -Operations HardDelete,SoftDelete `
-StartDate (Get-Date).AddDays(-14) -EndDate (Get-Date)The Owner logon type needs -ShowDetails, and -ShowDetails works only with -Identity (one mailbox).
3. Search several mailboxes#
New-MailboxAuditLogSearch -Mailboxes lina,omar -LogonTypes Admin,Delegate `
-StartDate (Get-Date).AddDays(-30) -EndDate (Get-Date) -StatusMailRecipients auditor@contoso.comIn the EAC, compliance management › auditing also offers a non-owner mailbox access report.
Verify#
- Make a harmless change, such as
Set-Mailbox testuser -CustomAttribute15 "audit test", wait up to 15 minutes for indexing, then find it withSearch-AdminAuditLog -Cmdlets Set-Mailbox. - Open a test mailbox with a Full Access account, delete an item, and confirm a
Delegateentry appears inSearch-MailboxAuditLog. - List mailboxes that still aren't audited:
Get-Mailbox -ResultSize Unlimited | Where-Object { -not $_.AuditEnabled } | Select-Object Name.
Tips & gotchas#
- Lowering
AdminAuditLogAgeLimitdeletes every entry older than the new limit, and 0 deletes them all. Limit who can change it, and check with my Exchange Server RBAC guide. - Accounts with an audit bypass leave no mailbox audit trail. Review them:
Get-MailboxAuditBypassAssociation -ResultSize Unlimited | Where-Object { $_.AuditBypassEnabled }. - Holds don't extend mailbox audit retention; raise
AuditLogAgeLimitor export entries you must keep. - Owner sign-ins are logged only for POP3, IMAP4 and OAuth logins, and
MessageBind(opening an item) is no longer logged. - Audit logs show actions, not intent. For a suspected break-in, start with the CSS-Exchange compromise checks; for cloud mailboxes use Microsoft Purview Audit.

