|
| 1 | +function Get-CIPPAlertInactiveGuestUsers { |
| 2 | + <# |
| 3 | + .FUNCTIONALITY |
| 4 | + Entrypoint |
| 5 | + #> |
| 6 | + [CmdletBinding()] |
| 7 | + param ( |
| 8 | + [Parameter(Mandatory = $false)] |
| 9 | + [Alias('input')] |
| 10 | + $InputValue, |
| 11 | + [Parameter(Mandatory = $false)] |
| 12 | + [switch]$IncludeNeverSignedIn, # Include users who have never signed in (default is to skip them), future use would allow this to be set in an alert configuration |
| 13 | + $TenantFilter |
| 14 | + ) |
| 15 | + |
| 16 | + try { |
| 17 | + try { |
| 18 | + $inactiveDays = 90 |
| 19 | + $excludeDisabled = $false |
| 20 | + |
| 21 | + $excludeDisabled = [bool]$InputValue.ExcludeDisabled |
| 22 | + if ($null -ne $InputValue.DaysSinceLastLogin -and $InputValue.DaysSinceLastLogin -ne '') { |
| 23 | + $parsedDays = 0 |
| 24 | + if ([int]::TryParse($InputValue.DaysSinceLastLogin.ToString(), [ref]$parsedDays) -and $parsedDays -gt 0) { |
| 25 | + $inactiveDays = $parsedDays |
| 26 | + } |
| 27 | + } |
| 28 | + |
| 29 | + |
| 30 | + |
| 31 | + $Lookup = (Get-Date).AddDays(-$inactiveDays).ToUniversalTime() |
| 32 | + Write-Host "Checking for guest users inactive since $Lookup (excluding disabled: $excludeDisabled)" |
| 33 | + # Build base filter - cannot filter assignedLicenses server-side |
| 34 | + $BaseFilter = if ($excludeDisabled) { 'accountEnabled eq true' } else { '' } |
| 35 | + |
| 36 | + $Uri = if ($BaseFilter) { |
| 37 | + "https://graph.microsoft.com/beta/users?`$filter=$BaseFilter&`$select=id,UserPrincipalName,signInActivity,mail,userType,accountEnabled,assignedLicenses" |
| 38 | + } else { |
| 39 | + "https://graph.microsoft.com/beta/users?`$select=id,UserPrincipalName,signInActivity,mail,userType,accountEnabled,assignedLicenses" |
| 40 | + } |
| 41 | + |
| 42 | + $GraphRequest = New-GraphGetRequest -uri $Uri-tenantid $TenantFilter | Where-Object { $_.userType -eq 'Guest' } |
| 43 | + |
| 44 | + $AlertData = foreach ($user in $GraphRequest) { |
| 45 | + $lastInteractive = $user.signInActivity.lastSignInDateTime |
| 46 | + $lastNonInteractive = $user.signInActivity.lastNonInteractiveSignInDateTime |
| 47 | + |
| 48 | + # Find most recent sign-in |
| 49 | + $lastSignIn = $null |
| 50 | + if ($lastInteractive -and $lastNonInteractive) { |
| 51 | + $lastSignIn = if ([DateTime]$lastInteractive -gt [DateTime]$lastNonInteractive) { $lastInteractive } else { $lastNonInteractive } |
| 52 | + } elseif ($lastInteractive) { |
| 53 | + $lastSignIn = $lastInteractive |
| 54 | + } elseif ($lastNonInteractive) { |
| 55 | + $lastSignIn = $lastNonInteractive |
| 56 | + } |
| 57 | + |
| 58 | + # Check if inactive |
| 59 | + $isInactive = (-not $lastSignIn) -or ([DateTime]$lastSignIn -le $Lookup) |
| 60 | + # Skip users who have never signed in by default (unless IncludeNeverSignedIn is specified) |
| 61 | + if (-not $IncludeNeverSignedIn -and -not $lastSignIn) { continue } |
| 62 | + # Only process inactive users |
| 63 | + if ($isInactive) { |
| 64 | + |
| 65 | + if (-not $lastSignIn) { |
| 66 | + $Message = 'Guest user {0} has never signed in.' -f $user.UserPrincipalName |
| 67 | + } else { |
| 68 | + $daysSinceSignIn = [Math]::Round(((Get-Date) - [DateTime]$lastSignIn).TotalDays) |
| 69 | + $Message = 'Guest user {0} has been inactive for {1} days. Last sign-in: {2}' -f $user.UserPrincipalName, $daysSinceSignIn, $lastSignIn |
| 70 | + } |
| 71 | + |
| 72 | + |
| 73 | + [PSCustomObject]@{ |
| 74 | + UserPrincipalName = $user.UserPrincipalName |
| 75 | + Id = $user.id |
| 76 | + lastSignIn = $lastSignIn |
| 77 | + DaysSinceLastSignIn = if ($daysSinceSignIn) { $daysSinceSignIn } else { 'N/A' } |
| 78 | + Message = $Message |
| 79 | + Tenant = $TenantFilter |
| 80 | + } |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData |
| 85 | + } catch {} |
| 86 | + } catch { |
| 87 | + Write-AlertMessage -tenant $($TenantFilter) -message "Failed to check inactive guest users for $($TenantFilter): $(Get-NormalizedError -message $_.Exception.message)" |
| 88 | + } |
| 89 | +} |
0 commit comments