Azure Active Directory Monitoring Tool

# Expert Azure Active Directory Monitoring Tool

# Ensure the required modules are installed
# Install-Module -Name AzureAD, MSOnline, AzureADPreview -Force

# Import required modules
Import-Module AzureAD
Import-Module MSOnline
Import-Module AzureADPreview

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\AzureAD_Expert_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"

function Show-Menu {
    Clear-Host
    Write-Host "=== Expert Azure AD Monitoring Tool ===" -ForegroundColor Cyan
    Write-Host "1.  Tenant Overview"
    Write-Host "2.  User Account Analysis"
    Write-Host "3.  Group Management Audit"
    Write-Host "4.  Application Integration Assessment"
    Write-Host "5.  Conditional Access Policies Review"
    Write-Host "6.  Security Configuration Analysis"
    Write-Host "7.  Identity Protection Status"
    Write-Host "8.  Device Management Overview"
    Write-Host "9.  Privileged Identity Management Audit"
    Write-Host "10. Azure AD Connect Health Status"
    Write-Host "11. License Usage and Assignment"
    Write-Host "12. Generate Comprehensive HTML Report"
    Write-Host "13. Exit"
}

function Connect-AzureServices {
    try {
        Connect-AzureAD
        Connect-MsolService
        Write-Host "Successfully connected to Azure services." -ForegroundColor Green
    }
    catch {
        Write-Host "Failed to connect to Azure services. Please check your credentials and try again." -ForegroundColor Red
        Exit
    }
}

function Get-TenantOverview {
    Write-Host "`nRetrieving Tenant Overview..." -ForegroundColor Yellow
    $tenantInfo = Get-AzureADTenantDetail
    $domainInfo = Get-AzureADDomain
    $verifiedDomains = ($domainInfo | Where-Object { $_.IsVerified -eq $true }).Count
    $unverifiedDomains = ($domainInfo | Where-Object { $_.IsVerified -eq $false }).Count

    $overview = [PSCustomObject]@{
        TenantName = $tenantInfo.DisplayName
        TenantId = $tenantInfo.ObjectId
        VerifiedDomains = $verifiedDomains
        UnverifiedDomains = $unverifiedDomains
        TechnicalContacts = $tenantInfo.TechnicalNotificationMails -join ", "
    }

    $overview | Format-List
    return $overview
}

function Analyze-UserAccounts {
    Write-Host "`nAnalyzing User Accounts..." -ForegroundColor Yellow
    $users = Get-AzureADUser -All $true
    $guestUsers = $users | Where-Object { $_.UserType -eq 'Guest' }
    $mfaUsers = Get-MsolUser -All | Where-Object { $_.StrongAuthenticationRequirements.State -ne $null }

    $analysis = [PSCustomObject]@{
        TotalUsers = $users.Count
        EnabledUsers = ($users | Where-Object { $_.AccountEnabled -eq $true }).Count
        DisabledUsers = ($users | Where-Object { $_.AccountEnabled -eq $false }).Count
        GuestUsers = $guestUsers.Count
        MFAEnabledUsers = $mfaUsers.Count
        RecentlyCreatedUsers = ($users | Where-Object { $_.CreatedDateTime -gt (Get-Date).AddDays(-30) }).Count
    }

    $analysis | Format-List
    return $analysis
}

function Audit-GroupManagement {
    Write-Host "`nAuditing Group Management..." -ForegroundColor Yellow
    $groups = Get-AzureADGroup -All $true
    $dynamicGroups = $groups | Where-Object { $_.GroupTypes -contains "DynamicMembership" }

    $audit = [PSCustomObject]@{
        TotalGroups = $groups.Count
        SecurityGroups = ($groups | Where-Object { $_.SecurityEnabled -eq $true }).Count
        DistributionGroups = ($groups | Where-Object { $_.SecurityEnabled -eq $false }).Count
        DynamicGroups = $dynamicGroups.Count
        EmptyGroups = ($groups | Where-Object { (Get-AzureADGroupMember -ObjectId $_.ObjectId).Count -eq 0 }).Count
    }

    $audit | Format-List
    return $audit
}

function Assess-ApplicationIntegration {
    Write-Host "`nAssessing Application Integration..." -ForegroundColor Yellow
    $apps = Get-AzureADApplication -All $true
    $enterpriseApps = Get-AzureADServicePrincipal -All $true

    $assessment = [PSCustomObject]@{
        TotalApps = $apps.Count
        EnterpriseApps = $enterpriseApps.Count
        AppsWithSecrets = ($apps | Where-Object { $_.PasswordCredentials.Count -gt 0 -or $_.KeyCredentials.Count -gt 0 }).Count
        RecentlyAddedApps = ($apps | Where-Object { $_.CreatedDateTime -gt (Get-Date).AddDays(-30) }).Count
    }

    $assessment | Format-List
    return $assessment
}

