How to Identify Inactive Users in Office 365: A Step-by-Step Guide

Requirement: Get inactive users report in Office 365.

How to Find Inactive Users in Office 365?

Inactive users are those who have not logged in to Microsoft 365 for a specified period of time. Inactive user accounts in your Office 365 environment can pose a security risk and waste valuable resources. Fortunately, there are ways to identify and manage these users to ensure your data remains secure. In this guide, we’ll show you how to find inactive users in Office 365 and take the necessary actions to protect your organization.

Understand the Risks of Inactive Users

First and foremost, inactive users can pose a security risk to your organization. If an inactive user’s account is compromised, it can be used to access sensitive data, send phishing emails, or launch other types of attacks. Additionally, inactive users can waste valuable resources like licenses and storage space. Identifying and managing inactive accounts is important to ensure your data remains secure and your resources are used efficiently. Finding and disabling inactive users can free up licenses and save money for your organization. So, How do I get a list of active users in Office 365?

Method 1: Use the Microsoft 365 Admin Center

The Microsoft 365 Admin Center is the central hub for managing your Microsoft 365 environment. One of the easiest ways to identify inactive users is by using the Microsoft 365 Admin Center. From the Admin Center, you can view a list of all the users in your organization and see when they last signed in. If a user has not signed in for a certain period of time, you can consider them inactive.

To find inactive users using this tool, follow these steps:

  1. Log in to the Office 365 Admin Center using your administrator credentials.
  2. Click on the “Users” tab in the left-hand menu.
  3. Click on the “Active users” tab at the top of the page.
  4. Search and find a specific user and click on the user name to open the user properties. In the user properties, look for “Last Sign-in”.
    office 365 check inactive users
  5. Once you have identified the inactive users, you can either delete their accounts or reset their passwords to force them to log in and reactivate their accounts.

However, this method can capture only the past 30 days sign-in log and doesn’t cover the service logins. Furthermore, checking the sign-in log of each user in the environment through the web browser interface can be cumbersome.

Method 2: Use Azure AD PowerShell Script

PowerShell is a powerful command-line tool that can be used to automate a wide variety of tasks in Microsoft 365. You can use PowerShell scripts to automate the process of identifying and managing inactive users in your environment. Run the below script that will identify all the inactive users in your organization, display them in a list, and export to a CSV file.

Make sure you have AzureAD and AzureADPreview modules installed prior to executing this script! Use:
Install-Module AzureAD
Install-Module AzureADPreview -AllowClobber -Force

To use PowerShell to find inactive users, follow these steps:

  1. Open PowerShell ISE on your local computer.
  2. Connect to your Microsoft 365 Azure Active Directory environment by running the following command: Connect-AzureAD
  3. Get all users in your environment using Get-AzureADUser cmdlet and iterate through each one of them.
  4. Search the Sign-in logs to get a list of all users who have not signed in for a certain amount of time with Get-AzureADAuditSignInLogs. Along with the Sign-in timestamp, it offers much other information, including IP Address, Device, Location, etc.
  5. Collect and export the details to a CSV report.
#Config Parameters
$InactiveDays = 30 # Past number of days user didn't login
$CSVPath = "C:\Temp\InactiveUsers.csv"
$InactiveUsers = @()
$ThresholdDate = (Get-Date).AddDays(-$InactiveDays)
$QueryStartDateTimeFilter = "{0:yyyy-MM-dd}T{0:HH:mm:sszzz}" -f $ThresholdDate

#Connect to Azure AD
Connect-AzureAD | Out-Null

#Get All users from Azure AD
$AllUsers = Get-AzureADUser -All $true
$TotalUsers = $AllUsers.Count

#Function to get the last login date time stamp of the user
Function Get-UserLastLogin([string] $UserObjectID)
{
    Try {
        Write-host -f Yellow "Collecting Last Login date of User Object:"$UserObjectID

        #Get Signin Logs of the user on specific time frame
        $SigninLog = Get-AzureADAuditSignInLogs -All:$true -Filter "userID eq '$UserObjectID' and status/errorCode eq 0 and createdDateTime ge $QueryStartDateTimeFilter" | Select -First 1

        #Return Last Login Date
        Return $SigninLog.CreatedDateTime
    }
    Catch {
        $message = $_
        If ($message -like "*Too Many Requests*")
        {
            Write-host "`tSleeping for 10 seconds due to throttling limitations..." -ForegroundColor Cyan 
            Sleep 10
            #Recursive function call to retry the entry that was throttled
            Get-UserLastLogin $UserObjectID
        }
        Else
        {
            Write-host $Message -ForegroundColor Red           
        }
    }
}

