Auswertung von Purview Audit Logs über Microsoft Graph (Preview)

In Microsoft Graph wird seit Januar eine neue API für die Auswertung von Purview Audit Logs bereitgestellt.
Die Dokumentation beschreibt die AuditLogQuery API mit den Methoden List, Create, Get und List records.


Folgende Methoden werden über die API bereitgestellt.

  • List
    Listet noch verfügbare Suchaufträge der letzten 30 Tage und deren Status.

  • Create
    Erstellt einen neuen Auftrag zur Auswertung von Audit Logs, ähnlich einem Auftrag über das Compliance Center. In der Dokumentation erwähnt Microsoft die unterstützten Produkte OneDrive, SharePoint, Exchange, Intune, Dynamics CRM, Entra oder alle verfügbaren Dienste. Abhängig zum Produkt benötigt es unterschiedliche API-Berechtigungen.

  • Get
    Zeigt den Status von einem ausgewählten Auftrag.

  • List audit log records
    Inkludiert die gefundenen Ergebnisse aus einem abgeschlossenen Auftrag.

Die API unterstützt Delegation und Application Permissions. Applikationen und Konten können eingeschränkt sein nur für ausgewählte Produkte Audit Logs abzurufen, siehe Berechtigungen.

Für eine allgemeine Hilfe über Suche in Audit Logs solltest du die Dokumentation lesen.
Mich interessierte die API mit Delegated Permissions für SharePoint und Microsoft Entra auszuprobieren. Praktisch ist es Administratoren über die API möglich Suchaufträge für Audit Logs abzusenden und die Ergebnisse auszuwerten. Kennt jemand die Filter ist die Auswertung über PowerShell schneller als über das Compliance Center. Vor allem ist es stabiler. Das Compliance Center ist immer wieder sehr träge.


Auswertung von Audit Logs für SharePoint Online

In meinem ersten Beispiel werte ich aus wann während der letzten 14 Tage Dokumente in den SharePoint Papierkorb verschoben wurden. Dafür benötigt es die Berechtigung AuditLogsQuery-SharePoint.Read.All.

In der Dokumentation für Create beschreibt Microsoft welche Typen unterstützt sind und welche Properties du in einer Anfrage mitsenden kannst. Wie bei Audit Logs üblich ist es empfehlenswert den Zeitraum und Inhalte einzugrenzen, um das Ergebnis weitgehend vorzufiltern.

  • In meinen Beispiel nutze ich einen ServiceFilter SharePoint.
  • Zusätzlich einen RecordTypeFilter für SharePointFileOperation. In der Dokumentation sind die Filter hier und hier erwähnt.
  • Zusätzlich einen OperationFilter FileRecycled. Die Filter beschreibt Microsoft in der Dokumentation für Audit Log Activities > File and page activities.
  • Sind die Filter unbekannt rate ich über das Compliance Center einen Audit Log Job auszuführen. Im Ergebnis stehen jeweils die erforderlichen Filterwerte. Ausserdem kannst du einen über das Compliance Center erstellten Job über PowerShell auswerten und die Filterwerte kopieren (siehe Schritt 1). 😊
1) Abfrage von Audit Search Jobs

Die Ergebnisse aus einem Audit Search Job speichert das Compliance Center für 30 Tage. Im ersten Schritt frage ich über die API bereits laufende und abgeschlossene Jobs ab.

PowerShell
Import-Module Microsoft.Graph.Authentication
Connect-MgGraph -Scopes AuditLogsQuery-SharePoint.Read.All

$Url = "https://graph.microsoft.com/beta/security/auditLog/queries"
$AuditLogQueryResults = Invoke-MgGraphRequest -Method Get -Uri $Url -ContentType "application/json"
$AuditLogQueryResults


0 bedeutet es sind aus den letzten 30 Tagen keine Jobs vorhanden.

PowerShell

2) Neuen Audit Search Job erstellen

Über die Methode Create erstelle ich einen neuen Search Job und wähle als Startdatum jetzt minus 14 Tage, als Enddatum die aktuelle Zeit.

  • Achte beim Auftrag auf das korrekte Format für Datum/Zeit.
  • Beachte die aktuelle Möglichkeit von maximal 180 Tage für das Startdatum, unabhängig zu einer E5 Lizenzierung.
