From fbc9665a1c6b2d2384d37181bf9a7332741b1fd7 Mon Sep 17 00:00:00 2001 From: Thomas De Reyck Date: Mon, 30 Sep 2024 15:51:57 +0200 Subject: [PATCH] Added stale user script. --- .../entra_id/list_stale_licensed_users.ps1 | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 microsoft/entra_id/list_stale_licensed_users.ps1 diff --git a/microsoft/entra_id/list_stale_licensed_users.ps1 b/microsoft/entra_id/list_stale_licensed_users.ps1 new file mode 100644 index 0000000..31def64 --- /dev/null +++ b/microsoft/entra_id/list_stale_licensed_users.ps1 @@ -0,0 +1,78 @@ +"Connecting to Graph API." +Connect-MgGraph -NoWelcome -Scopes "AuditLog.Read.All" + +"Connecting to Exchange On-line" +Connect-ExchangeOnline -ShowBanner:$false + +"Fetching list of SKUs." +# Note that SKU product names are documented at: +# https://learn.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference +$SKUs = Get-MgSubscribedSku + +"Fetching list of all users." +$Users = Get-MgUser -All -Property Id, UserPrincipalName, DisplayName, SignInActivity, UserType + +# Define an empty list for our results. +$StaleUsers = @() + +# Determine the cutoff date for users to be considered stale: +$CutoffDate = $(Get-Date).AddDays(-90) + +"Processing users." +ForEach($User in $Users) { + # If the user is a guest user, skip it. + If($User.UserType -like "Guest") { + Continue + } + + # If the user has signed in in the last 30 days, skip it. + If($User.SignInActivity.LastSignInDateTime) { + $LastSignInDateTime = [datetime]::parseexact($User.SignInActivity.LastSignInDateTime,'MM/dd/yyyy HH:mm:ss',$Null) + If($LastSignInDateTime -gt $CutoffDate) { + Continue + } + } Else { + $LastSignInDateTime = "Never" + } + + # Get the recipient type from Exchange, if a mailbox exists. + $OldPref = $global:ErrorActionPreference + try { + $global:ErrorActionPreference = 'Stop' + $Type = (Get-EXOMailbox -Identity $User.UserPrincipalName).RecipientTypeDetails + } catch { + $Type = "No Mailbox" + } + finally { + $global:ErrorActionPreference = $OldPref + } + + # Create a record to add to the results. + $UserRecord = [PSCustomObject]@{ + Id = $User.Id + UserPrincipalName = $User.UserPrincipalName + DisplayName = $User.DisplayName + LastSignInDateTime = $LastSignInDateTime + AnyLicenseAssigned = $False + Type = $Type + } + + ForEach($SKU in $SKUs) { + Add-Member -InputObject $UserRecord -MemberType NoteProperty -Name $SKU.SkuPartNumber -Value $False + } + + $LicenseDetails = Get-MgUserLicenseDetail -UserId $User.UserPrincipalName + + ForEach($LicenseDetail in $LicenseDetails) { + $UserRecord.$($LicenseDetail.SkuPartNumber) = $True + $UserRecord.AnyLicenseAssigned = $True + } + +$StaleUsers += ,$UserRecord + +} + +"Exporting results to CSV file." +$StaleUsers | Sort-Object LastSignInDateTime | Select UserPrincipalName, DisplayName, Type, LastSignInDateTime, AnyLicenseAssigned, SPE_E3, SPE_E5 | Export-Csv -Path "stale_licensed_users.csv" + +Disconnect-MgGraph