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:
- A comprehensive menu with 13 options
- 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
- Use of multiple Azure AD PowerShell modules (AzureAD, MSOnline, AzureADPreview)
- 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:
- Run PowerShell as an administrator
- Have the necessary Azure AD PowerShell modules installed
- Have appropriate permissions in the Azure AD environment (Global Administrator or similar high-level role)
- 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.

Leave a Reply
Want to join the discussion?Feel free to contribute!