Introduction
As a Tenant Admin of an Office 365 Exchange Online organization, have you ever needed to monitor who, what, and where someone is connecting to your Exchange Online resources, like accessing mailboxes on mobile devices? I ran into this request a few weeks ago, from one of my customers. After hours of research, and testing I became a believer in the power of Microsoft Graph (Graph). By now you’re probably thinking, what is an Exchange engineer working with a graphing tool for? Well last month, that is exactly what I would have thought too. Surprising (to me) Graph is an extremely powerful tool that can interface with a large set of Microsoft services and technologies to pull data and perform tasks within the service/technology. Pulling sign-in data from Azure Active Directory (AAD) is a breeze with Graph. After the data is extracted, using Power BI for visualization brings your reporting capabilities to a new level! Let’s walk thru a scenario setup where as a Tenant Admin you can find out who is accessing mailboxes in your Exchange Online tenant on mobile devices, using Exchange ActiveSync protocol (which is used by default mail apps on Apple & Android devices) from anywhere in the world.Note: For this procedure to work for you, you need to have two subscriptions: Exchange Online (like E1 or E3) and Azure Active Directory Premium (like P1 or P2).
Allowing Graph Access to AAD Audit Log Data
AAD allows application access through the App Registration feature. To allow Microsoft Graph to query audit log data from AAD you must first create a new app registration. You can do this by logging into https://portal.azure.com and going to Azure Active Directory > App registrations (you may also see one option as ‘App registrations (Preview)’, we will not use that one).







Pulling the data with PowerShell
To connect to Graph with PowerShell you first need to obtain an OAuth token from logon.microsoft.com. For authentication, your application ID and key secret is used. This is done using the code below: You will need the following parameters for the PS script below. Application ID:
$ClientID = "[INSERT APPLICATION ID]"
$ClientSecret = "[INSERT KEY SECRET]"
$TenantDomain = "[INSERT TENANT DOMAIN]"
$OutputDirectory = "[INSERT DIRECTORY PATH]"
$loginURL = 'https://login.microsoft.com'
$resource = 'https://graph.microsoft.com'
$body = @{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$TenantDomain/oauth2/token?api-version=1.0 -Body $body
$headerParams = @{Authorization="$($oauth.token_type) $($oauth.access_token)"}
$url = 'https://graph.microsoft.com/beta/auditLogs/signIns'
$resultSet = (Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url)
$output = @()
ForEach($event in ($resultSet.Content | ConvertFrom-Json).value) {
If($event.clientAppUsed -eq "Exchange ActiveSync")
{
$output += $event
}
}
$output | Export-CSV "$OutputDirectory\EXOClientAccessUsageReport.csv" -NoTypeInformation
<###############Disclaimer#####################################################
The sample scripts are not supported under any Microsoft standard support
program or service. The sample scripts are provided AS IS without warranty
of any kind. Microsoft further disclaims all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness for
a particular purpose. The entire risk arising out of the use or performance of
the sample scripts and documentation remains with you. In no event shall
Microsoft, its authors, or anyone else involved in the creation, production, or
delivery of the scripts be liable for any damages whatsoever (including,
without limitation, damages for loss of business profits, business interruption,
loss of business information, or other pecuniary loss) arising out of the use
of or inability to use the sample scripts or documentation, even if Microsoft
has been advised of the possibility of such damages.
###############Disclaimer#####################################################>
#Declare unique instance variables
$ClientID = "[INSERT APPLICATION ID]"
$ClientSecret = "[INSERT KEY SECRET]"
$TenantDomain = "[INSERT TENANT URL]"
$OutputDirectory = "[INSERT DIRECTORY PATH]"
#Declare static variables
$loginURL = 'https://login.microsoft.com'
$resource = 'https://graph.microsoft.com'
#Build OAuth tequest
$body = @{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
#Request OAuth token
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$TenantDomain/oauth2/token?api-version=1.0 -Body $body
#If OAuth was successful request data from Microsoft Graph
If($null -ne $oauth.access_token)
{
#Build Microsoft Graph web request
$headerParams = @{Authorization="$($oauth.token_type) $($oauth.access_token)"}
$url = 'https://graph.microsoft.com/beta/auditLogs/signIns'
#Request data via web request to Microsoft Graph
$resultSet = (Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url)
#Place all events related to EXO into an array
$output = @()
ForEach($event in ($resultSet.Content | ConvertFrom-Json).value) {
If($event.appDisplayName -like "*Exchange *")
{
$output += $event
}
}
#Export all EXO events to a CSV
$output | Export-CSV "$OutputDirectory\EXOAccessReport.csv" -NoTypeInformation
}
Else
{
Write-Error "Failed to authenticate to OAuth, no token obtained."
}
Visualizing Data with Power BI
The geniuses that developed Power BI (download the Power BI desktop app from here) have made this next step so easy even I can do it! Launch Power BI desktop app and simply import the data using Get Data > Text/CSV, select your report (if you used the defaults it will be named EXOAccessReport.csv), and click Load.



Keeping it fresh
To ensure that the report is always up to date with the latest data, I recommend you configure the PowerShell script to run at an interval that meets your needs. This task could be easily accomplished by Task Scheduler, System Center Orchestrator, and many other task scheduling solutions. For the purposes of this post we will use Task Scheduler since it is readily available on most versions of Windows. On the machine the script will be running from, launch Task Scheduler by pressing Windows + R then typing taskschd.msc and clicking OK. Click Create Task in the Actions pane on the right hand side of the window.



Reading the Report
Now that we have created an amazing Power BI visualization how do we view it? Navigate to https://app.powerbi.com/groups/me/list/reports then click on the report we just created.


Conclusion
Using Microsoft Graph, PowerShell, Task Scheduler, and Power BI we created an auto updating report to track Exchange Online user logins.
Updated Jul 01, 2019
Version 2.0The_Exchange_Team
Microsoft
Joined April 19, 2019
Exchange Team Blog
You Had Me at EHLO.