List inactive Guest Users in Azure AD

# This script requires PowerShell 7 or later for the following reasons:
# 1. The Microsoft Graph PowerShell SDK (Microsoft.Graph module) is designed for PowerShell 7+ and may not work reliably in Windows PowerShell 5.1.
# 2. The SignInActivity property is not returned or accessible in PowerShell 5.1 due to .NET and serialization limitations.
# 3. Modern authentication methods used by Connect-MgGraph are only fully supported in PowerShell 7+.
# 4. Paging and the -All switch for Get-MgUser are more reliable in PowerShell 7+.
# 5. Microsoft is focusing new features and bug fixes for the Graph SDK on PowerShell 7+ only.
# Attempting to run this script in Windows PowerShell 5.1 or earlier will result in errors or missing data.

# Check for PowerShell 7+
if ($PSVersionTable.PSVersion.Major -lt 7) {
    Write-Host "ERROR: This script requires PowerShell 7 or later. Please run it in PowerShell 7+ (pwsh.exe)." -ForegroundColor Red
    exit 1
}

# Connect to Microsoft Graph with required scopes
Connect-MgGraph -Scopes "User.Read.All", "AuditLog.Read.All"

# Define log file path and organization domain
$logFile = "UserReport_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$orgDomain = "company.com"  # Replace with your organization's primary domain

# Calculate the date 6 months ago
$inactiveThreshold = (Get-Date).AddMonths(-6)

# Initialize log content
Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Starting Azure AD user report."

# Get all users with necessary properties
$allUsers = Get-MgUser -All -Property Id, DisplayName, SignInActivity, AccountEnabled, UserType, UserPrincipalName |
    Where-Object { $_.SignInActivity.LastSignInDateTime -and ([datetime]$_.SignInActivity.LastSignInDateTime) -lt $inactiveThreshold -and $_.AccountEnabled -eq $true }

# Categorize users
$guestUsers = @()
$memberUsers = @()

foreach ($user in $allUsers) {
    if ($user.UserType -eq 'Guest') {
        $guestUsers += $user
    } elseif ($user.UserType -eq 'Member') {
        $memberUsers += $user
    }
}

# Log Guest Users
Add-Content -Path $logFile -Value "`n$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Guest Users (Inactive for 6+ months):"
if ($guestUsers.Count -eq 0) {
    $message = "No inactive Guest users found."
    Write-Host $message
    Add-Content -Path $logFile -Value $message
} else {
    foreach ($user in $guestUsers) {
        $message = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Guest User: $($user.DisplayName) (ID: $($user.Id), UPN: $($user.UserPrincipalName), Last sign-in: $($user.SignInActivity.LastSignInDateTime))"
        Write-Host $message
        Add-Content -Path $logFile -Value $message
    }
}

# Log Member Users
Add-Content -Path $logFile -Value "`n$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Member Users (Inactive for 6+ months):"
if ($memberUsers.Count -eq 0) {
    $message = "No inactive Member users found."
    Write-Host $message
    Add-Content -Path $logFile -Value $message
} else {
    foreach ($user in $memberUsers) {
        $message = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Member User: $($user.DisplayName) (ID: $($user.Id), UPN: $($user.UserPrincipalName), Last sign-in: $($user.SignInActivity.LastSignInDateTime))"
        Write-Host $message
        Add-Content -Path $logFile -Value $message
    }
}

# Summary
$totalUsers = $guestUsers.Count + $memberUsers.Count
$summary = "`n$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - Summary: Total Inactive Users: $totalUsers (Guests: $($guestUsers.Count), Members: $($memberUsers.Count))"
Write-Host $summary
Add-Content -Path $logFile -Value $summary

# Disconnect from Microsoft Graph
Disconnect-MgGraph
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...