Microsoft 365 Audit Logging - 夜莺博客

Microsoft 365 Audit Logging

原文:Microsoft 365 Audit Logging — theDXT (Daniel Keer)

For whatever reason the default fresh setup of Microsoft 365 has no audit logging turned on. Audit logging is very useful for IT troubleshooting and auditors love logs.

Microsoft says that it is enabled by default for Microsoft 365 and Office 365 enterprise organizations. I suspect that means only if you have E1 or higher. The new tenants I’ve made recently are not E1 or higher, that could be why I didn’t see it already on.

Someone asked for clarification about this on GitHub however the replies all say that it is on by default for everything but that isn’t true based on my experience. You can read the GitHub issue here.

Microsoft’s documentation also says to double check that audit logging is enabled which you 100% should be doing as if it’s on or not seems inconcistant.

In this post I will detail how to check if audit logging is enabled and how to enable it via the Web UI or PowerShell.

What Unified Audit Logging Actually Does

Unified audit logging — still frequently called the Office 365 audit log — is the tenant-wide pipeline that records user and administrator activity into a single searchable store. Every event carries the same envelope: a UTC timestamp, the user or application that performed the action, the workload it happened in, the operation name, the object that was touched, the client IP address, and a workload-specific payload of extra properties. Microsoft calls that payload AuditData, and the operation names read like UserLoggedIn, FileAccessed, FileDownloaded, New-Mailbox, Set-Mailbox, Add-MailboxPermission, UpdateUser or ConsentToApplication.

Because everything lands in one place, the log answers questions that used to require four separate tools: who deleted that SharePoint file, who granted themselves full access to a shared mailbox, which third-party application consented to read the whole directory, and which account signed in from an unfamiliar country at 03:00. That same store is what Microsoft Purview eDiscovery, Insider Risk Management and the Defender XDR hunting experiences read from, so when ingestion is off several compliance features quietly have nothing to work with.

Two details surprise people the first time they dig in. First, ingestion is not instant — Microsoft documents a latency of up to 60 minutes between an event occurring and the record becoming searchable, and in practice events can appear out of order inside that window. Second, several high-value event categories (mail item access, detailed Teams meeting activity, and most Defender alert data) need higher licences than the base ingestion switch, so a tenant with audit logging switched on can still be missing entire classes of records.

Prerequisites

  • Microsoft 365 Customizations needs to be enabled. If you don’t know how to do that my post Microsoft 365 Enable Organization Customization shows you how.
  • A role that can read audit configuration: Global Administrator, Compliance Administrator, Security Administrator or the Audit Logs role in Purview.
  • Exchange Online PowerShell module (ExchangeOnlineManagement) if you plan to enable or search from the command line.

The Web UI Way

  • Login to Microsoft 365 Admin center.
  • Click on Security or Compliance (you can get to auditing from either one)

Image 2

  • From the Security or Compliance admin centers click on Audit

Image 3

If audit logging isn’t enable the page will look something like this.

Image 4

  • Click on Start recording user and admin activity

Image 5

Audit Logging is now enabled it may take a bit for it to actually start working.

The PowerShell Way

  • Connect to Exchange Online with PowerShell

  • Run the following command to check if Audit Logging is enabled Get-AdminAuditLogConfig | FL UnifiedAuditLogIngestionEnabled

Image 6

In my example the returned result is false so audit logging isn’t enabled and we want to turn that on.

  • To enable audit logging run the following command Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true

Image 7

The process can take up to 60 minutes.

  • After 60 minutes double check and confirm that audit logging is enabled by running the following command Get-AdminAuditLogConfig | FL UnifiedAuditLogIngestionEnabled

Image 8

In my example the returned result is now true so audit logging is now enabled.

Searching the Audit Log in the Portal

Once ingestion is confirmed on, the same Audit blade becomes your investigation tool. The modern location is the Microsoft Purview portal (purview.microsoft.com) under Audit; the classic compliance.microsoft.com blade still redirects there. A search is defined by a handful of filters:

  • Date range — start and end date, with the understanding that searches are run in UTC.
  • Users — one or more user principal names; leaving it blank returns activity for every identity, which is rarely what you want.
  • Activities — a friendly-name picker backed by operation names such as FileAccessed or Set-Mailbox.
  • Workloads — Exchange, SharePoint, OneDrive, Teams, AzureActiveDirectory, Power BI, Dynamics 365 and the rest.
  • Record type — the numeric classification (for example AzureActiveDirectory, SharePointFileOperation, ExchangeItem) that maps to the payload schema.
  • File, folder or site — narrows SharePoint and OneDrive activity to a specific URL.

Results are paged and can be exported to CSV, but each export is capped at 50,000 rows, so a broad query across a busy tenant needs to be sliced by date or workload. If a search returns nothing, widen the date range before you assume the event was never recorded — remember the ingestion delay.

Searching the Audit Log with PowerShell

For repeatable investigations and for anything you want to pipe into ConvertFrom-Json, the cmdlet is far more useful than the portal.

Connect-ExchangeOnline
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) `
  -Operations FileAccessed,FileDownloaded -ResultSize 5000

The single most important quirk is the 5,000 record ceiling. A plain search stops there and gives you no indication that more data exists. To walk through everything you must reuse the returned session:

$session = (Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) `
  -EndDate (Get-Date) -ResultSize 5000 -SessionCommand ReturnLargeSet).SessionId
Search-UnifiedAuditLog -SessionId $session -ResultSize 5000 -SessionCommand ReturnLargeSet

Keep calling that second command until it stops returning rows, collecting the results into an array as you go. Then expand the payload, which arrives as a JSON string in the AuditData column:

$log = Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) `
  -UserIds admin@contoso.com -ResultSize 5000
$log | ForEach-Object {
    $d = $_.AuditData | ConvertFrom-Json
    [pscustomobject]@{
        Time    = $d.CreationTime
        User    = $d.UserId
        Op      = $d.Operation
        Workload= $d.Workload
        ClientIP= $d.ClientIP
        Object  = $d.ObjectId
    }
} | Sort-Object Time | Export-Csv .\audit-export.csv -NoTypeInformation

Useful parameters beyond the basics: -FreeText to grep the payload, -RecordType to restrict to one schema, -IPAddresses to chase a suspicious source address, and -SiteIds for SharePoint. Export the raw JSON too — the CSV projection throws away fields you will want later.

Mailbox Auditing Is a Separate Switch

This trips up almost everyone. UnifiedAuditLogIngestionEnabled controls whether the tenant writes to the unified log at all. Mailbox auditing — the MailboxLogin, SendAs, SendOnBehalf and delegate-access events — is a second, per-mailbox setting with its own organisation-wide default:

Get-Mailbox -ResultSize Unlimited | Select DisplayName, AuditEnabled, AuditLogAgeLimit
Set-OrganizationConfig -AuditDisabled $false
Set-Mailbox user@contoso.com -AuditEnabled $true -AuditLogAgeLimit 365.00:00:00

Microsoft enables mailbox auditing by default for new tenants, but older tenants migrated in place can still have it disabled, and a disabled value at the organisation level overrides every individual mailbox. Check both numbers before you tell an auditor you have full coverage.

Retention, Licensing and the Fine Print

  • Default retention is 90 days on E1/E3 (and most Business SKUs), and 365 days on E5.
  • An audit retention policy in Purview can extend specific record types to 10 years, but that capability is licensed separately and is not part of the base E3 entitlement.
  • Turning ingestion off stops new records; it does not delete existing ones. They age out on the normal retention clock.
  • Precise timestamps matter for forensics: everything is stored in UTC, so export and convert to local time yourself rather than trusting a displayed time.
  • A tenant that drops from E5 to a lower SKU will lose the extended retention window going forward.

Common Pitfalls and Troubleshooting

  • Set-AdminAuditLogConfig fails with a customization error — run Enable-OrganizationCustomization once, as described in the prerequisite above.
  • The web UI still shows “Start recording user and admin activity” after you enabled it with PowerShell — this is usually caching plus the 60 minute replication window. Re-check with Get-AdminAuditLogConfig rather than the portal.
  • Enabled yesterday, off today — licence changes are the usual cause. Converting a trial, or letting a trial expire, can flip ingestion back off.
  • Searches return nothing for a user you know was active — confirm the identity is the UPN rather than a display name, widen the date range, and remember that guest accounts and some service principals record under a different identifier.
  • Records present but payload looks empty — you are probably looking at a record type that needs a higher licence tier to populate fully.
  • Export truncated at 50,000 rows — slice the query by date or by workload, or use the PowerShell session paging shown earlier.

Verifying Coverage After the Change

Enabling the switch is the start, not the finish. A short validation pass saves an unpleasant conversation later: sign in from a test account, open a document, delete a test item, then search the audit log for those operations and confirm they appear with the expected user, workload and client IP. Repeat the same check after any licence change or tenant migration. If you script it, run the check on a schedule and alert when UnifiedAuditLogIngestionEnabled returns anything other than True — the setting silently reverting is exactly the failure mode this whole post exists to avoid.

Summary

That’s all it take to enable Audit Logging on Microsoft 365 — and now also how to search it, how to page past the 5,000 record ceiling, why mailbox auditing is a different control, and what the retention limits really are.

If you want to read more about the audit log you can do so by reading Microsoft’s documentation about it here.

Related Reading on This Site

Audit logging depends on organization customization being enabled first, covered in Microsoft 365 Enable Organization Customization. For the mailbox-side limits that the audit log will record once you raise them, see Exchange Online 150 MB message size. Access-control events from the same log are explored in Entra ID conditional access What-If, and if the whole tenant is being torn down, delete a Microsoft 365 tenant covers the order of operations.