Find List Of Inactive Users In Microsoft 365 Using PowerShell

Finding inactive users in an organization is very difficult where hundreds of users are working. Many organizations share information with external users or guest users who do not belong to their organization. For example, some companies connect with their customers on MS teams or shares information through SharePoint or One Drive where they provide access as guest users. Many times, companies do not have information about whether those guests’ users are still active or not. How many days they last logged in?

One simple solution is login to Azure Active Directory and navigate to a specific user and get the last login date. But it is very time-consuming to go to every single user and get the last login date.

Another solution is Azure Audit Log which captures users’ activity with datetime.

Get-AzureADAuditSignInLogs -Filter “userPrincipalName= ' UserPrincipalName '” -Top 1

The parameter -Top is for the maximum number of records to return. In case of above we will get last one record.

The above PowerShell command returns last sign in datetime of the specific user of any of the apps like MS Teams, SharePoint, One Drive, etc. Use Get-AzureADUser to get a list of users and loop through it to get each specific user’s last sign-in date. Here, there is one challenge in using Get-AzureADAuditSignInLogs command in loop. It returns a throttling issue when looping through a set of users.

To resolve the problem, just add Start-Sleep -Milliseconds 10 at the end of each request. We will be using this in try/catch.

Below is the complete PowerShell script which reads users from Azure AD, get last sign-in date of each user, and save it in CSV file.

Function FindLastSignInDate {
    param ( [string]$upn )
    $AllUsers = @()
    $DateToday =(Get-Date).ToString("yyyy-MM-dd")
    $Days = 0
    $filter = "userPrincipalName = '" + $upn + "'"
    Try {
       $Result = Get-AzureADAuditSignInLogs -Filter $filter -Top 1 | Select-Object CreatedDateTime, UserPrincipalName
        $LoginTime = $Result.CreatedDateTime
        if($LoginTime -ne $null){
            $LoginDate = $LoginTime.substring(0,10)
            $ts = New-TimeSpan -Start $LoginDate -End  $DateToday
            $Days = $ts.Days
            $AllUsers += [pscustomobject]@{
                UPN= $UPN
                LoginDate = $LoginDate
                Days = $Days
            }
    }
    Catch
    {
            sleep 10
            GetLastSignInDate $upn
    }
    finally {
        $AllUsers | Out-File "c:\LastLogin.csv" -Append
    }
}
Import-Module AzureADPreview
$Result = ""
$output = ""
$filter = ""

#Connect to Azure AD
$user = "[email protected]"
$password = "xxxxxxxxxxxx"
$secPass = ConvertTo-SecureString $password -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ($user, $secPass)
Connect-AzureAD -Credential $Cred
$Users = Get-AzureADUser -all $true
Foreach($user in $Users ){
    $upn = $user.UserPrincipalName.ToLower().Trim()
    FindLastSignInDate $upn
}

The above script will create a CSV file.