jbines / remove-staleguests Goto Github PK
View Code? Open in Web Editor NEWThis script removes stale Azure AD Guest accounts.
License: MIT License
This script removes stale Azure AD Guest accounts.
License: MIT License
Hi again,
Is it possible to enforce any admin to use only values greater than 120 when defining the InactiveTimeSpan value in the cmdlet in PowerShell?
This is probably something on my end but I've done my best to run through everything I could. In the notes, it mentions to use AzureADPreview. On my local computer, I uninstalled and installed the preview which I can confirm here
PS C:\PowershellScripts> Get-InstalledModule Azure*
Version Name Repository Description
------- ---- ---------- -----------
2.0.2.138 AzureADPreview PSGallery Azure Active Directory V2 Preview Module. ...
In the notes it mentioned I need to make sure I'm connecting the session to AzureAD which I have done by adding Connect-AzureAD after the param section, however it doesn't seem to be connecting the session for some reason.
Here's the output when I try this command
PS C:\PowershellScripts> .\Remove-StaleGuests.ps1 -ExportCSVPath guest.csv
Get-AzureADUser Get-AzureADAuditDirectoryLogs Set-MailUser Get-MailUser does not exist
[2021-10-25 18:22:54] [ERROR] :: Script requires a higher level of access! You are missing the connection to the AzureADPreview Module or PSession to ExchangeOnline. You are missing access to
Get-AzureADUser,Get-MailUser,Set-MailUser,Get-AzureADAuditDirectoryLogs
I must be doing something wrong but I'm just not sure how to connect the AzureAD session to powershell or the ps1. To be clear I can run Connect-AzureAD in the session just fine, but it's not passing it through to the ps1 either
I'm running into an issue where I'm getting an error 403 forbidden when running the script. I am our tenant global admin, have registered an app, assigned an auth certificate with private key, am connected to azureAD and exchangeonline via powershell, and running in elevated powershell. I've looked at the location in the script that is writing the error, but am unsure what is triggering it, or what is causing the 403. Any advice is appreciated.
`[2022-03-01 12:35:36] [DEBUG] :: Correct RBAC Access Confirmed
[2022-03-01 12:35:36] [SUCCESS] :: Authenication via Certificate - Completed!
[2022-03-01 12:35:37] [Error] :: The remote server returned an error: (403) Forbidden.
Write-Log : [2022-03-01 12:35:37] [Error] :: The remote server returned an error: (403) Forbidden.
At C:\scripts\Remove-StaleGuests.ps1:399 char:9
Write-Log -Message $ErrorMessage -LogLevel Error -ConsoleOutp ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I think I'm missing something here, I have read the documentation, and I've run the command "-InactiveTimeSpan 182 -RemoveExpiredGuests:$true" - which has removed expired guest invitations correctly (over 700!) - but I am assuming to remove all guests that haven't been active in 182 days I need to actually capture information for that long, as the Azure logs don't go back that far, so I need to keep running this script to update the time stamps?
According to the last CSV output 1069 out of 1217 haven't logged on at all (but have accepted invitations) and the remainder have logged in within the last 40 days.
Thanks in advance, I'm sure I'm missing something simple, I just don't want to remove users that are still valid.
Some issues I've found:
Line 6 usage says:
[-ExportCSVPath <String>]
Line 15 however says
"This is a switch only and the filename will be set via the script"
So Line 6 shouldn't have an optional <String>
?
Line 22 usage says:
Remove-StaleGuests.ps1 -- REPORT ONLY -- In this example the script will provide detailed report information on your guest accounts.
However line 61 suggests InactiveTimeSpan is Mandatory [Parameter(Mandatory = $True)]
so the above usage errors. I've also just ran the script as this example says (no switches so in report mode) and it's made changes:
Set-NewTimeStamp;CMDlet:Set-MailUser;UPN:...
Not ideal. No log file either, apart from to console.
I've also installed the latest AzureADPreview (2.0.2.102) and the script test passed the Test-CommandExists
function however it didn't check and failed on:
The term 'Get-MailUser' is not recognized as the name of a cmdlet...
I'm breaking this out into a separate issue as I can't find a work around.
I'm getting rate limited / throttled when running this script. See errors far below.
Basically, this line $guestLastLogonDate = (Get-AzureADAuditSignInLogs -Top 1 -Filter "userid eq '$guestObjectID' and status/errorCode eq 0").CreatedDateTime
is getting rate limited/throttled.
I experimented some, I'm not great at powershell but I added Start-Sleep -Seconds 2
directly under foreach($guest in $guestUsers){
at line 249. It makes it painfully slow however it no longer gives error 429 too many requests. At least that was the case the other night. Today I was just attempting to timestamp guest accounts with .\Remove-StaleGuests.ps1 -InactiveTimeSpan 180
and no matter if I add a 3 or 5 second delay, it still immediately errors.
I'm not good enough with powershell to know how to do this but is there a way to add a one or 2 second delay INSIDE this set variable? $guestLastLogonDate = (Get-AzureADAuditSignInLogs -Top 1 -Filter "userid eq '$guestObjectID' and status/errorCode eq 0").CreatedDateTime
Maybe there's a better way? Let me know what you think.
Detailed errors:
PS C:\PowershellScripts> .\Remove-StaleGuests.ps1 -ExportCSVPath guest3.csv
[2021-10-27 14:45:22] [DEBUG] :: Correct RBAC Access Confirmed
[2021-10-27 14:45:23] [DEBUG] :: Processing Guest Users - Total Found: 116
Get-AzureADAuditSignInLogs : Error occurred while executing GetAuditSignInLogs
Code: UnknownError
Message: Too Many Requests
InnerError:
RequestId: 364a1997-**********************55e9
DateTimeStamp: Wed, 27 Oct 2021 21:45:25 GMT
HttpStatusCode: 429
HttpStatusDescription: Too Many Requests
HttpResponseStatus: Completed
At C:\PowershellScripts\Remove-StaleGuests.ps1:271 char:32
+ ... ogonDate = (Get-AzureADAuditSignInLogs -Top 1 -Filter "userid eq '$g ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-AzureADAuditSignInLogs], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.MSGraphBeta.Client.ApiException,Microsoft.Open.MSGraphBeta.PowerShell.Get
AuditSignInLogs
Name CreatedDateTime LastlogonDate DaysSinceLastLogon
---- --------------- ------------- ------------------
Je*********d 4/18/2019 6:27:06 PM
Get-AzureADAuditSignInLogs : Error occurred while executing GetAuditSignInLogs
Code: UnknownError
Message: Too Many Requests
InnerError:
RequestId: d14d13*****************cc5f149
DateTimeStamp: Wed, 27 Oct 2021 21:45:25 GMT
HttpStatusCode: 429
HttpStatusDescription: Too Many Requests
HttpResponseStatus: Completed
At C:\PowershellScripts\Remove-StaleGuests.ps1:271 char:32
+ ... ogonDate = (Get-AzureADAuditSignInLogs -Top 1 -Filter "userid eq '$g ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-AzureADAuditSignInLogs], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.MSGraphBeta.Client.ApiException,Microsoft.Open.MSGraphBeta.PowerShell.Get
AuditSignInLogs
M***********huk 4/18/2019 6:28:58 PM
Get-AzureADAuditSignInLogs : Error occurred while executing GetAuditSignInLogs
Code: UnknownError
Message: Too Many Requests
InnerError:
RequestId: 2e4*******************************139deb
DateTimeStamp: Wed, 27 Oct 2021 21:45:26 GMT
HttpStatusCode: 429
HttpStatusDescription: Too Many Requests
HttpResponseStatus: Completed
At C:\PowershellScripts\Remove-StaleGuests.ps1:271 char:32
+ ... ogonDate = (Get-AzureADAuditSignInLogs -Top 1 -Filter "userid eq '$g ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-AzureADAuditSignInLogs], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.MSGraphBeta.Client.ApiException,Microsoft.Open.MSGraphBeta.PowerShell.Get
AuditSignInLogs
Pa**************ay 5/8/2019 10:02:46 PM
Get-AzureADAuditSignInLogs : Error occurred while executing GetAuditSignInLogs
Code: UnknownError
Message: Too Many Requests
InnerError:
RequestId: fead***********553516
DateTimeStamp: Wed, 27 Oct 2021 21:45:27 GMT
HttpStatusCode: 429
HttpStatusDescription: Too Many Requests
HttpResponseStatus: Completed
At C:\PowershellScripts\Remove-StaleGuests.ps1:271 char:32
+ ... ogonDate = (Get-AzureADAuditSignInLogs -Top 1 -Filter "userid eq '$g ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-AzureADAuditSignInLogs], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.MSGraphBeta.Client.ApiException,Microsoft.Open.MSGraphBeta.PowerShell.Get
AuditSignInLogs
S********av... 4/18/2019 6:28:37 PM
Get-AzureADAuditSignInLogs : Error occurred while executing GetAuditSignInLogs
Code: UnknownError
Message: Too Many Requests
InnerError:
RequestId: 2b28**********************1b8f60
DateTimeStamp: Wed, 27 Oct 2021 21:45:27 GMT
HttpStatusCode: 429
HttpStatusDescription: Too Many Requests
HttpResponseStatus: Completed
At C:\PowershellScripts\Remove-StaleGuests.ps1:271 char:32
+ ... ogonDate = (Get-AzureADAuditSignInLogs -Top 1 -Filter "userid eq '$g ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-AzureADAuditSignInLogs], ApiException
+ FullyQualifiedErrorId : Microsoft.Open.MSGraphBeta.Client.ApiException,Microsoft.Open.MSGraphBeta.PowerShell.Get
AuditSignInLogs
.PARAMETER InactiveTimeSpan
The InactiveTimeSpan parameter defines the number of days that a guest user has not logged
using the guest account. Please be aware that the signin data .
What would we need to be aware of?
In the documentation part:
.PARAMETER ForceRemoval
The ForceRemoval parameter allows the removable of guests with default logon information
older than Apr-2020 or for accounts that have not yet had a signin. The DateTime value
might be displayed as 01-01-0001. As exact logon details cannot be provided these accounts
are excluded from remove by default.
Does it refer to these type of users that come out in the exported report?
We want to make sure we are deleting the right guest users.
Terrific script and really well laid out comments within, having a small issue which perhaps is user error (I did read the Readme.md!).
When I run it in remote only mode (Remove-StaleGuests.ps1 -ExportCSVPath guest.csv) I don't see a column value showing last logon, and using excel to look at the RefreshToken field only runs dates until February this year (but AAD sign in logs will only have last 90 days, and.....
I see recent LastLogonDate events when running it in (remote-staleguests.ps1 -InactiveTimeSpan 90 -exportcasvpath blah.csv) but without the remove $true, it attempts (I haven't yet elevated to roles capable of making changes, just global/sec reader), it begins to write-host "SUCCESS: addding lastlogondate to CustomAttribue1". Which is great, of course it errors hugely because it can't write the attributes but I just did it as a test to see if I misunderstood your instructions.
I need to be able to provide initial stats on how many of our guests are stale, so we can plan the impact of deleting them. How can I run the script in report only mode, to obtain the LastLogon dates? Is this possible?
Great script JBines,
I found a small bug on line 304:
$Token = Get-MsalToken -clientID $clientID -ClientSecret (ConvertTo-SecureString $ClientSecret -AsPlainText -Force) -tenantID $tenantID
$clientID should be $AppId.
When using the Azure app registration, it will not allow a certificate upload with extension .pfx. But a certificate with the .cer extension doesn't have a private key, which in turn throws an error in powershell. I've run this script before, successfully, but I can't for the life of me figure out what could have been different. I've tried both the original certificate, and a new one. I created a self-signed cert with private key, but again, it can only be exported with the pfx extension.
Script works for us but is not pulling the last non-interactive sign on datew which is what we woudl use to determine if the user is not active, Please can you help me include this option ?
Any time I run the script, I get a "Too Many Requests" error from powershell (admin).
`Get-AzureADAuditSignInLogs : Error occurred while executing GetAuditSignInLogs
Code: UnknownError
Message: Too Many Requests
InnerError:
RequestId: 9740490d-95f4-44f0-910c-90fc06bc2347
DateTimeStamp: Tue, 08 Feb 2022 22:12:47 GMT
HttpStatusCode: 429
HttpStatusDescription:
HttpResponseStatus: Completed
At C:\scripts\Remove-StaleGuests.ps1:271 char:32
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hi,
thanks you for you job. But in environment with 2000 users I've got such as error:
Message: This request is throttled. Please try again after the value specified in the Retry-After header. CorrelationId: XXX
InnerError:
RequestId: YYY
DateTimeStamp: Thu, 6 May 2021 08:00:21 GMT
HttpStatusCode: 429
HttpStatusDescription: Completed
Error occurred while executing GetAuditSignInLogs
Code: UnknownError
and its over and over again. how can I handle with it, please?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.