Search-AuditLogGraph.PS1
📦 Office 365 POWERSHELLPrzeszukuje Unified Audit Log przez Microsoft Graph API — nowoczesna alternatywa dla Search-UnifiedAuditLog
Opis
Autor: Tony Redmond / office365itpros.com GitHub: https://github.com/12Knocksinna/Office365itpros/blob/master/Search-AuditLogGraph.PS1 Nowoczesny skrypt korzystajacy z Microsoft Graph API i Exchange Online Management v3.
🕒 2026-04-13
📦 Źródło: 12knocksinna
skrypt.ps1
# Search-AuditLogGraph.PS1
# Example of how to search the Microsoft 365 unified audit log using the Graph API
# In this case, we use the Microsoft Graph PowerShell SDK to do the magic. Tested with SDK V2.15.
# See this article for more information: https://practical365.com/audit-log-query-api/
# V1.0 29-Feb-2024
# https://github.com/12Knocksinna/Office365itpros/blob/master/Search-AuditLogGraph.PS1
Connect-MgGraph -Scopes AuditLogsQuery.Read.All -NoWelcome
$SearchId = $null
# Construct basic search parameters
# For multiple operations, use "operationFilters" = @("fileaccessed","filedeleted")
# For record type filters, use "recordTypeFilters" = @("sharePointFileOperation","threatIntelligence")
$StartDate = $null; $EndDate = $null; $Operations = $null
$StartDate = Read-Host "Start Date for audit search"
$EndDate = Read-Host "End Date for audit search"
[array]$UserOperations = Read-Host "Enter the audit operations to search for (separated by commas)"
[array]$Operations = $UserOperations.split(",").trim(" ").tolower()
Try {
$StartDateSearch = (Get-Date $StartDate -format s) + "Z"
}
Catch {
Write-Host ("{0} is not a valid date" -f $StartDate)
Break
}
Try {
$EndDateSearch = (Get-Date $EndDate -format s) + "Z"
}
Catch {
Write-Host ("{0} is not a valid date" -f $EndDate)
Break
}
If (!($Operations)) {
Write-Host "No audit operations specified - exiting"
Break
}
$SearchName = ("Audit Search created {0}" -f (Get-Date -format 'dd-MMM-yyyy HH:mm'))
$SearchParameters = @{
"displayName" = $SearchName
"filterStartDateTime" = $StartDateSearch
"filterEndDateTime" = $EndDateSearch
"operationFilters" = $Operations
}
Write-Host "Creating an audit search query..."
$Uri = "https://graph.microsoft.com/beta/security/auditLog/queries"
$SearchQuery = Invoke-MgGraphRequest -Method POST -Uri $Uri -Body $SearchParameters
$SearchId = $SearchQuery.Id
If ($null -eq $SearchId) {
Write-Host "Search not created"
Break
} Else {
$SearchId = $SearchQuery.Id
Write-Host ("Audit log search created with id: {0} and name {1}" -f $SearchId, $SearchQuery.displayname)
}
[int]$i = 1
[int]$SleepSeconds = 20
$SearchFinished = $false; [int]$SecondsElapsed = 20
Write-Host "Checking audit query status..."
Start-Sleep -Seconds 20
$Uri = ("https://graph.microsoft.com/beta/security/auditLog/queries/{0}" -f $SearchId)
$SearchStatus = Invoke-MgGraphRequest -Uri $Uri -Method GET
While ($SearchFinished -eq $false) {
$i++
Write-Host ("Waiting for audit search to complete. Check {0} after {1} seconds. Current state {2}" -f $i, $SecondsElapsed, $SearchStatus.status)
If ($SearchStatus.status -eq 'succeeded') {
$SearchFinished = $true
} Else {
Start-Sleep -Seconds $SleepSeconds
$SecondsElapsed = $SecondsElapsed + $SleepSeconds
$SearchStatus = Invoke-MgGraphRequest -Uri $Uri -Method GET
}
}
Write-Host "Fetching audit records found by the search..."
$Uri = ("https://graph.microsoft.com/beta/security/auditLog/queries/{0}/records?`$Top=999" -f $SearchId)
[array]$SearchRecords = Invoke-MgGraphRequest -Uri $Uri -Method GET
[array]$AuditRecords = $SearchRecords.value
# Paginate to fetch all available audit records
$NextLink = $SearchRecords.'@odata.NextLink'
While ($null -ne $NextLink) {
$SearchRecords = $null
[array]$SearchRecords = Invoke-MgGraphRequest -Uri $NextLink -Method GET
$AuditRecords += $SearchRecords.value
Write-Host ("{0} audit records fetched so far..." -f $AuditRecords.count)
$NextLink = $SearchRecords.'@odata.NextLink'
}
Write-Host ("Total of {0} audit records found" -f $AuditRecords.count) -ForegroundColor Red
$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'
# An example script used to illustrate a concept. More information about the topic can be found in the Office 365 for IT Pros eBook https://gum.co/O365IT/
# and/or a relevant article on https://office365itpros.com or https://www.practical365.com. See our post about the Office 365 for IT Pros repository # https://office365itpros.com/office-365-github-repository/ for information about the scripts we write.
# Do not use our scripts in production until you are satisfied that the code meets the need of your organization. Never run any code downloaded from the Internet without
# first validating the code in a non-production environment.