PowerShell
$StartDate = (Get-Date).AddDays(-14).ToString("yyyy-MM-ddT00:00:00Z")
$EndDate = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ")

$Body = 
@"
{
    "displayName": "AuditlogQuery-SharePoint-Test1",
    "filterStartDateTime": "$StartDate",
    "filterEndDateTime": "$EndDate",
    "serviceFilters": ["SharePoint"],
    "recordTypeFilters": ["SharePointFileOperation"],
    "operationFilters": ["FileRecycled"]    
  }
"@

$Url = "https://graph.microsoft.com/beta/security/auditLog/queries"
$AuditLogNewQuery = Invoke-MgGraphRequest -Method POST -Uri $Url -Body $Body -ContentType "application/json"
$$AuditLogNewQuery


Die API sendet Informationen über den Auftrag. Die ID wird für die Statusabfrage benötigt, den Status wie fortgeschritten der Auftrag ist.

PowerShell

Eine Kontrolle im Compliance Center bestätigt den Auftrag. Der über die API erstellte Auftrag ist dort ebenfalls ersichtlich.

Audit Log Search Job im Compliance Center
Audit Log Search Job im Compliance Center

3) Status von Audit Search Job auswerten

Über die Methode Get frage ich über die ID des Auftrags den Status ab. Abhängig zur Datenmenge kann der Job einige Zeit dauern.

PowerShell
$AuditLogNewQueryID = $AuditLogNewQuery.id
$Url = "https://graph.microsoft.com/beta/security/auditLog/queries/$AuditLogNewQueryID"
$AuditLogNewQueryResult = Invoke-MgGraphRequest -Method Get -Uri $Url -ContentType "application/json"
$AuditLogNewQueryResult


Mein Auftrag wurde nach kurzer Zeit abgeschlossen.

PowerShell

4) Ergebnisse von Audit Search Job auswerten

Ebenfalls mit der ID des Auftrags frage ich über die Methode List records ab wie viele Ergebnisse die Suche gefunden hat > 3 Stück.

PowerShell
$Url = "https://graph.microsoft.com/beta/security/auditLog/queries/$AuditLogNewQueryID/records"
$AuditLogNewQueryResultRecords = Invoke-MgGraphRequest -Method Get -Uri $Url -ContentType "application/json"
$AuditLogNewQueryResultRecords

PowerShell

Alle Ergebnisse listet es ebenfalls auf. Mit den Ergebnissen kann jemand einen Export durchführen oder weiterarbeiten.

PowerShell

Hinweis zur Kontrolle im Compliance Center. Im abgeschlossenen Auftrag findest du die oben erwähnten Filterwerte, falls sie initial unbekannt sind. Öffnen einen Auftrag und achte auf die Werte

  • Workload im Auftrag ist ServiceFilter in der API
  • RecordType im Auftrag ist RecordTypeFilter in der API
  • Operation im Auftrag ist OperationFilter in der API

Auch am Ergebnis der API-Abfrage erkennbar.

PowerShell


Auswertung von Anmeldungen in Microsoft Entra

Nun führe ich über die API noch einen ähnlichen Tests für Audit Logs aus Microsoft Entra durch.
Das Purview Audit Log unterstützt für Entra folgende Filter:

  • serviceFilter (Workload) AzureActiveDirectory
  • recordTypeFilter azureActiveDirectory, azureActiveDirectoryAccountLogon und azureActiveDirectoryStsLogon

Copilot beschreibt die Unterschiede zwischen azureActiveDirectoryAccountLogon und azureActiveDirectoryStsLogon.

azureActiveDirectoryAccountLogon and azureActiveDirectoryStsLogon are both types of events that can be logged in the Azure Active Directory audit logs, and they can be used as filters when querying these logs through the Microsoft Graph API.

azureActiveDirectoryAccountLogon represents an account logon event in Azure Active Directory. This event is logged when a user or an application logs in to an Azure Active Directory account. This can be useful for tracking authentication events for security or auditing purposes.

