Jul 14 2021 06:33 AM - edited Jul 14 2021 10:24 PM
Hi Azure / Microsoft365 friends,
In a recent project, I was allowed to take on the following task. Search for all users (active users, not deactivated accounts) who had not logged in in the last 180 days. Clearly a case for PowerShell, right?
I used the PowerShell ISE for this configuration. But you are also very welcome to use Visual Studio Code, just as you wish. Please start with the following steps to begin the deployment (the Hashtags are comments):
#The first two lines have nothing to do with the configuration, but make some space below in the blue part of the ISE.
Set-Location C:\
Clear-Host
#Install MSOline Module
Install-Module -Name MSOnline -AllowClobber -Force -Verbose
#Import MSOline Module
Import-Module -Name MSOnline
#This connects to Microsoft 365
Connect-MsolService
#We need the module (without the parameter for a specific version)
Install-Module -Name ExchangeOnlineManagement -Force -Verbose
#More specific if you want
Install-Module -Name ExchangeOnlineManagement -RequiredVersion 2.0.5 -Force -Verbose
#Update the module (if necessary)
Update-Module -Name ExchangeOnlineManagement -Verbose -Force
#Let's import the module
Import-Module ExchangeOnlineManagement
#Check the version (if you have not selected a version)
Get-InstalledModule -Name ExchangeOnlineManagement
#Variable for the Credential
$UserCredential = Get-Credential
#Now we connect to Exchange Online
Connect-ExchangeOnline -Credential $UserCredential
#Another way to connect (choose one or the other)
Connect-ExchangeOnline -UserPrincipalName tom@wechsler.cloud
#Set admin UPN
$UPN = 'tom@wechsler.cloud'
#Time range
$startDate = (Get-Date).AddDays(-180).ToString('MM/dd/yyyy')
$endDate = (Get-Date).ToString('MM/dd/yyyy')
#We are looking for accounts that are active - not deactivated
$allUsers = @()
$allUsers = Get-MsolUser -All -EnabledFilter EnabledOnly | Select UserPrincipalName
#We search
$loggedOnUsers = @()
$loggedOnUsers = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate -Operations UserLoggedIn, PasswordLogonInitialAuthUsingPassword, UserLoginFailed -ResultSize 5000
#Create the list
$inactiveInLastSixMonthsUsers = @()
$inactiveInLastSixMonthsUsers = $allUsers.UserPrincipalName | where {$loggedOnUsers.UserIds -NotContains $_}
#We get a result
Write-Output "The following users have no logged in for the last 180 days:"
#written to the screen
Write-Output $inactiveInLastSixMonthsUsers
#Export list to CSV
$inactiveInLastSixMonthsUsers
$inactiveInLastSixMonthsUsers > "C:\Temp\InactiveUsers.csv"
#Remove the session
Disconnect-ExchangeOnline -Confirm:$false
Now we have a list in CSV format with all users who have not logged in during the last 180 days. Great! I know that wasn't super fancy at all. But I really wanted to share my experience with you.
I hope this article was useful. Best regards, Tom Wechsler
P.S. All scripts (#PowerShell, Azure CLI, #Terraform, #ARM, etc.) that I use can be found on github! https://github.com/tomwechsler
Jul 14 2021 09:19 AM
Jul 14 2021 08:59 PM
Jun 17 2022 08:09 AM
@TomWechsler Thank you for the script, is something a lot of people search for.
Still, for companies with lots of users, this script is not reliable as the 5000 records returned by Search-UnifiedAuditLog will cover only couple of days of logins and users will be reported as inactive even if they have logged in.
Jun 17 2022 08:32 AM
Jul 27 2022 02:02 PM
This would only pull users who have mailboxes right? I'm struggling to find this same data on users who have no activity the last 30 days, many who are unlicensed (the accounts were just for SSO purposes and had no license requirement)
Apr 16 2023 08:03 AM
Hi,
after execution gets a list of all users. And in my organization, Microsfot Teams services are actively used. What is the reason for this?
Apr 28 2023 05:39 AM
May 16 2023 02:43 AM
May 16 2023 03:02 AM
Dec 13 2023 08:51 AM
@Marc BeaudoinI think you want to change -"NotContains" to "Contains"
Dec 13 2023 08:53 AM