function Review-ConditionalAccessPolicies {
    Write-Host "`nReviewing Conditional Access Policies..." -ForegroundColor Yellow
    $policies = Get-AzureADMSConditionalAccessPolicy

    $review = [PSCustomObject]@{
        TotalPolicies = $policies.Count
        EnabledPolicies = ($policies | Where-Object { $_.State -eq "enabled" }).Count
        DisabledPolicies = ($policies | Where-Object { $_.State -eq "disabled" }).Count
        ReportOnlyPolicies = ($policies | Where-Object { $_.State -eq "enabledForReportingButNotEnforced" }).Count
    }

    $review | Format-List
    return $review
}

function Analyze-SecurityConfiguration {
    Write-Host "`nAnalyzing Security Configuration..." -ForegroundColor Yellow
    $securityDefaults = (Get-MsolCompanyInformation).SecurityDefaultsEnabled
    $passwordPolicy = Get-MsolPasswordPolicy -TenantId (Get-MsolCompanyInformation).ObjectId

    $analysis = [PSCustomObject]@{
        SecurityDefaultsEnabled = $securityDefaults
        PasswordValidityPeriod = $passwordPolicy.ValidityPeriod
        MinimumPasswordLength = $passwordPolicy.MinimumPasswordLength
        PasswordComplexityEnabled = $passwordPolicy.StrongPasswordRequired
    }

    $analysis | Format-List
    return $analysis
}

function Get-IdentityProtectionStatus {
    Write-Host "`nRetrieving Identity Protection Status..." -ForegroundColor Yellow
    $riskDetections = Get-AzureADIdentityProtectionRiskDetection -Top 1000
    $riskyUsers = Get-AzureADIdentityProtectionRiskyUser -Top 1000

    $status = [PSCustomObject]@{
        TotalRiskDetections = $riskDetections.Count
        HighRiskDetections = ($riskDetections | Where-Object { $_.RiskLevel -eq "High" }).Count
        RiskyUsers = $riskyUsers.Count
        HighRiskUsers = ($riskyUsers | Where-Object { $_.RiskLevel -eq "High" }).Count
    }

    $status | Format-List
    return $status
}

function Get-DeviceManagementOverview {
    Write-Host "`nRetrieving Device Management Overview..." -ForegroundColor Yellow
    $devices = Get-AzureADDevice -All $true

    $overview = [PSCustomObject]@{
        TotalDevices = $devices.Count
        EnabledDevices = ($devices | Where-Object { $_.AccountEnabled -eq $true }).Count
        DisabledDevices = ($devices | Where-Object { $_.AccountEnabled -eq $false }).Count
        ManagedDevices = ($devices | Where-Object { $_.IsManaged -eq $true }).Count
        CompliantDevices = ($devices | Where-Object { $_.IsCompliant -eq $true }).Count
    }

    $overview | Format-List
    return $overview
}

function Audit-PrivilegedIdentityManagement {
    Write-Host "`nAuditing Privileged Identity Management..." -ForegroundColor Yellow
    $pimRoles = Get-AzureADMSPrivilegedRoleDefinition

    $audit = [PSCustomObject]@{
        TotalPIMRoles = $pimRoles.Count
        ActiveAssignments = (Get-AzureADMSPrivilegedRoleAssignment -ProviderId "aadRoles" -ResourceId (Get-AzureADTenantDetail).ObjectId | Where-Object { $_.AssignmentState -eq "Active" }).Count
        EligibleAssignments = (Get-AzureADMSPrivilegedRoleAssignment -ProviderId "aadRoles" -ResourceId (Get-AzureADTenantDetail).ObjectId | Where-Object { $_.AssignmentState -eq "Eligible" }).Count
    }

    $audit | Format-List
    return $audit
}

function Get-AzureADConnectHealthStatus {
    Write-Host "`nRetrieving Azure AD Connect Health Status..." -ForegroundColor Yellow
    $adConnectStatus = Get-MsolCompanyInformation | Select-Object -Property DirectorySynchronizationEnabled, DirectorySynchronizationStatus, LastDirSyncTime, LastPasswordSyncTime

    $status = [PSCustomObject]@{
        SyncEnabled = $adConnectStatus.DirectorySynchronizationEnabled
        SyncStatus = $adConnectStatus.DirectorySynchronizationStatus
        LastSyncTime = $adConnectStatus.LastDirSyncTime
        LastPasswordSyncTime = $adConnectStatus.LastPasswordSyncTime
    }

    $status | Format-List
    return $status
}

