Search code examples
azurepowershellazure-active-directorymicrosoft-graph-apiazure-powershell

AzureAD Inactive User Monitoring


I'm currently working on monitoring inactive user accounts within AzureAD (or EntraID). To do this, I'm using PowerShell with MgGraph to collect user information and their last sign-in date.

To filter out only Azure users (not on-premises), I'm using the OnPremisesSyncEnabled attribute. However, this attribute appears to be empty in our environment, which is causing some challenges in identifying the desired user accounts.

I wrote the following script (connection to Graph has already been done)

$users = Get-MgUser -All | Where-Object { $_.OnPremisesSyncEnabled -eq $none -and $_.UserType -ne "Guest" -and $_.SignInActivity.LastSignInDateTime -lt (Get-Date).AddDays(-180) }

$users | Select-Object UserPrincipalName, OnPremisesSyncEnabled, @{Name="LastSignIn"; Expression={$_.SignInActivity.LastSignInDateTime}}

This script returns nothing... does someone have an idea on how to monitor this properly?


Solution

  • The OnPremisesSyncEnabled property is only retrieved on $select (-Select when using Get-MgUser) when pointing to the v1.0 endpoint. See Properties.

    As aside, you can use $filter (-Filter) in this case to make your query more efficient. The alternatives could be:

    • Find users where the onPremisesSyncEnabled is null and userType is not Guest

      -Filter "onPremisesSyncEnabled eq null and userType ne 'Guest'"
      

      Note: The query using this filtering condition will require the use of -CountVariable and -ConsistencyLevel 'eventual'.

    • Find users having a lastSignInDateTime lower than or equal to a target date

      $date = [datetime]::UtcNow.AddDays(-180).ToString('s') + 'Z'
      -Filter "signInActivity/lastSignInDateTime le $date"
      

    Unfortunately, both filters can't be combined, the query to signInActivity must go alone:

    doc

    Also, note that you will also require User.Read.All and AuditLog.Read.All (for signInActivity) permissions. See also How to detect and investigate inactive user accounts for relevant information.

    So here is how the code would look filtering on signInActivity:

    $date = [datetime]::UtcNow.AddDays(-180).ToString('s') + 'Z'
    $getMgUserSplat = @{
        Filter = "signInActivity/lastSignInDateTime le $date"
        Select = 'UserPrincipalName', 'OnPremisesSyncEnabled', 'signInActivity', 'userType'
        All    = $true
    }
    
    $users = Get-MgUser @getMgUserSplat |
        Where-Object { -not $_.OnPremisesSyncEnabled -and $_.userType -ne 'Guest' } |
        Select-Object UserPrincipalName, OnPremisesSyncEnabled, @{ N='LastSignIn'; E={ $_.SignInActivity.LastSignInDateTime }}