$Counter = 1
$AllUsers | ForEach-Object {
    Write-Progress -Activity "Checking Signin Logs:" -Status "Processing $($_.UserPrincipalName) ($Counter of $TotalUsers)" -PercentComplete (($Counter / $TotalUsers) * 100) 
    #Call the function to get sign-in log
    $LastLoginDate = Get-UserLastLogin $_.ObjectID
    
    #Collect data
    If(!$LastLoginDate -or ($LastLoginDate -and ((Get-Date $LastLoginDate) -lt $ThresholdDate)))
    {
        $InactiveUsers += [PSCustomObject][ordered]@{
            UserLoginName   = $_.UserPrincipalName
            UserDisplayName   = $_.DisplayName
        }
    }
    $Counter++
}

$InactiveUsers

#Export Data to CSV
$InactiveUsers | Export-Csv -Path $CSVPath -NoTypeInformation

You can adjust the $InactiveDays variable to define your inactivity threshold. However, the cmdlet Get-AzureADAuditSignInLogs is limited to only checking sign-in logs for the past 30 days! Users who have not logged in for a certain period of time, such as 90 days, are likely inactive and should be reviewed.

To get the last login date of External users, use:
$GuestUsers = Get-AzureADUser -All $true -Filter “usertype eq ‘guest'”

Method 3: Get Audit Log Reports for All Users using Microsoft Graph API

Finally, we have the Microsoft Graph API to overcome all the limits. Here is the PowerShell script to fetch the last login date for all users in your Office 365 environment.

#Parameters
$InactiveDays = 90 
$CSVPath = "C:\Temp\InactiveUsers.csv"
$InactiveUsers = @()
$ThresholdDate = (Get-Date).AddDays(-$InactiveDays)

#Connect to Microsoft Graph
Connect-MgGraph -Scopes "AuditLog.Read.All", "User.Read.All"

#Set the Graph Profile
Select-MgProfile beta

#Properties to Retrieve
$Properties = @(
    'Id','DisplayName','Mail','UserPrincipalName','UserType', 'AccountEnabled', 'SignInActivity'    
)

#Get All users along with the properties
$AllUsers = Get-MgUser -All -Property $Properties

ForEach ($User in $AllUsers)
{
    $LastLoginDate = $User.SignInActivity.LastSignInDateTime
    If($LastLoginDate -eq $null)
    {
        $LastSignInDate = "Never Signed-in!"
    }
    Else
    {
        $LastSignInDate = $LastLoginDate
    }

    #Collect data
    If(!$LastLoginDate -or ($LastLoginDate -and ((Get-Date $LastLoginDate) -lt $ThresholdDate)))
    {
        $InactiveUsers += [PSCustomObject][ordered]@{
            LoginName       = $User.UserPrincipalName
            Email           = $User.Mail
            DisplayName     = $User.DisplayName
            UserType        = $User.UserType
            AccountEnabled  = $User.AccountEnabled
            LastSignInDate  = $LastSignInDate
        }
    }
}

$InactiveUsers
#Export Data to CSV
$InactiveUsers | Export-Csv -Path $CSVPath -NoTypeInformation

This script generates an Office 365 inactive users report using PowerShell.

Determine the Best Course of Action for Each Inactive User

Once you have identified inactive users in your Office 365 environment, it’s important to determine the best course of action for each user. You can either delete/disable their accounts or reset their passwords to force them to log in and reactivate their accounts and prevent unauthorized users like former employees and contractors from accessing any sensitive information. Some users may simply need a reminder to log in and use their accounts, while others may need to have their accounts disabled or deleted to ensure the security of their data.

Consider factors such as the user’s role in your organization, their access to sensitive data, and their activity history before making a decision. It’s also important to communicate any changes to the user and provide them with any necessary resources or support.

Conclusion

Inactive users or stale accounts can pose a security risk to your Office 365 environment, so it’s important to regularly review and manage your user accounts. This includes identifying and deactivating accounts that are no longer needed or being used, and monitoring user activity to ensure that accounts are being used appropriately. By using PowerShell, you can automate the process of identifying inactive users, saving you time and effort. Whether you choose to use the Microsoft 365 Admin Center, PowerShell, or a third-party tool, managing your user accounts properly will pay off in the long run. Regularly monitoring and managing user accounts ensures that your Microsoft 365 environment is secure and efficient.

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

4 thoughts on “How to Identify Inactive Users in Office 365: A Step-by-Step Guide

  • I cross referenced a user said last sign in was may, in O365 they signed in today.

    Reply
  • Handy but the script only finds users that haven’t signed in interactively in x days. To be sure the users are inactive, activity details need to be included also:

    “https://graph.microsoft.com/v1.0/reports/getOffice365ActiveUserDetail(period=’D90′)”
    Then select the details needed:
    select “User Principal Name”, “display Name”, “Exchange Last Activity Date”, “OneDrive Last Activity Date”, “SharePoint Last Activity Date”, “Teams Last Activity Date”
    And determine the latest date from both results.

    Reply
  • Hi Team

    I need help with finding all the users who haven’t signed in or accessed their Office 365 account in the last 30 days in Azure Active Directory using Powershell. Could you please assist?

    Kind regards,

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *