A cybersecurity analyst monitors cloud data flows and protected files on dual screens in a modern office.
SOC Prime has published a short walkthrough on exporting the Microsoft 365 Unified Audit Log (UAL) as clean JSON. The core procedure holds up against Microsoft's documentation. Several details need qualifying before you rely on it in an incident: the stop condition in the loop, the retention claims, and the advice to upload exports to a third-party site.

A cybersecurity analyst monitors cloud data flows and protected files on dual screens in a modern office. What the Unified Audit Log covers​

Microsoft describes the log as holding events from Exchange Online, SharePoint, OneDrive, Microsoft Entra ID, Microsoft Teams, Power BI, and other Microsoft 365 services. In a business email compromise (BEC), it is where you look for inbox rule changes, forwarding and bulk file downloads.

The Purview portal (Audit → Search) can export results to CSV. Microsoft explains that the exported file includes an AuditData column, and that column holds the extra detail for each event as a JSON object. The Excel route is to open the CSV in Power Query and apply the JSON transform to split AuditData into columns. Microsoft warns that the column list is built from the first 1,000 rows, so properties that first appear later can go missing. Narrow the search or filter by Operations first to avoid that.

Before you export: three checks​

1. Is auditing actually on? Microsoft says audit logging is on by default for Microsoft 365 organizations. It also states that auditing isn't enabled by default for SMB licenses such as Business Basic, Business Standard and Business Premium, nor for unmanaged tenants on enterprise trials. In Exchange Online PowerShell, run:

Code:
Connect-ExchangeOnline
Get-AdminAuditLogConfig | Format-List UnifiedAuditLogIngestionEnabled

True means ingestion is on. Run this in Exchange Online PowerShell specifically. Microsoft notes that in Security & Compliance PowerShell the same property is always False, even when auditing is turned on. If auditing was off, turning it on will not recreate the missing history. Microsoft also says events can take several hours to become searchable after you turn it on.

2. Do you have the right role? You need the Audit Logs or View-Only Audit Logs role. To use the cmdlet you need that role in Exchange Online. To use the portal you need it in Purview.

3. Is the data old enough, or new enough? Microsoft doesn't guarantee a delivery time. For core services such as Exchange, SharePoint, OneDrive and Teams, records are typically available 60 to 90 minutes after the event, and other services can take longer. If you are chasing something from this morning, it may not be searchable yet.

Retention is not a blanket "one year"​

SOC Prime says Audit (Premium) keeps data for a year by default. Microsoft's wording is narrower:

  • The default Audit (Premium) policy retains Exchange Online, SharePoint, OneDrive and Microsoft Entra audit records for one year. Records from all other workloads default to 180 days.
  • That one-year default only applies to activity by users with an E5 license or the qualifying Purview or eDiscovery and Audit add-on. For non-E5 users and guests, records are retained for 180 days.
  • Custom retention policies override the default. A shorter custom policy for Exchange mailbox activity means those records are kept for the shorter period.
  • Audit (Standard) retention is 180 days for logs generated on or after October 17, 2023. Older logs kept the former 90-day period.

Check the specific user's license, the workload and any custom policy before you assume the evidence is still there.

The PowerShell export, and where it can mislead you​

The portal and the cmdlet have different limits.

MethodLimit
Purview CSV export, Audit (Standard)Up to 50,000 records from a single query
Purview CSV export, Audit (Premium)Up to 1,000,000 records
Search-UnifiedAuditLog, no session100 records by default
Search-UnifiedAuditLog with -ResultSizeDefault 100, maximum 5,000
Search-UnifiedAuditLog with ReturnLargeSet and pagingUp to 50,000 results, returned unsorted

If an export exceeds its limit, Microsoft says the CSV won't include everything and may omit some audit logs. Its remedy is to narrow the date range or add filters such as UserId or Operation.

SOC Prime's loop uses a GUID session ID, ReturnLargeSet and -ResultSize 5000. It appends each record's AuditData string to a .jsonl file, so you get one JSON event per line. The .jsonl loop is SOC Prime's own example, not a Microsoft-prescribed script. The dates in it (October 19 to 20, 2026) are placeholders for your own incident window.

Code:
$session = [guid]::NewGuid().ToString()
$out = "ual_2026-10-19.jsonl"
do {
  $batch = Search-UnifiedAuditLog -StartDate "2026-10-19 00:00" -EndDate "2026-10-20 00:00" `
    -SessionId $session -SessionCommand ReturnLargeSet -ResultSize 5000
  $batch | ForEach-Object { $_.AuditData } | Add-Content $out
} while ($batch.Count -eq 5000)

Cautions to apply​

  • The stop condition is a shortcut. The loop quits as soon as a page returns fewer than 5,000 records. Microsoft's own description is different: rerun the cmdlet with the same SessionId and SessionCommand until you get zero returns or hit the session maximum. It also points to AuditSearchRequestMetadata.moreRecordsAvailable as a progress indicator. A safer pattern is to keep paging until a call returns nothing. Then record the final count.
  • A silent ceiling. At 50,000 records the session is exhausted. One third-party guide says a 50,000-record result is not proof that all matching events were retrieved. If you hit it, split the window into smaller pieces. That matches SOC Prime's own troubleshooting row.
  • Don't mix session commands. Don't switch between ReturnLargeSet and ReturnNextPreviewPage for the same session ID, or the output is limited to 10,000 results.
  • Order and duplicates. ReturnLargeSet returns unsorted data, so sort after collection. Practical365 reported that this mode can return duplicate records. Deduplicate before you count anything. That report is several years old, so treat it as a caution rather than a current guarantee.
  • UTC. Entries are stored in UTC, and a date/time without a time zone is interpreted as UTC. Convert your incident times before you set the window.
  • Same-day searches. If StartDate and EndDate are the same date and have no timestamp, you get no results. Include times.

Microsoft also recommends the Office 365 Management Activity API over scripted cmdlet use for programmatic or recurring collection. SOC Prime's FAQ reaches the same conclusion: use the API for continuous SIEM feeds and PowerShell for one-off investigations.

What to hunt for​

SOC Prime's pivot list is sensible as a starting point:

OperationWhat it can indicate
New-InboxRule, Set-InboxRule, UpdateInboxRulesRules that forward, move or delete mail
Set-Mailbox with ForwardingSmtpAddressMailbox-level forwarding to an external address
Add-MailboxPermission, Add-RecipientPermissionSomeone gaining access to another mailbox
MailItemsAccessedWhich messages were actually read, which helps scope a breach
FileDownloaded, FileSyncDownloadedFull burstsBulk download from SharePoint or OneDrive
Application consentA rogue app granted access to mail or files

An operation name alone proves nothing. Admins legitimately create rules and grant permissions. Read the parameters in AuditData, then check who acted, on whom, and what happened around it. The classic BEC sequence is an odd sign-in followed within minutes by a rule that hides replies from finance. For that you need sign-in context as well as audit records.

SOC Prime's FAQ is right that the UAL has some login events, but that Entra sign-in logs are far richer for MFA, Conditional Access and risk detail. Export both.

Some mailbox audit events may not show up in UAL searches at all, even with mailbox auditing on by default. Treat an empty result as "not found here", not as "didn't happen."

Handle the export like evidence​

An audit export contains user names, mailbox activity and file paths. SOC Prime's guide ends its workflow by telling readers to upload the .jsonl file to LogTotal, its own commercial analysis product. The page also advertises Prime Core's detection rules and a paid access offer. The 79 rules mapped to 33 MITRE ATT&CK techniques are a vendor claim. I did not verify them independently.

Nothing I reviewed describes LogTotal's data-handling terms. Don't send an investigation export to any outside service unless your security and legal teams have approved it. The PowerShell and Excel Power Query route needs no third party.

Quick troubleshooting​

SymptomLikely causeWhat to do
Cmdlet not recognizedNot connectedRun Connect-ExchangeOnline first
No resultsAuditing off, events too new, or outside retentionCheck ingestion, wait, and verify license and retention
Exactly 5,000 resultsSingle-call capUse SessionId and ReturnLargeSet and keep paging
Stuck at 50,000Session ceilingSplit the window into smaller ranges
Access deniedMissing audit roleGet Audit Logs or View-Only Audit Logs
Ingestion shows FalseWrong shellRe-run the check in Exchange Online PowerShell

Bottom line​

The SOC Prime procedure works as a practical starting point. Make three changes before you trust it. Page until the results run dry, not just until a page comes back short. Verify retention per user and workload. Keep the data inside your own environment unless your policy says otherwise.

 

References

  1. Microsoft 365 Unified Audit Log: Export and Analyze - SOC Prime SOC Prime 2026-10-23T12:48:59+00:00
  2. Search the audit log | Microsoft Learn learn.microsoft.com
  3. How to Search Office 365 Audit Logs with PowerShell (Handling Large Sets) theitbros.com