Every so often when I run an audit on my environment, I’m always finding myself needing to check recent activity logs to specifically get Azure AD last login date and sign-in activity. If you recall, I wrote a previous post to Get Last Logon Date For All Users in Your Domain, but that script is specifically for Onprem Active Directory domain activity.
In this instance, we’re going to focus our efforts on compiling an Azure last login report using PowerShell. Our report would include something similar to the following:
- CreatedDateTime: Date and Time of when the sign-in occurred
- UserPrincipalName: UPN of the user
- IsInteractive: Whether or not the user signed in manually, or if it was through automation
- AppDisplayName: Which app the user was logging into
- IpAddress: In some instances it will display the public IP, or internal IP
- TokenIssuerType: If the authentication happened in ADFS or Azure AD
- DeviceOS: The operating system of the device
You can also add properties to determine the City/State location, device detail such as System OS and what client was being used. The information that is provided is very rich and it’s up to you to choose what suits your needs.
The great thing is that you don’t need to re-invent the wheel because the Azure AD module already has a cmdlet that encompasses all of the information that I mentioned above. That command is Get-AzureADAuditSignInLogs
Get Azure AD Last Login Date And Sign-In Activity in Azure Portal
There are methods of getting the information that we need, and those 2 methods are the GUI method as well as the Powershell method. We’ll focus on the GUI method first.
- Navigate to https://portal.azure.com -> Azure AD -> User you want to check -> Sign-Ins
The GUI is probably preferred when you need to check a handful of users, but as you can see this option is not very scalable. For batch processing, we’ll turn over to trusty Powershell.
Get Azure AD Last Login Report Using PowerShell
As I mentioned already, if we want to scale this operation, the GUI is simply not going to cut it. Just think how long it will take to check 100 users, 10,000? yeah not happening. The good thing is that it’s relatively easy to do it using PS.
In my example, I’m going to check Buzz Lightyear as we did in the GUI just to confirm that the data we’re pulling is the same. I should mention that you’ll need to download the Azure AD (or Azure AD Preview) module. I, myself, like to use the Azure AD Preview module.
#Import the Azure AD Module Import-Module AzureADPreview #Connect to Azure AD Connect-AzureAD -AccountId [email protected] Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '[email protected]'" -Top 1 | ` select CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress, TokenIssuerType, @{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}}
The above works great for checking a single user or multiple users. If we wanted to check more users, we would either need the UPN or ObjectId of that user and do a foreach loop. Here’s what that would look like.
$UPNList = '[email protected]', '[email protected]', '[email protected]' foreach ($User in $UPNList) { Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$User'" -Top 1 | ` select CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress, TokenIssuerType, @{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}} }
Conclusion
So there you have it, hopefully you found this article to get Azure AD last login date and sign-in activity useful and something you might be able to use in your org. Thankfully, the folks at Microsoft and Azure have this readily and easily available. If you like articles like this, be sure to check out our Azure category for more information on MS cloud. If you’re more into video learning, check out our Youtube Page for awesome sysadmin content.
Is there a way to find the last time a user signed on, regardless of when it was? This was easy in an on-prem environment, but seems unavailable for Azure/Entra. I would like a way to determine unused accounts.
The Get-AzureAdAuditSigninLogs value is quite useless when attempting to determine user accounts that have not been used recently as this only goes back 30 days. I would expect CreatedDateTime to return the date/time the account was created. I can’t tell what data is returned. Users are listed multiple times and the date is always today. This is useless. I don’t understand why Microsoft makes things so difficult these days. For on-prem, this is easily obtained by a single command (Get-ADUser) and the information is complete and accurate.
I seem to have dates going back three years… users with $null can be new users who have not logged on yet, and shared mailboxes (as it’s the accessing users account that logs on to those).
Was longer retention of this introduced at some stage?
I wrote a similar thing but we are at the mercy of the MS servers for responding to queries. A query for 100 users has so far taken over 2 hours to run. An on-prem query for 100 users finishes in about 3 seconds.
Thank you for include John Snow, Tony Stark, and Buzz Lightyear. This working for me.
Sadly this will not work if you don’t have a P1 / 2 Azure AD license:
Get-AzureADAuditSignInLogs : Error occurred while executing GetAuditSignInLogs
Code: Authentication_RequestFromNonPremiumTenantOrB2CTenant
Message: Neither tenant is B2C or tenant doesn’t have premium license
is there a way to get the same but for “non-interactive logon”?
I believe this only goes back 30 days?
That is correct. If there’s been no activity in the last 30 days, this will return $null. A better way would be calling https://graph.microsoft.com/beta/users/[email protected]?$select=displayName,signInActivity
Hi, great article!
I am a bit of newbie in this but I am trying to build a script that gives me the login status for a series of users.
I have tried this, but with no visible results:
#Import the Azure AD Module
Import-Module AzureADPreview
#Connect to Azure AD
Connect-AzureAD -AccountId [email protected]
$CSVData = @(Import-CSV -Path AzureADBulkUserCreation.csv -ErrorAction Stop)
Write-Verbose “Successfully imported entries from $FilePath”
Write-Verbose “Total no. of entries in CSV are : $($CSVData.count)”
Foreach ($Entry in $CSVData) {
# Verify that mandatory properties are defined for each object
$UserPrincipalName = $Entry.UserPrincipalName
}
foreach ($UserPrincipalName in $CSVData) {
Get-AzureADAuditSignInLogs -Filter “UserPrincipalName eq ‘$UserPrincipalName'” -Top 1 | `
select CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress, TokenIssuerType, @{Name = ‘DeviceOS’; Expression = {$_.DeviceDetail.OperatingSystem}}
}
Any idea of what could be going wrong?
Please check if the users in the CSV file have any Sign in logs available in the last 30 days.
I had the similar issue and realized that there were no Sign in logs for the users I tried in the last 30 days.