Guest User Last Sign-in date time in Azure Active Directory and automatic cleanup

Azure AD’s sign in logs also only go back 30 days, which makes it highly recommended to stream Azure AD’s sign in logs to a Log Analytics workspace (Azure Monitor). You just need one single P1 license in your tenant to be able to enable this.

However, even if you don’t stream your sign in logs, Microsoft does keep track of when an account last signed in.

My script gets the last sign in data of all guest accounts in your tenant, without any dependencies other than the Az PS module.

If a guest user has never signed in, the creationDate is used to determine inactivity. Otherwise either the last interactive or last non interactive sign in is used (whichever is most recent).

Additionally, the script can also be configured to automatically clean up any guest accounts that have been inactive for a given number of days by using the -removeInactiveGuests switch.

Even in large environments, processing only takes a few minutes at most.

Download

Download the script from my Gitlab here:

https://gitlab.com/Lieben/assortedFunctions/-/blob/master/get-AzureAdInactiveGuestUsers.ps1

Limitations

Microsoft started using these properties in april 2020, so accounts active before that will seem like they have never been active.

Scheduling

This script supports running non-interactive as a runbook in Azure Automation if you supply the -nonInteractive switch. Before this will work, you’ll have to enable Managed Identity on your automation account and run a small script to assign graph permissions to the Managed Identity: AuditLog.Read.All and Organization.Read.All and if you also want it to be able to execute deletions: User.ReadWrite.All and assign the MI the ‘Privileged Authentication Administrator’ role in Entra.

Reports

If you wish, you can also let the script mail you a report in CSV format. Add the Mail.Send graph permissions like you did with device permissions and give the MailFrom and MailTo parameters a value.

Disclaimer

As always this script is provided as-is and should be reviewed and then used at your own risk.

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

31 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Andy Hill
Andy Hill
3 months ago

Hi, running the script non-interactively and if any attempts to remove guest accounts I get an Insufficient rights error on the Remove-Azuser command. I think I have granted rights to the MI to do this task. Am I missing something ?

h1tchiker
h1tchiker
11 months ago

Hi There, Thanks for providing this script 🙂 I am trying to test this on-prem in PWSH ISE and run the following: .\get-AzureAdInactiveGuestUsers.ps1 -inactiveThresholdInDays 730 -mailFrom Email@address.com -mailTo Email@address.com -readOnly I have check all the FW access, stripped out newer AZ modules so I am only running the ones specified in the script. I get the AZ login prompt and sign in is sucessful but the script never moves past: ‘Running in Read-Only mode, all logging and reporting will reflect what would happen if readOnly is not supplied, no actual deletions will occur’ I added a Start-Transcript and Stop-Transcript and… Read more »

Filip
Filip
1 year ago

Exactly what I was looking for, works like a charm, thanks !

Vinay
Vinay
1 year ago

Hi Jos,

Thanks for this script and helping community members in making life easier.
I would like to know when this script is executed does it directly remove/delete the guest users who never accepted invite and never logged in the tenant?

My goal is to just get the list of users who have not signed in or inactive loggings from XX days.

Please help

Kelly
Kelly
2 years ago

Hi, Thanks for this script. its exactly what we need. when i run the script. i get no progress at all. is there something im missing? looks like it hangs. any help would be hugely appreciated

Amir
Amir
2 years ago

Hi Jos, Thank you for posting this. So far it’s the only script that worked for me! Can this be used for All AAD users and not just guests? I modified your script and removed the guest filter, it pulled all users, but their Last Sign-in was set to Never for all!

Regarding the permissions, I’m running it as GA. Do I still need to modify anything?

Please advise.

Thank you,
Amir-

Martin
Martin
2 years ago

Im sure this great script worked. But now I get a message:

Invoke-RestMethod : The remote server returned an error: (403) Forbidden.
At C:\Temp\Guest.ps1:50 char:13
+ $userData = Invoke-RestMethod -Uri “https://graph.microsoft.com/beta/ ..

trackback

[…] with cleaning up inactive guest users, inactive devices also pose several issues for […]

Ludwig
Ludwig
2 years ago

With the Graph it is possible to get the signInActivity.lastSignInDateTime property. Is there a benefit for this purpose of the blog to use the workspace solution over this property?

maxcoder88
maxcoder88
2 years ago

Hi,

first of all thanks for your script. I have two simple question.

1- We have already Azure AD Premium P1.

I will choose only “Sign-in Logs”. correct ?

https://docs.microsoft.com/en-us/azure/active-directory/reports-monitoring/howto-integrate-activity-logs-with-log-analytics

2 – if I use this log analytics then Are there any extra costs?

thanks,