Table of Contents
AuditLog Query API Cmdlets Now Available in the Microsoft Graph PowerShell SDK
In April 2024, I wrote about the new AuditLog Query Graph API. At the time, the API exhibited the normal rough edges found in any beta API, but I managed to use it to retrieve records from the Microsoft 365 unified audit log.
Roll forward some months and cmdlets are available for the AuditLog Query Graph API in the beta version of the Microsoft Graph PowerShell SDK (I used version 2.21 to test). Microsoft uses a process called AutoRest to automatically generate SDK cmdlets from Graph API metadata and cmdlets usually turn up a month or so after an API appears. The relevant cmdlets are:
- New-MgBetaSecurityAuditLogQuery: create and submit an audit log query. Purview processes audit log queries in the background, just like the way audit searches work in the Purview compliance portal.
- Get-MgBetaSecurityAuditLogQuery: check the processing status of an audit log query. Because background jobs handle the queries, they take much longer to complete than searches performed with the Search-UnifiedAuditLog cmdlet do. One job took 35 minutes to complete when Search-UnifiedAuditLog required three minutes.
- Get-MgBetaSecurityAuditLogQueryRecord: retrieve the audit records found by the query.
Running a query is a matter of constructing a hash table containing the parameters such as the start and end time and the operations to search for, checking for completion of the job, and downloading the results. You can check out the test script I used from GitHub.
The Too Many Retries Problem
Two oddities occurred during testing. First, “Too many retries performed” errors appeared when running the New-MgBetaSecurityAuditLogQuery cmdlet. A search against the SDK issues revealed that I wasn’t the only one to encounter the problem. Adding the Set-MgRequestContext cmdlet to the script seems to have solved the problem. At least, it hasn’t reappeared.
According to its documentation, the Set-MgRequestContext cmdlet “Sets request context for Microsoft Graph invocations.” This is a delightfully obscure description that means little to most people. The important point is that you can increase the retry delay (in seconds) and maximum retries to get around then “too many retries problem” that seems to afflict some Graph APIs (those dealing with devices and Intune seem to be most affected). The default for these values are 3 (retries) and 3 (seconds delay). The maximums are 10 (retries) and 180 (delay seconds). For example:
Set-MgRequestContext -MaxRetry 10 -RetryDelay 15
Some trial and error is likely required to determine the optimum values for a script.
The Incorrect Audit Record Counts
The second issue was a complete disconnect between the number of audit records returned by the audit log query (10,878) and Search-UnifiedAuditLog (10,879), and the number reported by the Purview compliance portal (2,538).
The compliance portal loads pages of 150 audit records at a time. If you scroll to the bottom of the list, it loads the next page, and so on. If you’re persistent, it’s possible to advance page by page until the full set of retrieved records is exhausted (Figure 2).
I don’t know why the Purview compliance portal shows an incorrect count of audit records found by a search. The reason might be that the actual number of audit records found by a search is not returned by the API. Instead, you must fetch the records to find out how many are found.
Microsoft might be relying on the fact that audit searches are often quite precise (for instance, focusing on Copilot interactions for a single user). These searches don’t return thousands of records. If only 100 audit records are found, it’s easy for the portal to display an accurate count.
AuditLog Query API Still Needs Work
It’s nice to see the AuditLog Query API appear in SDK cmdlets. However, the API is still in beta status and the audit records it returns are less complete than those found by the Search-UnifiedAuditLog cmdlet. I guess everything needs time to mature.
Learn more about how the Microsoft 365 applications really work on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.
Always a good read. I’m stuck for finding if a particular event is recorded in the audit logs. It doesn’t seem to be unless it has a cryptic name. I’m want to know if a user adding another user’s calendar shows up in the audit log.
Whar I do to find new audit events is to perform the action I want to know about, wait 3 hours, and then search the audit log for my userid and the approximate timeframe when I performed the action.
A good idea thanks. I tried that and it seemed to be missing. ChatGPT and its friends seemed to hallucinate trying to track down an opperation called FolderBind but it didn’t uncover anthing. I would have thought it would have been a basic audit event to know if someone was adding open calendars in your organisation in the hope of gaining advantage they perhaps shouldn’t have. Thanks
FolderBind is an Exchange Online mailbox audit record. It indicates the time when a non-owner accesses a mailbox folder. You could report the problem as a support issue to Microsoft to make sure that it gets recorded. It’s the only way the engineering team will spend any time considering the issue.