function Analyze-LicenseUsage {
    Write-Host "`nAnalyzing License Usage and Assignment..." -ForegroundColor Yellow
    $licenses = Get-MsolAccountSku

    $analysis = @()
    foreach ($license in $licenses) {
        $analysis += [PSCustomObject]@{
            SkuPartNumber = $license.SkuPartNumber
            TotalUnits = $license.ActiveUnits
            UsedUnits = $license.ConsumedUnits
            AvailableUnits = $license.ActiveUnits - $license.ConsumedUnits
        }
    }

    $analysis | Format-Table -AutoSize
    return $analysis
}

function Generate-HTMLReport {
    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Azure AD Expert Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }
        h1, h2 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>Azure AD Expert Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Tenant Overview</h2>
    $($overview | ConvertTo-Html -Fragment)

    <h2>User Account Analysis</h2>
    $($analysis | ConvertTo-Html -Fragment)

    <h2>Group Management Audit</h2>
    $($audit | ConvertTo-Html -Fragment)

    <h2>Application Integration Assessment</h2>
    $($assessment | ConvertTo-Html -Fragment)

    <h2>Conditional Access Policies Review</h2>
    $($review | ConvertTo-Html -Fragment)

    <h2>Security Configuration Analysis</h2>
    $($securityAnalysis | ConvertTo-Html -Fragment)

    <h2>Identity Protection Status</h2>
    $($identityProtectionStatus | ConvertTo-Html -Fragment)

    <h2>Device Management Overview</h2>
    $($deviceOverview | ConvertTo-Html -Fragment)

    <h2>Privileged Identity Management Audit</h2>
    $($pimAudit | ConvertTo-Html -Fragment)

    <h2>Azure AD Connect Health Status</h2>
    $($adConnectStatus | ConvertTo-Html -Fragment)

    <h2>License Usage and Assignment</h2>
    $($licenseAnalysis | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program
Connect-AzureServices

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-13)"

    switch ($choice) {
        "1"  { $overview = Get-TenantOverview }
        "2"  { $analysis = Analyze-UserAccounts }
        "3"  { $audit = Audit-GroupManagement }
        "4"  { $assessment = Assess-ApplicationIntegration }
        "5"  { $review = Review-ConditionalAccessPolicies }
        "6"  { $securityAnalysis = Analyze-SecurityConfiguration }
        "7"  { $identityProtectionStatus = Get-IdentityProtectionStatus }
        "8"  { $deviceOverview = Get-DeviceManagementOverview }
        "9"  { $pimAudit = Audit-PrivilegedIdentityManagement }
        "10" { $adConnectStatus = Get-AzureADConnectHealthStatus }
        "11" { $licenseAnalysis = Analyze-LicenseUsage }
        "12" { Generate-HTMLReport }
        "13" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "13") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "13")

This Azure AD Monitoring Tool includes:

  1. A comprehensive menu with 13 options
  2. Advanced functions for various Azure AD monitoring and analysis tasks:
    • Tenant overview
    • User account analysis
    • Group management audit
    • Application integration assessment
    • Conditional Access policies review
    • Security configuration analysis
    • Identity Protection status
    • Device management overview
    • Privileged Identity Management audit
    • Azure AD Connect health status
    • License usage and assignment analysis
  3. Use of multiple Azure AD PowerShell modules (AzureAD, MSOnline, AzureADPreview)
  4. Detailed output and reporting capabilities, including HTML report generation

Key features:

  • Comprehensive Tenant Overview: Provides key information about the Azure AD tenant
  • In-depth User Analysis: Analyzes user accounts, including guest users and MFA status
  • Group Management Audit: Examines group types and configurations
  • Application Integration Assessment: Reviews registered applications and service principals
  • Conditional Access Review: Summarizes Conditional Access policies
  • Security Configuration Analysis: Checks security defaults and password policies
  • Identity Protection Insights: Provides an overview of risk detections and risky users
  • Device Management Overview: Summarizes device registration and compliance status
  • PIM Audit: Reviews Privileged Identity Management roles and assignments
  • Azure AD Connect Health Check: Verifies directory synchronization status
  • License Analysis: Examines license allocation and usage

This tool provides a comprehensive analysis of an Azure AD environment. It’s particularly useful for:

  • Conducting regular Azure AD health checks
  • Preparing for security audits
  • Identifying potential security risks
  • Optimizing license usage
  • Generating detailed reports for management or compliance purposes

Note: To use this script effectively, you need to:

  1. Run PowerShell as an administrator
  2. Have the necessary Azure AD PowerShell modules installed
  3. Have appropriate permissions in the Azure AD environment (Global Administrator or similar high-level role)
  4. Be prepared to authenticate to Azure AD when prompted

This script is suitable for experienced Azure AD administrators who need comprehensive monitoring and analysis capabilities for managing complex Azure AD environments.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *