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

Get audit records (Graph SDK)

Example script to show how to run an audit query using the Microsoft Graph PowerShell SDK.

Connect & set up

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

Connect-MgGraph -NoWelcome -Scopes AuditLogsQuery.Read.All

Run it

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

param(
[int] $LookbackDays = 180,
[string] $StartDate = (Get-Date).AddDays(-$LookbackDays),
[string] $EndDate = (Get-Date).AddDays(1)
)
Connect-MgGraph -NoWelcome -Scopes AuditLogsQuery.Read.All
Set-MgRequestContext -MaxRetry 10 -RetryDelay 15
$AuditQueryName = ("Audit Job created at {0}" -f (Get-Date))
$AuditQueryStart = (Get-Date $StartDate -format s)
$AuditQueryEnd = (Get-Date $EndDate -format s)
[array]$AuditQueryOperations = "FileModified", "FileUploaded"
$AuditQueryParameters = @{}
#$AuditQueryParameters.Add("@odata.type","#microsoft.graph.security.auditLogQuery")
$AuditQueryParameters.Add("displayName", $AuditQueryName)
$AuditQueryParameters.Add("OperationFilters", $AuditQueryOperations)
$AuditQueryParameters.Add("filterStartDateTime", $AuditQueryStart)
$AuditQueryParameters.Add("filterEndDateTime", $AuditQueryEnd)
# Submit the audit query
$AuditJob = New-MgBetaSecurityAuditLogQuery -BodyParameter $AuditQueryParameters
# Check the audit query status every 20 seconds until it completes
[int]$i = 1
[int]$SleepSeconds = 20
$SearchFinished = $false; [int]$SecondsElapsed = 20
Write-Host "Checking audit query status..."
Start-Sleep -Seconds 30
$AuditQueryStatus = Get-MgBetaSecurityAuditLogQuery -AuditLogQueryId $AuditJob.Id
While ($SearchFinished -eq $false) {
$i++
Write-Host ("Waiting for audit search to complete. Check {0} after {1} seconds. Current state {2}" -f $i, $SecondsElapsed, $AuditQueryStatus.status)
If ($AuditQueryStatus.status -eq 'succeeded') {
$SearchFinished = $true
} Else {
Start-Sleep -Seconds $SleepSeconds
$SecondsElapsed = $SecondsElapsed + $SleepSeconds
$AuditQueryStatus = Get-MgBetaSecurityAuditLogQuery -AuditLogQueryId $AuditJob.Id
}
}
# Fetch the audit records returned by the query
[array]$AuditRecords = Get-MgBetaSecurityAuditLogQueryRecord -AuditLogQueryId $AuditJob.Id -All -PageSize 999
Write-Host ("Audit query {0} returned {1} records" -f $AuditQueryName, $AuditRecords.Count)
$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($Record in $AuditRecords) {
$ReportLine = [PSCustomObject][Ordered]@{
Service = $Record.Service
Timestamp = $Record.CreatedDateTime
UPN = $Record.userPrincipalName
Operation = $Record.operation
}
$Report.Add($ReportLine)
}
$Report | Sort-Object {$_.Timestamp -as [datetime]} | Out-GridView -Title ("Audit Records fetched by query {0}" -f $AuditQueryName)

Parameters

ParameterDefaultNotes
-LookbackDays180Number of days to include in the Graph audit log query.
-StartDate(Get-Date).AddDays(-180)Start of the reporting window.
-EndDate(Get-Date).AddDays(1)End of the reporting window.
Attribution