Using the Azure AD Graph Reporting API from PowerShell

In an earlier article (source) i demonstrated how to use the Azure AD Graph REST API to do things in Azure AD such as creating users, getting users and license users. This time, we will use the new Repoting API.

What you must first do, is to follow the first steps in this article to create your application. Follow the same steps all the way to “permissions to other applications”. The Reporting API only requires “read directory data”, not “read and write directory data”. As of writing, it actually seems it does not work with “read and write directory data” at all, only if you check “read directory data” does things start to work (you will see an error message like “Unable to check Directory Read access for appId”).

Here is an example of application that gets an oauth token using ADAL and requests a list of all reports:

Add-type -Path C:\GraphAPI\Microsoft.IdentityModel.Clients.ActiveDirectory.2.18.206251556\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll

$clientID = "26b2e067-291d-4ad7-9cd2-2e1fae15c905"
$clientSecret = "7dAkpp6sCfc3n6bfsBRoBYORnMFYeA7LsLVkQX+rAn0="
$resAzureGraphAPI = "";

$serviceRootURL = ""
$authString = "";

[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]$AuthContext = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]$authString
[Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential]$clientCredential = New-Object -TypeName "Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential"($clientID, $clientSecret)

$authenticationResult = $AuthContext.AcquireToken($resAzureGraphAPI, $clientCredential);

Invoke-RestMethod -Uri "$serviceRootURl/reports?api-version=beta" -Headers @{Authorization=$authenticationResult.CreateAuthorizationHeader()} -ContentType "application/json" | select -ExpandProperty value

This will return something like:

Here are some further examples on what you can do. Please note that if the reports are empty, you seem to be getting the error “An error occurred while processing this request” for some of the reports.

# Gets the Multi-Geo signin report and outputs to screen, grouped by username.
Invoke-RestMethod -Uri "$serviceRootURl/reports/signInsFromMultipleGeographiesEvents?api-version=beta" -Headers @{Authorization=$authenticationResult.CreateAuthorizationHeader()} -ContentType "application/json" |
    Select -ExpandProperty Value |
    Group UserName |
    Foreach {
        Write-Host -ForegroundColor Yellow "----- $($_.Group[0].DisplayName) ($($_.Name)) -----"
        $_.Group | Foreach {
            Write-Host "First signin from:   $($_.firstSignInFrom)"
            Write-Host "Second signin from:  $($_.secondSignInFrom)"
            Write-Host "Time:                $($_.timeOfSecondSignIn)"
            Write-Host "Time between:        $($_.timeBetweenSignIns)"
            Write-Host "Estimated travel:    $($_.estimatedTravelHours) hours"
            Write-Host ""

# Gets the report for users with many failed logon attemps, before suddenly being able to sign in
Invoke-RestMethod -Uri "$serviceRootURl/reports/signInsAfterMultipleFailuresEvents?api-version=beta" -Headers @{Authorization=$authenticationResult.CreateAuthorizationHeader()} -ContentType "application/json" | Select -ExpandProperty Value

# Sends an email to each user informing them of the irregular sign ons the last 24 hours
$uri = '{0}/reports/signInsFromMultipleGeographiesEvents?api-version=beta&$filter=timeOfSecondSignIn gt {1}' -f $serviceRootURl, ((Get-Date (Get-Date).AddDays(-1) -Format "u") -replace " ", "T")
Invoke-RestMethod -Uri $uri -Headers @{Authorization=$authenticationResult.CreateAuthorizationHeader()} -ContentType "application/json" |
    Select -ExpandProperty Value |
    Foreach {
        #Send-MailMessage -From '"IT Department" ' -To
        $params = @{
            Body = "Hi,<br /><br />According to our reports your account was first signed in from '$($_.firstSignInFrom)', and then $($_.timeBetweenSignIns) later, you were signed in from '$($_.secondSignInFrom)'. The estimated travel time is $($_.estimatedTravelHours) hour(s). <br /><br />Please review, and if this looks suspicious to you, change your password.<br /><br />- IT"
            To = ('"{0}" ' -f $_.displayName, $_.username)
            From = '"IT Department" '
            Subject = "Suspicious logon activity for your account"
            BodyAsHtml = $true
            SmtpServer = ""
            UseSSL = $true
            Credential = (Get-Credential -Message "Input office 365 credentials for sending mail")

        Send-MailMessage @params

Hope it helps!