Extending the Usefulness of Sign-in Audit Data

A few weeks ago, I wrote about how to use the Entra ID audit sign-in logs to understand how users and applications interact with Entra ID. It’s the kind of knowledge that helps Microsoft 365 administrators understand how their tenants tick.

Today, I’m going to take a slightly different approach by combining sign-in data with the last sign-in date for user accounts to generate a report about when users last signed in successfully and the apps they use. After all, understanding that someone can sign into a tenant successfully is valuable; knowing what apps they use can be even more important.

Discovering the Apps People Use

First, let’s get some information about the apps detected in user sign-ins. This code fetches the latest 20,000 sign-in audit logs and counts the number of instances for each app. I’m showing the top eight apps found in my tenant. Remember, Entra ID keeps sign-in records for 30 days and that the data shown here is purely for illustrative purposes. What you see in your tenant will reflect the apps people use, how they access those apps, and how often users are required to sign in.

[array]$SignIns = Get-MgAuditLogSignIn -Top 20000 -PageSize 500
$SignIns | Group-Object AppdisplayName -NoElement | Sort-Object Count -Descending | Format-Table Name, Count


Name                                           Count
----                                           -----
Microsoft Teams                                 7006
Microsoft 365 Security and Compliance Center    1933
Microsoft Edge                                   864
Microsoft Exchange Online Protection             853
Microsoft Edge Enterprise New Tab Page           842
Office365 Shell WCSS-Client                      695
Augmentation Loop                                625
Office 365 Search Service                        622

It’s normal to see a lot of sign-in activity for Teams. Every hour or so, because their access token expires, Teams clients renew the access token and sign in automatically to keep users connected. Among the other apps, we see a lot of client activity through the Edge browser and lots of interaction with the Purview compliance portal, which accumulates sign-in events as users access the various Purview solutions.

The Office365 Shell WCSS-Client is worthy of common. This is a very common entry in any analysis of sign-in data because the shell client (also known as the suite header) is code that runs whenever a user navigates between Microsoft 365 applications in a browser. It does things like retrieve information about the licensing state for the signed-in user to allow the app launcher to restrict its display to apps that the user is entitled to access. It also connects to the user’s Exchange Online mailbox to fetch details of upcoming events and notifications, and to the Microsoft Graph to retrieve user settings like the browser theme. The app also fetches information about the most recently used (MRU) list for the user. Because users commonly navigate from app to app during a session, several events for the client can show up in the sign-in audit log as the shell client fetches and caches different information from different workloads.

Modifying App Names

Now that we know the frequency of app sign-in, we can create a list of the apps found. The reason to do this is that some of the app names are not obvious (like the shell client). By exporting the app data to a CSV file, we can edit the app names to make them more understandable. Here’s what we do to create and export the CSV file:

$Apps = $SignIns | Sort-Object AppId -Unique
$AppInfo = [System.Collections.Generic.List[Object]]::new()
Foreach ($App in $Apps) {
   $ReportLine = [PSCustomObject][Ordered]@{
      'App' = $App.AppId
      'Name' = $App.AppDisplayName
   }
   $AppInfo.Add($ReportLine)
}
$AppInfo = $AppInfo | Sort-Object Name

$AppInfo | Export-Csv c:\temp\AppInfo.CSV -NoTypeInformation

I normally edit the app file with Excel (Figure 1) and scan through the names to see if I can replace any with better names. Microsoft documents first-party apps and their identifiers, but the information available online is incomplete and doesn’t cast any more light on what many of the apps do. To be fair to Microsoft, the engineers who named the apps probably didn’t set out with the intention of making the intention behind the apps very obvious.

Editing app name
Figure 1: Editing app names

After customizing the app names, we can load them into a hash table for lookup by the script with code like this:

$AppDataAvailable = $false
$AppDataFile = 'C:\temp\AppInfo.csv'
If (Test-path $AppDataFile) {
    $AppDataAvailable = $true
    [array]$AppDataInfo = Import-CSV $AppDataFile
    $AppDataHash = @{}
    ForEach ($App in $AppDataInfo) {
        $AppDataHash.Add($App.App, $App.Name)
    }
}   

The Main Script

The main script, which you can download the script from GitHub finds the set of licensed Entra ID user accounts, excluding any Exchange Online shared and room mailboxes that have licenses, and does the following for each account:

  • Finds the last successful sign in date, or if this property is unavailable, the last sign-in date.
  • Calculate how many days it’s been since the last sign-in. If this is 30 or less (the maximum range for Entra ID audit sign-in records), the script fetches the last 50 sign-in events. If you consider that this isn’t enough to create a good analysis, you can increase the number of fetched events. Doubling the number will increase the time required to process each account by 1-2 seconds.
  • Finds the set of unique application identifiers from the set of sign-in events and checks each identifier against the hash table of app names to build the set of apps the user has signed into.

After extracting the various bits of data to construct a report, the script sorts the data by the last sign-in date and outputs the result through the Out-GridView cmdlet (Figure 2) and either an Excel worksheet or CSV file, depending on whether the ImportExcel module is installed on the workstation.

User sign ins with app sign-in information
Figure 2: User sign-ins with app sign-in information

The result is that we now know the last sign-in dates for user accounts together with the most recent applications they have signed into. Checking audit logs makes it slower to report user sign-ins, but I think the extra data is worthwhile.

Audit Logs for Non-Interactive Sign-ins

The Get-MgAuditLogSignIn cmdlet returns data for interactive sign-ins. User accounts can also be used for non-interactive sign-ins, such as when they are used to run a scheduled Power App flow. To find details of interactive sign-ins for a user account, use the Get-MgBetaAuditLogSignIn cmdlet and specify the “interactiveUser” event type. To find non-interactive sign-ins, look for events that are not of that type. For example:

[array]$AuditSignIns = Get-MgBetaAuditLogSignIn -Filter "userId eq '$UserId' and (signInEventTypes/any(t:t ne 'interactiveUser'))" -Top 50

Make sure to use the account identifier rather than the user principal name for this kind of lookup.

Building a Picture

When I discuss the topic of using PowerShell to manage Microsoft 365 at conferences and other events, I often discover that people are very focused on exploiting a single data source and don’t think about how they can combine information from multiple sources to construct a more complete picture. They also accept whatever data Microsoft makes available. There’s no doubt that valuable insight can be gained from individual data sources, but it’s often better when you cast a net more widely, like we did here.

About the Author

Tony Redmond

Tony Redmond has written thousands of articles about Microsoft technology since 1996. He is the lead author for the Office 365 for IT Pros eBook, the only book covering Office 365 that is updated monthly to keep pace with change in the cloud. Apart from contributing to Practical365.com, Tony also writes at Office365itpros.com to support the development of the eBook. He has been a Microsoft MVP since 2004.

Leave a Reply