On the other hand, azureActiveDirectoryStsLogon represents a Security Token Service (STS) logon event in Azure Active Directory. The STS is a component of identity providers like Azure Active Directory that issues security tokens, or more specifically, OAuth tokens. An STS logon event is logged when a user or an application logs in using these security tokens.

In meinem Beispiel werte ich die Anmeldungen von einem Konto über die letzten 60 Tage aus.

PowerShell
Connect-MgGraph -Scopes AuditLogsQuery-Entra.Read.All
$StartDate = (Get-Date).AddDays(-60).ToString("yyyy-MM-ddT00:00:00Z")
$EndDate = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ")

$Body = 
@"
{
    "displayName": "AuditlogQuery-EntraLogon-TanjaK-1",
    "filterStartDateTime": "$StartDate",
    "filterEndDateTime": "$EndDate",
    "serviceFilters": ["AzureActiveDirectory"],  
    "recordTypeFilters": ["azureActiveDirectoryAccountLogon", "azureActiveDirectoryStsLogon"],
    "userPrincipalNameFilters": ["[email protected]"]  
  }
"@

$Url = "https://graph.microsoft.com/beta/security/auditLog/queries"
$AuditLogNewQuery = Invoke-MgGraphRequest -Method POST -Uri $Url -Body $Body -ContentType "application/json"


Der Job ist nach wenigen Minuten abgeschlossen.

PowerShell

Während der letzten 60 Tage wurden 5 Anmeldungen gefunden.

PowerShell


Auswertung von Aktivitäten in Microsoft Entra

Mit dem Wissen welchen ServiceFilter es für die Suche benötigt ist es jetzt möglich Aufträge über Entra Aktivitäten der letzten 180 Tage auszuwerten. Zur Erinnerung, selbst mit E5 Lizenzen kannst du keine Auswertung über mehr als 180 Tage in Auftrag geben.

Ich führte drei verschiedene Tests durch.

  • Ich fragte Aktivitäten vom Service AzureActiveDirectory ab.
  • Ich fragte für AzureActiveDirectory die Aktivitäten von Alex W. ab.
  • Ich fragte für AzureActiveDirectory die Aktivitäten von Tanja K. ab.

Beispiel für Aktivitäten vom Service AzureActiveDirectory.

PowerShell
Connect-MgGraph -Scopes AuditLogsQuery-Entra.Read.All
$StartDate = (Get-Date).AddDays(-180).ToString("yyyy-MM-ddT00:00:00Z")
$EndDate = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ")

$Body = 
@"
{
    "displayName": "AuditlogQuery-EntraActivities",
    "filterStartDateTime": "$StartDate",
    "filterEndDateTime": "$EndDate",
    "serviceFilters": ["AzureActiveDirectory"] 
  }
"@

$Url = "https://graph.microsoft.com/beta/security/auditLog/queries"
$AuditLogNewQuery = Invoke-MgGraphRequest -Method POST -Uri $Url -Body $Body -ContentType "application/json"

# Check the job status
$AuditLogNewQueryID = $AuditLogNewQuery.id
$Url = "https://graph.microsoft.com/beta/security/auditLog/queries/$AuditLogNewQueryID"
$AuditLogNewQueryResult = Invoke-MgGraphRequest -Method Get -Uri $Url -ContentType "application/json"
$AuditLogNewQueryResult

# Get the job results after the job is completed
$Url = "https://graph.microsoft.com/beta/security/auditLog/queries/$AuditLogNewQueryID/records?`$top=1000"
$AuditLogNewQueryResultRecords = Invoke-MgGraphRequest -Method Get -Uri $Url -ContentType "application/json"
$AuditLogNewQueryResultRecords


Die Suche über 180 Tage wird ohne weitere Filter entsprechend lange benötigen.
Bei Ergebnissen ab 150 Einträgen führt die API ein Paging durch und gibt pro Abfrage maximal 1.000 Einträge zurück.

PowerShell

Mit einer Schleife frage ich alle Ergebnisse ab.

PowerShell
function Get-TAMgGraphAllData {

    <#
        .SYNOPSIS
        This function retrieves all data from a specified Microsoft Graph API endpoint.

        .DESCRIPTION
        The Get-TAMgGraphAllData function sends a GET request to the provided Microsoft Graph API URL. 
        It handles pagination by checking for the '@odata.nextLink' property in the response, 
        which contains the URL for the next page of data. 
        The function continues to send requests to the next page URL until there are no more pages, 
        aggregating all the data into the $dataList array.

        .PARAMETER Url
        The URL of the Microsoft Graph API endpoint to retrieve data from. This parameter is mandatory.

        .EXAMPLE
        Get-TAMgGraphAllData -Url "https://graph.microsoft.com/v1.0/users"

        This example retrieves all users from the Microsoft Graph API.

        .OUTPUTS
        Array. Returns an array of all data retrieved from the specified Microsoft Graph API endpoint.
    #>

    param( [Parameter(Mandatory = $true)][string]$Url  )        

    $APIUrl = $Url
    $GraphResultList = @()

    While ( $null -ne $APIUrl ) {
        $data = Invoke-MgGraphRequest -Method GET -Uri $APIUrl -ContentType "application/json" 
        $GraphResultList += $data.Value         
        $APIUrl = $data.'@Odata.NextLink'
        
    }
    
    return $GraphResultList
    
}

$Results = Get-TAMgGraphAllData -Url "https://graph.microsoft.com/beta/security/auditLog/queries/$AuditLogNewQueryID/records?`$top=1000"
$Results.Count


Das Ergebnis sind 5.786 Zeilen.

Im Compliance Center erkenne ich die Ergebnisse meiner Aufträge.

  • Aktivitäten vom Service AzureActiveDirectory 8.000+.
  • Aktivitäten von AlexW 801.
  • Aktivitäten von TanjaK 41.
Audit Log Suchaufträge
Audit Log Suchaufträge

Es fällt auf, zwischen API und Compliance Center zeigt das System unterschiedliche Total Results.
Anfangs fragte ich mich warum es zwischen Compliance Center und API eine Differenz gibt. Alle Konten sind mit Microsoft 365 E5 lizenziert, es sollte beim Export keine Limitierung geben.

Export supports results up to 50 KB for Audit (Standard) and up to 500 KB (500,000 rows) for Audit (Premium).

Ich führte darum noch die Auswertung mit Tanja K. durch. Das Konto hat mit 41 sehr wenige Aktivitäten und lässt sich manuell kontrollieren/zählen.

Die API gibt mir 26 Ergebnisse zurück, gegenüber dem Compliance Center wieder eine Differenz.

Kontrolle des Auftrags im Audit Log des Compliance Centers.
Der Auftrag zeigt 41 Ergebnisse, der Filter 52 Items (es ist kein Filter aktiv und alle Zeilen geladen). Zählt man die Zeilen sind es 26 Ergebnisse. Die Anzahl der API über 26 gefundene Einträge stimmt. Export nach Excel inkludiert ebenfalls die 26 Zeilen. Die Angabe über Total Results im Compliance Center stimmt scheinbar nicht.

Auch bei meinen zwei anderen Tests ist es ein ähnliches Ergebnis.

  • Aktivitäten vom Service AzureActiveDirectory inkludieren über die API 5.786 Zeilen, statt 8.000+.
  • Aktivitäten von Alex W. inkludieren über die API 518 Zeilen, statt 801.

Ich probierte es noch in zwei anderen Tenants. Total Results ist immer höher als das Ergebnis im Export. Die API gibt die korrekten Ergebnisse zurück, ebenfalls ein Export.

Share
Avatar-Foto

Tobias Asböck

Tobias ist ein Senior System Engineer mit rund 10 Jahren Berufserfahrung für Microsoft 365 Produkte wie SharePoint Online, OneDrive for Business, Teams Collaboration, Entra ID, Information Protection, Universal Print und Microsoft 365 Lizenzierung. Aus der Vergangenheit kennt er über einen Zeitraum von 15+ Jahren die Planung, Administration und den Betrieb von SharePoint Server Umgebungen. Tobias ist ein PowerShell Scripter mit Zertifizierungen für Microsoft 365 Produkte. In seiner Freizeit beschäftigt sich Tobias mit Aktualisierungen in der M365-Welt, ist mit seinem Rennvelo unterwegs und anderen sportlichen Aktivitäten beschäftigt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert