Return a permanently deleted user’s sign-in info with Get-MgUser

I recently picked up a quirk with Microsoft Graph that when filtering for users based on the user’s sign-in activity, if you combine that with selecting information such as the user displayName or UserPrincipalName, it can return objects that contain no personally identifiable information. Upon further inspection, these seem to be the logs for users who have been deleted from the directory. I would have assumed that the user’s corresponding logs would have been deleted at the same time the user was deleted, but this looks to not be the case. Lets take a look using the Microsoft Graph PowerShell SDK.

I will begin by connecting to Microsoft Graph and consenting to both the User.Read.All and AuditLog.Read.All permission. This is needed as the directory data and sign-in data are stored in two different data stores, that require different permissions to access.

 Connect-MgGraph -Scopes User.Read.All, AuditLog.Read.All

Once connected, I will start by filtering used based on the last sign-in date property. In the below example, I filter for users where their last sign-in date is less than the 1st June 2024.

 Get-MgUser -Filter "signInActivity/lastSignInDateTime le 2024-06-01T12:00:00Z"

As you can see, my command has returned only 6 results:

Get-MgUser by signindate
Get-MgUser by signindate

However, if I slightly adjust my command and select only the properties I want to be returned, such as the SignInActivity, DisplayName, Mail & UserPrincipal name, look what happens.

Get-MgUser -Filter "signInActivity/lastSignInDateTime le 2024-06-01T12:00:00Z" `
-select DisplayName,UserPrincipalName,Mail,IdUserType,SignInActivity

As you can see, I now have 8 results, however 2 of the items returned have no personally identifiable information associated with them.

Deleted user IDs returned
Deleted user IDs returned

This is because the directory data and the sign-in log data are stored in two separate locations on the back end. So when a user is deleted from Microsoft Entra, all the personally identifiable information (PII) is deleted, however, the sign-in information and the user ID are retained for the foreseeable. The issue is that when you filter by the sign-in activity and specifically select the SignInActivity property, you will mostly always return deleted (or ghosted) users from your directory.

The second part of this problem is attempting to filter out the deleted users using Microsoft Graph PowerShell. Another problem with this user data being spread over two backend systems is that you cannot combine Microsoft Graph filters across these data sources. I.e. you cannot filter by SignInActivity AND filter by whether the user contains PII in the same request. The only option would be to filter locally once all the data has been downloaded from Microsoft Graph. The below example will filter out any items where the UserPrincipalName is blank.

Get-MgUser -Filter "signInActivity/lastSignInDateTime le 2024-06-01T12:00:00Z" `
-select DisplayName,UserPrincipalName,Mail,IdUserType,SignInActivity `
| Where {$_.UserPrincipalName -ne $null}

To learn more about filtering with Microsoft Graph, check out my article How to Use -Filter with Microsoft Graph PowerShell.

Daniel Bradley

My name is Daniel Bradley and I work with Microsoft 365 and Azure as an Engineer and Consultant. I enjoy writing technical content for you and engaging with the community. All opinions are my own.

Leave a Reply