Tag Archive for: Program

DNS Analyzer Tool

<#
.SYNOPSIS
DNS Analyzer Tool

.DESCRIPTION
This script analyzes DNS configurations, zones, records, and potential issues across DNS servers in your network.

.NOTES
File Name      : DNSAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, DnsServer module, appropriate admin permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\DNSAnalyzer.ps1
#>

# Import required module
Import-Module DnsServer

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== DNS Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze DNS Server Configuration"
    Write-Host "2. Check DNS Zones"
    Write-Host "3. Analyze DNS Records"
    Write-Host "4. Check DNS Forwarders"
    Write-Host "5. Analyze DNS Performance"
    Write-Host "6. Check DNS Security Settings"
    Write-Host "7. Analyze DNS Client Settings on Domain Controllers"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Gets a list of DNS servers to analyze.

.OUTPUTS
Array of DNS server names.
#>
function Get-TargetDNSServers {
    $option = Read-Host "Analyze (A)ll domain DNS servers, (S)pecific servers, or (F)ile input? (A/S/F)"
    switch ($option.ToUpper()) {
        "A" {
            return (Get-DnsServerZone -ComputerName (Get-ADDomain).PDCEmulator | Select-Object -ExpandProperty ZoneNames | Get-DnsServerResourceRecord -RRType NS -ComputerName (Get-ADDomain).PDCEmulator | Select-Object -ExpandProperty RecordData | Select-Object -ExpandProperty NameServer)
        }
        "S" {
            $servers = @()
            do {
                $server = Read-Host "Enter DNS server name (or press Enter to finish)"
                if ($server -ne "") { $servers += $server }
            } while ($server -ne "")
            return $servers
        }
        "F" {
            $filePath = Read-Host "Enter the path to the file containing DNS server names"
            return (Get-Content $filePath)
        }
        default {
            Write-Host "Invalid option. Defaulting to all domain DNS servers." -ForegroundColor Yellow
            return (Get-DnsServerZone -ComputerName (Get-ADDomain).PDCEmulator | Select-Object -ExpandProperty ZoneNames | Get-DnsServerResourceRecord -RRType NS -ComputerName (Get-ADDomain).PDCEmulator | Select-Object -ExpandProperty RecordData | Select-Object -ExpandProperty NameServer)
        }
    }
}

<#
.SYNOPSIS
Analyzes DNS server configuration.

.PARAMETER Servers
Array of DNS server names to analyze.

.OUTPUTS
Array of PSObjects containing DNS server configuration details.
#>
function Analyze-DNSServerConfiguration {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing DNS Server Configuration..." -ForegroundColor Yellow
    $configResults = @()
    foreach ($server in $Servers) {
        try {
            $config = Get-DnsServerSetting -ComputerName $server -ErrorAction Stop
            $configResults += [PSCustomObject]@{
                Server = $server
                ListeningIPAddress = $config.ListeningIPAddress -join ", "
                EnableDnsSec = $config.EnableDnsSec
                BindSecondaries = $config.BindSecondaries
                RoundRobin = $config.RoundRobin
                LocalNetPriority = $config.LocalNetPriority
            }
        }
        catch {
            Write-Host "Error analyzing DNS configuration on $server : $_" -ForegroundColor Red
        }
    }
    $configResults | Format-Table -AutoSize
    return $configResults
}

<#
.SYNOPSIS
Checks DNS zones on target servers.

.PARAMETER Servers
Array of DNS server names to analyze.

.OUTPUTS
Array of PSObjects containing DNS zone details.
#>
function Check-DNSZones {
    param([string[]]$Servers)

    Write-Host "`nChecking DNS Zones..." -ForegroundColor Yellow
    $zoneResults = @()
    foreach ($server in $Servers) {
        try {
            $zones = Get-DnsServerZone -ComputerName $server -ErrorAction Stop
            foreach ($zone in $zones) {
                $zoneResults += [PSCustomObject]@{
                    Server = $server
                    ZoneName = $zone.ZoneName
                    ZoneType = $zone.ZoneType
                    IsDsIntegrated = $zone.IsDsIntegrated
                    IsReverseLookupZone = $zone.IsReverseLookupZone
                    RecordCount = $zone.ZoneStatistics.RecordCount
                }
            }
        }
        catch {
            Write-Host "Error checking DNS zones on $server : $_" -ForegroundColor Red
        }
    }
    $zoneResults | Format-Table -AutoSize
    return $zoneResults
}

<#
.SYNOPSIS
Analyzes DNS records in specific zones.

.PARAMETER Servers
Array of DNS server names to analyze.

.OUTPUTS
Array of PSObjects containing DNS record details.
#>
function Analyze-DNSRecords {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing DNS Records..." -ForegroundColor Yellow
    $recordResults = @()
    foreach ($server in $Servers) {
        try {
            $zones = Get-DnsServerZone -ComputerName $server -ErrorAction Stop
            foreach ($zone in $zones) {
                $records = Get-DnsServerResourceRecord -ZoneName $zone.ZoneName -ComputerName $server -ErrorAction Stop
                $recordResults += [PSCustomObject]@{
                    Server = $server
                    ZoneName = $zone.ZoneName
                    TotalRecords = $records.Count
                    ARecords = ($records | Where-Object {$_.RecordType -eq "A"}).Count
                    AAAARecords = ($records | Where-Object {$_.RecordType -eq "AAAA"}).Count
                    CNAMERecords = ($records | Where-Object {$_.RecordType -eq "CNAME"}).Count
                    MXRecords = ($records | Where-Object {$_.RecordType -eq "MX"}).Count
                }
            }
        }
        catch {
            Write-Host "Error analyzing DNS records on $server : $_" -ForegroundColor Red
        }
    }
    $recordResults | Format-Table -AutoSize
    return $recordResults
}

<#
.SYNOPSIS
Checks DNS forwarders on target servers.

.PARAMETER Servers
Array of DNS server names to analyze.

.OUTPUTS
Array of PSObjects containing DNS forwarder details.
#>
function Check-DNSForwarders {
    param([string[]]$Servers)

    Write-Host "`nChecking DNS Forwarders..." -ForegroundColor Yellow
    $forwarderResults = @()
    foreach ($server in $Servers) {
        try {
            $forwarders = Get-DnsServerForwarder -ComputerName $server -ErrorAction Stop
            $forwarderResults += [PSCustomObject]@{
                Server = $server
                ForwarderAddresses = $forwarders.IPAddress -join ", "
                UseRootHint = $forwarders.UseRootHint
                Timeout = $forwarders.Timeout
            }
        }
        catch {
            Write-Host "Error checking DNS forwarders on $server : $_" -ForegroundColor Red
        }
    }
    $forwarderResults | Format-Table -AutoSize
    return $forwarderResults
}

<#
.SYNOPSIS
Analyzes DNS performance on target servers.

.PARAMETER Servers
Array of DNS server names to analyze.

.OUTPUTS
Array of PSObjects containing DNS performance details.
#>
function Analyze-DNSPerformance {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing DNS Performance..." -ForegroundColor Yellow
    $performanceResults = @()
    foreach ($server in $Servers) {
        try {
            $counters = Get-Counter -ComputerName $server -Counter @(
                "\DNS\Total Query Received/sec",
                "\DNS\Total Response Sent/sec",
                "\DNS\Recursive Queries/sec"
            ) -ErrorAction Stop
            $performanceResults += [PSCustomObject]@{
                Server = $server
                QueriesReceived = $counters.CounterSamples[0].CookedValue
                ResponsesSent = $counters.CounterSamples[1].CookedValue
                RecursiveQueries = $counters.CounterSamples[2].CookedValue
            }
        }
        catch {
            Write-Host "Error analyzing DNS performance on $server : $_" -ForegroundColor Red
        }
    }
    $performanceResults | Format-Table -AutoSize
    return $performanceResults
}

<#
.SYNOPSIS
Checks DNS security settings on target servers.

.PARAMETER Servers
Array of DNS server names to analyze.

.OUTPUTS
Array of PSObjects containing DNS security setting details.
#>
function Check-DNSSecuritySettings {
    param([string[]]$Servers)

    Write-Host "`nChecking DNS Security Settings..." -ForegroundColor Yellow
    $securityResults = @()
    foreach ($server in $Servers) {
        try {
            $security = Get-DnsServerSetting -ComputerName $server -ErrorAction Stop
            $securityResults += [PSCustomObject]@{
                Server = $server
                EnableDnsSec = $security.EnableDnsSec
                NameCheckingLevel = $security.NameCheckingLevel
                UpdateOptions = $security.UpdateOptions
                SecureResponses = $security.SecureResponses
            }
        }
        catch {
            Write-Host "Error checking DNS security settings on $server : $_" -ForegroundColor Red
        }
    }
    $securityResults | Format-Table -AutoSize
    return $securityResults
}

<#
.SYNOPSIS
Analyzes DNS client settings on Domain Controllers.

.OUTPUTS
Array of PSObjects containing DNS client setting details for Domain Controllers.
#>
function Analyze-DNSClientSettingsOnDCs {
    Write-Host "`nAnalyzing DNS Client Settings on Domain Controllers..." -ForegroundColor Yellow
    $dcResults = @()
    $dcs = Get-ADDomainController -Filter *
    foreach ($dc in $dcs) {
        try {
            $nics = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $dc.HostName -Filter "IPEnabled='True'"
            foreach ($nic in $nics) {
                $dcResults += [PSCustomObject]@{
                    DomainController = $dc.HostName
                    InterfaceDescription = $nic.Description
                    DNSServers = $nic.DNSServerSearchOrder -join ", "
                    DNSSuffixSearchOrder = $nic.DNSDomainSuffixSearchOrder -join ", "
                }
            }
        }
        catch {
            Write-Host "Error analyzing DNS client settings on $($dc.HostName) : $_" -ForegroundColor Red
        }
    }
    $dcResults | Format-Table -AutoSize
    return $dcResults
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>DNS Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>DNS Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>DNS Server Configuration</h2>
    $($AllResults.ServerConfig | ConvertTo-Html -Fragment)

    <h2>DNS Zones</h2>
    $($AllResults.Zones | ConvertTo-Html -Fragment)

    <h2>DNS Records</h2>
    $($AllResults.Records | ConvertTo-Html -Fragment)

    <h2>DNS Forwarders</h2>
    $($AllResults.Forwarders | ConvertTo-Html -Fragment)

    <h2>DNS Performance</h2>
    $($AllResults.Performance | ConvertTo-Html -Fragment)

    <h2>DNS Security Settings</h2>
    $($AllResults.SecuritySettings | ConvertTo-Html -Fragment)

    <h2>DNS Client Settings on Domain Controllers</h2>
    $($AllResults.DCClientSettings | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$targetDNSServers = Get-TargetDNSServers
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.ServerConfig = Analyze-DNSServerConfiguration -Servers $targetDNSServers }
        "2" { $allResults.Zones = Check-DNSZones -Servers $targetDNSServers }
        "3" { $allResults.Records = Analyze-DNSRecords -Servers $targetDNSServers }
        "4" { $allResults.Forwarders = Check-DNSForwarders -Servers $targetDNSServers }
        "5" { $allResults.Performance = Analyze-DNSPerformance -Servers $targetDNSServers }
        "6" { $allResults.SecuritySettings = Check-DNSSecuritySettings -Servers $targetDNSServers }
        "7" { $allResults.DCClientSettings = Analyze-DNSClientSettingsOnDCs }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This DNS Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of DNS:
    • DNS Server Configuration analysis
    • DNS Zones check
    • DNS Records analysis
    • DNS Forwarders check
    • DNS Performance analysis
    • DNS Security Settings check
    • DNS Client Settings analysis on Domain Controllers
  3. Flexible DNS server selection (all domain DNS servers, specific servers, or from a file).
  4. Comprehensive error handling for each analysis function.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of DNS server configurations across multiple servers
  • Checking of DNS zones and record distributions
  • Review of DNS forwarder settings
  • Performance analysis using DNS-related counters
  • Security configuration checks
  • Analysis of DNS client settings on Domain Controllers
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • System administrators managing DNS servers
  • Network administrators troubleshooting DNS-related issues
  • Security professionals auditing DNS configurations
  • IT professionals performing DNS health checks

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query the target DNS servers
  3. Have the required PowerShell modules available (DnsServer and ActiveDirectory)

This script provides a comprehensive overview of DNS configurations and potential issues across multiple DNS servers in your network. It can significantly streamline the process of auditing and maintaining DNS services, enhancing both performance and security aspects of your DNS infrastructure.

Firewall Analyzer Tool

<#
.SYNOPSIS
Firewall Analyzer Tool

.DESCRIPTION
This script analyzes Windows Firewall configurations, rules, and potential issues across servers in your network.

.NOTES
File Name      : FirewallAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, appropriate admin permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\FirewallAnalyzer.ps1
#>

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Firewall Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze Firewall Profiles"
    Write-Host "2. Check Firewall Rules"
    Write-Host "3. Analyze Inbound Rules"
    Write-Host "4. Analyze Outbound Rules"
    Write-Host "5. Check for Potentially Risky Rules"
    Write-Host "6. Analyze Firewall Logging Settings"
    Write-Host "7. Check Firewall Service Status"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Gets a list of servers to analyze.

.OUTPUTS
Array of server names.
#>
function Get-TargetServers {
    $option = Read-Host "Analyze (A)ll domain servers, (S)pecific servers, or (F)ile input? (A/S/F)"
    switch ($option.ToUpper()) {
        "A" {
            return (Get-ADComputer -Filter {OperatingSystem -like "*Server*"} | Select-Object -ExpandProperty Name)
        }
        "S" {
            $servers = @()
            do {
                $server = Read-Host "Enter server name (or press Enter to finish)"
                if ($server -ne "") { $servers += $server }
            } while ($server -ne "")
            return $servers
        }
        "F" {
            $filePath = Read-Host "Enter the path to the file containing server names"
            return (Get-Content $filePath)
        }
        default {
            Write-Host "Invalid option. Defaulting to all domain servers." -ForegroundColor Yellow
            return (Get-ADComputer -Filter {OperatingSystem -like "*Server*"} | Select-Object -ExpandProperty Name)
        }
    }
}

<#
.SYNOPSIS
Analyzes firewall profiles on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing firewall profile details.
#>
function Analyze-FirewallProfiles {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing Firewall Profiles..." -ForegroundColor Yellow
    $profileResults = @()
    foreach ($server in $Servers) {
        try {
            $profiles = Get-NetFirewallProfile -CimSession $server -ErrorAction Stop
            foreach ($profile in $profiles) {
                $profileResults += [PSCustomObject]@{
                    Server = $server
                    ProfileName = $profile.Name
                    Enabled = $profile.Enabled
                    DefaultInboundAction = $profile.DefaultInboundAction
                    DefaultOutboundAction = $profile.DefaultOutboundAction
                    AllowInboundRules = $profile.AllowInboundRules
                    AllowLocalFirewallRules = $profile.AllowLocalFirewallRules
                }
            }
        }
        catch {
            Write-Host "Error analyzing firewall profiles on $server : $_" -ForegroundColor Red
        }
    }
    $profileResults | Format-Table -AutoSize
    return $profileResults
}

<#
.SYNOPSIS
Checks firewall rules on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing firewall rule details.
#>
function Check-FirewallRules {
    param([string[]]$Servers)

    Write-Host "`nChecking Firewall Rules..." -ForegroundColor Yellow
    $ruleResults = @()
    foreach ($server in $Servers) {
        try {
            $rules = Get-NetFirewallRule -CimSession $server -ErrorAction Stop
            $ruleResults += [PSCustomObject]@{
                Server = $server
                TotalRules = $rules.Count
                EnabledRules = ($rules | Where-Object { $_.Enabled -eq $true }).Count
                DisabledRules = ($rules | Where-Object { $_.Enabled -eq $false }).Count
                InboundRules = ($rules | Where-Object { $_.Direction -eq "Inbound" }).Count
                OutboundRules = ($rules | Where-Object { $_.Direction -eq "Outbound" }).Count
            }
        }
        catch {
            Write-Host "Error checking firewall rules on $server : $_" -ForegroundColor Red
        }
    }
    $ruleResults | Format-Table -AutoSize
    return $ruleResults
}

<#
.SYNOPSIS
Analyzes inbound firewall rules on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing inbound rule details.
#>
function Analyze-InboundRules {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing Inbound Rules..." -ForegroundColor Yellow
    $inboundResults = @()
    foreach ($server in $Servers) {
        try {
            $inboundRules = Get-NetFirewallRule -CimSession $server -Direction Inbound -Enabled True -ErrorAction Stop
            foreach ($rule in $inboundRules) {
                $ports = (Get-NetFirewallPortFilter -AssociatedNetFirewallRule $rule).LocalPort -join ", "
                $inboundResults += [PSCustomObject]@{
                    Server = $server
                    RuleName = $rule.DisplayName
                    Action = $rule.Action
                    Protocol = (Get-NetFirewallPortFilter -AssociatedNetFirewallRule $rule).Protocol
                    LocalPort = if ($ports) { $ports } else { "Any" }
                    RemoteAddress = (Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $rule).RemoteAddress -join ", "
                }
            }
        }
        catch {
            Write-Host "Error analyzing inbound rules on $server : $_" -ForegroundColor Red
        }
    }
    $inboundResults | Format-Table -AutoSize
    return $inboundResults
}

<#
.SYNOPSIS
Analyzes outbound firewall rules on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing outbound rule details.
#>
function Analyze-OutboundRules {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing Outbound Rules..." -ForegroundColor Yellow
    $outboundResults = @()
    foreach ($server in $Servers) {
        try {
            $outboundRules = Get-NetFirewallRule -CimSession $server -Direction Outbound -Enabled True -ErrorAction Stop
            foreach ($rule in $outboundRules) {
                $ports = (Get-NetFirewallPortFilter -AssociatedNetFirewallRule $rule).RemotePort -join ", "
                $outboundResults += [PSCustomObject]@{
                    Server = $server
                    RuleName = $rule.DisplayName
                    Action = $rule.Action
                    Protocol = (Get-NetFirewallPortFilter -AssociatedNetFirewallRule $rule).Protocol
                    RemotePort = if ($ports) { $ports } else { "Any" }
                    RemoteAddress = (Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $rule).RemoteAddress -join ", "
                }
            }
        }
        catch {
            Write-Host "Error analyzing outbound rules on $server : $_" -ForegroundColor Red
        }
    }
    $outboundResults | Format-Table -AutoSize
    return $outboundResults
}

<#
.SYNOPSIS
Checks for potentially risky firewall rules on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing potentially risky rule details.
#>
function Check-PotentiallyRiskyRules {
    param([string[]]$Servers)

    Write-Host "`nChecking for Potentially Risky Rules..." -ForegroundColor Yellow
    $riskyResults = @()
    foreach ($server in $Servers) {
        try {
            $rules = Get-NetFirewallRule -CimSession $server -Enabled True -ErrorAction Stop
            foreach ($rule in $rules) {
                $isRisky = $false
                $riskReason = @()

                if ($rule.Action -eq "Allow" -and $rule.Direction -eq "Inbound") {
                    $remoteAddress = (Get-NetFirewallAddressFilter -AssociatedNetFirewallRule $rule).RemoteAddress
                    if ($remoteAddress -contains "Any") {
                        $isRisky = $true
                        $riskReason += "Allows inbound from any address"
                    }

                    $localPort = (Get-NetFirewallPortFilter -AssociatedNetFirewallRule $rule).LocalPort
                    if ($localPort -contains "Any") {
                        $isRisky = $true
                        $riskReason += "Allows inbound on any port"
                    }
                }

                if ($isRisky) {
                    $riskyResults += [PSCustomObject]@{
                        Server = $server
                        RuleName = $rule.DisplayName
                        Direction = $rule.Direction
                        Action = $rule.Action
                        RiskReason = $riskReason -join ", "
                    }
                }
            }
        }
        catch {
            Write-Host "Error checking for risky rules on $server : $_" -ForegroundColor Red
        }
    }
    $riskyResults | Format-Table -AutoSize
    return $riskyResults
}

<#
.SYNOPSIS
Analyzes firewall logging settings on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing firewall logging setting details.
#>
function Analyze-FirewallLoggingSettings {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing Firewall Logging Settings..." -ForegroundColor Yellow
    $loggingResults = @()
    foreach ($server in $Servers) {
        try {
            $profiles = Get-NetFirewallProfile -CimSession $server -ErrorAction Stop
            foreach ($profile in $profiles) {
                $loggingResults += [PSCustomObject]@{
                    Server = $server
                    ProfileName = $profile.Name
                    LogAllowed = $profile.LogAllowed
                    LogBlocked = $profile.LogBlocked
                    LogIgnored = $profile.LogIgnored
                    LogFileName = $profile.LogFileName
                    LogMaxSizeKilobytes = $profile.LogMaxSizeKilobytes
                }
            }
        }
        catch {
            Write-Host "Error analyzing firewall logging settings on $server : $_" -ForegroundColor Red
        }
    }
    $loggingResults | Format-Table -AutoSize
    return $loggingResults
}

<#
.SYNOPSIS
Checks firewall service status on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing firewall service status details.
#>
function Check-FirewallServiceStatus {
    param([string[]]$Servers)

    Write-Host "`nChecking Firewall Service Status..." -ForegroundColor Yellow
    $serviceResults = @()
    foreach ($server in $Servers) {
        try {
            $service = Get-Service -ComputerName $server -Name MpsSvc -ErrorAction Stop
            $serviceResults += [PSCustomObject]@{
                Server = $server
                Status = $service.Status
                StartType = $service.StartType
            }
        }
        catch {
            Write-Host "Error checking firewall service status on $server : $_" -ForegroundColor Red
        }
    }
    $serviceResults | Format-Table -AutoSize
    return $serviceResults
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>Firewall Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>Firewall Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Firewall Profiles</h2>
    $($AllResults.FirewallProfiles | ConvertTo-Html -Fragment)

    <h2>Firewall Rules Summary</h2>
    $($AllResults.FirewallRules | ConvertTo-Html -Fragment)

    <h2>Inbound Rules</h2>
    $($AllResults.InboundRules | ConvertTo-Html -Fragment)

    <h2>Outbound Rules</h2>
    $($AllResults.OutboundRules | ConvertTo-Html -Fragment)

    <h2>Potentially Risky Rules</h2>
    $($AllResults.RiskyRules | ConvertTo-Html -Fragment)

    <h2>Firewall Logging Settings</h2>
    $($AllResults.LoggingSettings | ConvertTo-Html -Fragment)

    <h2>Firewall Service Status</h2>
    $($AllResults.ServiceStatus | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$targetServers = Get-TargetServers
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.FirewallProfiles = Analyze-FirewallProfiles -Servers $targetServers }
        "2" { $allResults.FirewallRules = Check-FirewallRules -Servers $targetServers }
        "3" { $allResults.InboundRules = Analyze-InboundRules -Servers $targetServers }
        "4" { $allResults.OutboundRules = Analyze-OutboundRules -Servers $targetServers }
        "5" { $allResults.RiskyRules = Check-PotentiallyRiskyRules -Servers $targetServers }
        "6" { $allResults.LoggingSettings = Analyze-FirewallLoggingSettings -Servers $targetServers }
        "7" { $allResults.ServiceStatus = Check-FirewallServiceStatus -Servers $targetServers }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Firewall Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of Windows Firewall:
    • Firewall Profile analysis
    • Firewall Rules summary
    • Inbound Rules analysis
    • Outbound Rules analysis
    • Potentially Risky Rules check
    • Firewall Logging Settings analysis
    • Firewall Service Status check
  3. Flexible server selection (all domain servers, specific servers, or from a file).
  4. Comprehensive error handling for each analysis function.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of firewall profiles across multiple servers
  • Comprehensive overview of firewall rules, including inbound and outbound rules
  • Identification of potentially risky firewall rules
  • Analysis of firewall logging settings
  • Verification of firewall service status
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Network administrators managing Windows servers
  • Security professionals auditing firewall configurations
  • IT professionals performing security assessments
  • System administrators troubleshooting network connectivity issues

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query the target servers
  3. Have the required PowerShell modules available (like ActiveDirectory if querying domain servers)

This script provides a comprehensive overview of Windows Firewall configurations and potential security issues across multiple servers in your network. It can significantly streamline the process of auditing and maintaining firewall configurations, enhancing the overall security posture of your Windows server environment.

SMB Analyzer Tool

<#
.SYNOPSIS
SMB Analyzer Tool

.DESCRIPTION
This script analyzes SMB configurations, shares, and potential issues across servers in your network.

.NOTES
File Name      : SMBAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, appropriate admin permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\SMBAnalyzer.ps1
#>

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== SMB Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze SMB Shares"
    Write-Host "2. Check SMB Protocol Versions"
    Write-Host "3. Analyze SMB Security Settings"
    Write-Host "4. Check SMB Performance Counters"
    Write-Host "5. Analyze SMB Encryption Status"
    Write-Host "6. Check SMB Signing Configuration"
    Write-Host "7. Analyze SMB Client Connections"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Gets a list of servers to analyze.

.OUTPUTS
Array of server names.
#>
function Get-TargetServers {
    $option = Read-Host "Analyze (A)ll domain servers, (S)pecific servers, or (F)ile input? (A/S/F)"
    switch ($option.ToUpper()) {
        "A" {
            return (Get-ADComputer -Filter {OperatingSystem -like "*Server*"} | Select-Object -ExpandProperty Name)
        }
        "S" {
            $servers = @()
            do {
                $server = Read-Host "Enter server name (or press Enter to finish)"
                if ($server -ne "") { $servers += $server }
            } while ($server -ne "")
            return $servers
        }
        "F" {
            $filePath = Read-Host "Enter the path to the file containing server names"
            return (Get-Content $filePath)
        }
        default {
            Write-Host "Invalid option. Defaulting to all domain servers." -ForegroundColor Yellow
            return (Get-ADComputer -Filter {OperatingSystem -like "*Server*"} | Select-Object -ExpandProperty Name)
        }
    }
}

<#
.SYNOPSIS
Analyzes SMB shares on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing SMB share details.
#>
function Analyze-SMBShares {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing SMB Shares..." -ForegroundColor Yellow
    $shareResults = @()
    foreach ($server in $Servers) {
        try {
            $shares = Get-SmbShare -CimSession $server -ErrorAction Stop
            foreach ($share in $shares) {
                $shareResults += [PSCustomObject]@{
                    Server = $server
                    ShareName = $share.Name
                    Path = $share.Path
                    Description = $share.Description
                    AccessBasedEnumerationEnabled = $share.FolderEnumerationMode
                }
            }
        }
        catch {
            Write-Host "Error analyzing shares on $server : $_" -ForegroundColor Red
        }
    }
    $shareResults | Format-Table -AutoSize
    return $shareResults
}

<#
.SYNOPSIS
Checks SMB protocol versions on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing SMB protocol version details.
#>
function Check-SMBProtocolVersions {
    param([string[]]$Servers)

    Write-Host "`nChecking SMB Protocol Versions..." -ForegroundColor Yellow
    $protocolResults = @()
    foreach ($server in $Servers) {
        try {
            $smbServer = Get-SmbServerConfiguration -CimSession $server -ErrorAction Stop
            $protocolResults += [PSCustomObject]@{
                Server = $server
                EnableSMB1Protocol = $smbServer.EnableSMB1Protocol
                EnableSMB2Protocol = $smbServer.EnableSMB2Protocol
            }
        }
        catch {
            Write-Host "Error checking SMB protocol versions on $server : $_" -ForegroundColor Red
        }
    }
    $protocolResults | Format-Table -AutoSize
    return $protocolResults
}

<#
.SYNOPSIS
Analyzes SMB security settings on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing SMB security setting details.
#>
function Analyze-SMBSecuritySettings {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing SMB Security Settings..." -ForegroundColor Yellow
    $securityResults = @()
    foreach ($server in $Servers) {
        try {
            $smbServer = Get-SmbServerConfiguration -CimSession $server -ErrorAction Stop
            $securityResults += [PSCustomObject]@{
                Server = $server
                RequireSecuritySignature = $smbServer.RequireSecuritySignature
                EncryptData = $smbServer.EncryptData
                EnableAuthenticateUserSharing = $smbServer.EnableAuthenticateUserSharing
                EnableSecuritySignature = $smbServer.EnableSecuritySignature
            }
        }
        catch {
            Write-Host "Error analyzing SMB security settings on $server : $_" -ForegroundColor Red
        }
    }
    $securityResults | Format-Table -AutoSize
    return $securityResults
}

<#
.SYNOPSIS
Checks SMB performance counters on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing SMB performance counter details.
#>
function Check-SMBPerformanceCounters {
    param([string[]]$Servers)

    Write-Host "`nChecking SMB Performance Counters..." -ForegroundColor Yellow
    $performanceResults = @()
    foreach ($server in $Servers) {
        try {
            $counters = Get-Counter -ComputerName $server -Counter @(
                "\SMB Server\Data Bytes/sec",
                "\SMB Server\Read Bytes/sec",
                "\SMB Server\Write Bytes/sec"
            ) -ErrorAction Stop
            $performanceResults += [PSCustomObject]@{
                Server = $server
                DataBytesPerSec = $counters.CounterSamples[0].CookedValue
                ReadBytesPerSec = $counters.CounterSamples[1].CookedValue
                WriteBytesPerSec = $counters.CounterSamples[2].CookedValue
            }
        }
        catch {
            Write-Host "Error checking SMB performance counters on $server : $_" -ForegroundColor Red
        }
    }
    $performanceResults | Format-Table -AutoSize
    return $performanceResults
}

<#
.SYNOPSIS
Analyzes SMB encryption status on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing SMB encryption status details.
#>
function Analyze-SMBEncryptionStatus {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing SMB Encryption Status..." -ForegroundColor Yellow
    $encryptionResults = @()
    foreach ($server in $Servers) {
        try {
            $smbServer = Get-SmbServerConfiguration -CimSession $server -ErrorAction Stop
            $encryptionResults += [PSCustomObject]@{
                Server = $server
                EncryptData = $smbServer.EncryptData
                RejectUnencryptedAccess = $smbServer.RejectUnencryptedAccess
            }
        }
        catch {
            Write-Host "Error analyzing SMB encryption status on $server : $_" -ForegroundColor Red
        }
    }
    $encryptionResults | Format-Table -AutoSize
    return $encryptionResults
}

<#
.SYNOPSIS
Checks SMB signing configuration on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing SMB signing configuration details.
#>
function Check-SMBSigningConfiguration {
    param([string[]]$Servers)

    Write-Host "`nChecking SMB Signing Configuration..." -ForegroundColor Yellow
    $signingResults = @()
    foreach ($server in $Servers) {
        try {
            $smbServer = Get-SmbServerConfiguration -CimSession $server -ErrorAction Stop
            $signingResults += [PSCustomObject]@{
                Server = $server
                RequireSecuritySignature = $smbServer.RequireSecuritySignature
                EnableSecuritySignature = $smbServer.EnableSecuritySignature
            }
        }
        catch {
            Write-Host "Error checking SMB signing configuration on $server : $_" -ForegroundColor Red
        }
    }
    $signingResults | Format-Table -AutoSize
    return $signingResults
}

<#
.SYNOPSIS
Analyzes SMB client connections on target servers.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing SMB client connection details.
#>
function Analyze-SMBClientConnections {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing SMB Client Connections..." -ForegroundColor Yellow
    $connectionResults = @()
    foreach ($server in $Servers) {
        try {
            $connections = Get-SmbConnection -CimSession $server -ErrorAction Stop
            foreach ($connection in $connections) {
                $connectionResults += [PSCustomObject]@{
                    Server = $server
                    ClientComputerName = $connection.ClientComputerName
                    ShareName = $connection.ShareName
                    Dialect = $connection.Dialect
                    NumOpens = $connection.NumOpens
                }
            }
        }
        catch {
            Write-Host "Error analyzing SMB client connections on $server : $_" -ForegroundColor Red
        }
    }
    $connectionResults | Format-Table -AutoSize
    return $connectionResults
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>SMB Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>SMB Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>SMB Shares</h2>
    $($AllResults.SMBShares | ConvertTo-Html -Fragment)

    <h2>SMB Protocol Versions</h2>
    $($AllResults.ProtocolVersions | ConvertTo-Html -Fragment)

    <h2>SMB Security Settings</h2>
    $($AllResults.SecuritySettings | ConvertTo-Html -Fragment)

    <h2>SMB Performance Counters</h2>
    $($AllResults.PerformanceCounters | ConvertTo-Html -Fragment)

    <h2>SMB Encryption Status</h2>
    $($AllResults.EncryptionStatus | ConvertTo-Html -Fragment)

    <h2>SMB Signing Configuration</h2>
    $($AllResults.SigningConfiguration | ConvertTo-Html -Fragment)

    <h2>SMB Client Connections</h2>
    $($AllResults.ClientConnections | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$targetServers = Get-TargetServers
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.SMBShares = Analyze-SMBShares -Servers $targetServers }
        "2" { $allResults.ProtocolVersions = Check-SMBProtocolVersions -Servers $targetServers }
        "3" { $allResults.SecuritySettings = Analyze-SMBSecuritySettings -Servers $targetServers }
        "4" { $allResults.PerformanceCounters = Check-SMBPerformanceCounters -Servers $targetServers }
        "5" { $allResults.EncryptionStatus = Analyze-SMBEncryptionStatus -Servers $targetServers }
        "6" { $allResults.SigningConfiguration = Check-SMBSigningConfiguration -Servers $targetServers }
        "7" { $allResults.ClientConnections = Analyze-SMBClientConnections -Servers $targetServers }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This SMB Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of SMB:
    • SMB Shares analysis
    • SMB Protocol Versions check
    • SMB Security Settings analysis
    • SMB Performance Counters check
    • SMB Encryption Status analysis
    • SMB Signing Configuration check
    • SMB Client Connections analysis
  3. Flexible server selection (all domain servers, specific servers, or from a file).
  4. Comprehensive error handling for each analysis function.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of SMB shares across multiple servers
  • Checking of SMB protocol versions in use
  • Review of SMB security settings and configurations
  • Performance analysis using SMB-related counters
  • Encryption and signing configuration checks
  • Analysis of current SMB client connections
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • System administrators managing file servers
  • Network administrators troubleshooting SMB-related issues
  • Security professionals auditing SMB configurations
  • IT professionals performing server health checks

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query the target servers
  3. Have the required PowerShell modules available (like ActiveDirectory if querying domain servers)

This script provides a comprehensive overview of SMB configurations and potential issues across multiple servers in your network. It can significantly streamline the process of auditing and maintaining SMB services, enhancing both performance and security aspects of file sharing in your environment.

FSMO Analyzer Tool

<#
.SYNOPSIS
FSMO Analyzer Tool

.DESCRIPTION
This script analyzes FSMO roles in an Active Directory environment, providing detailed information
about role holders, health status, and potential issues.

.NOTES
File Name      : FSMOAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Active Directory module, and appropriate AD permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\FSMOAnalyzer.ps1
#>

# Import required modules
Import-Module ActiveDirectory

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== FSMO Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Identify FSMO Role Holders"
    Write-Host "2. Check FSMO Role Health"
    Write-Host "3. Analyze FSMO Role Transfer History"
    Write-Host "4. Verify FSMO Role Connectivity"
    Write-Host "5. Check for Orphaned FSMO Roles"
    Write-Host "6. Analyze FSMO Role Performance"
    Write-Host "7. Generate Comprehensive HTML Report"
    Write-Host "8. Exit"
}

<#
.SYNOPSIS
Identifies current FSMO role holders.

.OUTPUTS
PSObject containing FSMO role holder information.
#>
function Identify-FSMORoleHolders {
    Write-Host "`nIdentifying FSMO Role Holders..." -ForegroundColor Yellow
    $forest = Get-ADForest
    $domain = Get-ADDomain

    $fsmoRoles = [PSCustomObject]@{
        SchemaMaster = $forest.SchemaMaster
        DomainNamingMaster = $forest.DomainNamingMaster
        PDCEmulator = $domain.PDCEmulator
        RIDMaster = $domain.RIDMaster
        InfrastructureMaster = $domain.InfrastructureMaster
    }

    $fsmoRoles | Format-List
    return $fsmoRoles
}

<#
.SYNOPSIS
Checks the health of FSMO roles.

.OUTPUTS
Array of PSObjects containing FSMO role health information.
#>
function Check-FSMORoleHealth {
    Write-Host "`nChecking FSMO Role Health..." -ForegroundColor Yellow
    $roles = Identify-FSMORoleHolders
    $healthResults = @()

    foreach ($role in $roles.PSObject.Properties) {
        $dcdiag = Invoke-Command -ComputerName $role.Value -ScriptBlock {
            dcdiag /test:KnowsOfRoleHolders /test:RegisterInDNS
        } -ErrorAction SilentlyContinue

        $healthResults += [PSCustomObject]@{
            Role = $role.Name
            Holder = $role.Value
            KnowsOfRoleHolders = if ($dcdiag -match "passed test KnowsOfRoleHolders") { "Passed" } else { "Failed" }
            RegisteredInDNS = if ($dcdiag -match "passed test RegisterInDNS") { "Passed" } else { "Failed" }
        }
    }

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

<#
.SYNOPSIS
Analyzes FSMO role transfer history.

.OUTPUTS
Array of PSObjects containing FSMO role transfer history.
#>
function Analyze-FSMORoleTransferHistory {
    Write-Host "`nAnalyzing FSMO Role Transfer History..." -ForegroundColor Yellow
    $domain = Get-ADDomain
    $forest = Get-ADForest
    $transferHistory = @()

    $events = Get-WinEvent -ComputerName $domain.PDCEmulator -FilterHashtable @{
        LogName = 'Directory Service'
        ID = 1190, 1647, 2162
    } -ErrorAction SilentlyContinue

    foreach ($event in $events) {
        $transferHistory += [PSCustomObject]@{
            TimeStamp = $event.TimeCreated
            EventID = $event.Id
            Message = $event.Message
        }
    }

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

<#
.SYNOPSIS
Verifies connectivity to FSMO role holders.

.OUTPUTS
Array of PSObjects containing FSMO role connectivity information.
#>
function Verify-FSMORoleConnectivity {
    Write-Host "`nVerifying FSMO Role Connectivity..." -ForegroundColor Yellow
    $roles = Identify-FSMORoleHolders
    $connectivityResults = @()

    foreach ($role in $roles.PSObject.Properties) {
        $pingResult = Test-Connection -ComputerName $role.Value -Count 1 -Quiet
        $portResult = Test-NetConnection -ComputerName $role.Value -Port 389 -WarningAction SilentlyContinue

        $connectivityResults += [PSCustomObject]@{
            Role = $role.Name
            Holder = $role.Value
            Pingable = $pingResult
            LDAPAccessible = $portResult.TcpTestSucceeded
        }
    }

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

<#
.SYNOPSIS
Checks for orphaned FSMO roles.

.OUTPUTS
Array of PSObjects containing orphaned FSMO role information.
#>
function Check-OrphanedFSMORoles {
    Write-Host "`nChecking for Orphaned FSMO Roles..." -ForegroundColor Yellow
    $roles = Identify-FSMORoleHolders
    $orphanedRoles = @()

    foreach ($role in $roles.PSObject.Properties) {
        $dcExists = Get-ADDomainController -Identity $role.Value -ErrorAction SilentlyContinue

        if (-not $dcExists) {
            $orphanedRoles += [PSCustomObject]@{
                Role = $role.Name
                Holder = $role.Value
                Status = "Orphaned"
            }
        }
    }

    if ($orphanedRoles.Count -eq 0) {
        Write-Host "No orphaned FSMO roles found." -ForegroundColor Green
    } else {
        $orphanedRoles | Format-Table -AutoSize
    }

    return $orphanedRoles
}

<#
.SYNOPSIS
Analyzes FSMO role performance.

.OUTPUTS
Array of PSObjects containing FSMO role performance information.
#>
function Analyze-FSMORolePerformance {
    Write-Host "`nAnalyzing FSMO Role Performance..." -ForegroundColor Yellow
    $roles = Identify-FSMORoleHolders
    $performanceResults = @()

    foreach ($role in $roles.PSObject.Properties) {
        $cpu = Get-WmiObject Win32_Processor -ComputerName $role.Value | Measure-Object -Property LoadPercentage -Average | Select-Object -ExpandProperty Average
        $memory = Get-WmiObject Win32_OperatingSystem -ComputerName $role.Value | Select-Object @{Name="MemoryUsage";Expression={"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize)}}
        $disk = Get-WmiObject Win32_LogicalDisk -ComputerName $role.Value -Filter "DeviceID='C:'" | Select-Object @{Name="FreeSpace";Expression={"{0:N2}" -f ($_.FreeSpace/1GB)}}

        $performanceResults += [PSCustomObject]@{
            Role = $role.Name
            Holder = $role.Value
            CPUUsage = "$cpu%"
            MemoryUsage = "$($memory.MemoryUsage)%"
            FreeDiskSpace = "$($disk.FreeSpace) GB"
        }
    }

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

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>FSMO Role Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>FSMO Role Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>FSMO Role Holders</h2>
    $($AllResults.RoleHolders | ConvertTo-Html -Fragment)

    <h2>FSMO Role Health</h2>
    $($AllResults.RoleHealth | ConvertTo-Html -Fragment)

    <h2>FSMO Role Transfer History</h2>
    $($AllResults.TransferHistory | ConvertTo-Html -Fragment)

    <h2>FSMO Role Connectivity</h2>
    $($AllResults.RoleConnectivity | ConvertTo-Html -Fragment)

    <h2>Orphaned FSMO Roles</h2>
    $($AllResults.OrphanedRoles | ConvertTo-Html -Fragment)

    <h2>FSMO Role Performance</h2>
    $($AllResults.RolePerformance | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.RoleHolders = Identify-FSMORoleHolders }
        "2" { $allResults.RoleHealth = Check-FSMORoleHealth }
        "3" { $allResults.TransferHistory = Analyze-FSMORoleTransferHistory }
        "4" { $allResults.RoleConnectivity = Verify-FSMORoleConnectivity }
        "5" { $allResults.OrphanedRoles = Check-OrphanedFSMORoles }
        "6" { $allResults.RolePerformance = Analyze-FSMORolePerformance }
        "7" { Generate-HTMLReport -AllResults $allResults }
        "8" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This FSMO Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of FSMO roles:
    • Identification of current FSMO role holders
    • Health check of FSMO roles
    • Analysis of FSMO role transfer history
    • Verification of connectivity to FSMO role holders
    • Check for orphaned FSMO roles
    • Performance analysis of FSMO role holders
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed identification of all FSMO role holders
  • Health check of FSMO roles using dcdiag
  • Analysis of recent FSMO role transfers
  • Connectivity tests to ensure FSMO role holders are accessible
  • Detection of orphaned FSMO roles
  • Performance metrics of servers holding FSMO roles
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Active Directory administrators
  • System administrators managing domain controllers
  • IT professionals troubleshooting AD issues related to FSMO roles
  • Security teams auditing AD infrastructure

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query domain controllers and FSMO role holders
  3. Have the Active Directory PowerShell module installed

This script provides a comprehensive overview of FSMO roles in an Active Directory environment, making it easier to identify issues, track changes, and ensure the health and performance of these critical roles. It can significantly streamline the process of maintaining and troubleshooting FSMO roles in organizations of any size.

Domain Controller Analyzer Tool

<#
.SYNOPSIS
Domain Controller Analyzer Tool

.DESCRIPTION
This script analyzes Domain Controllers in an Active Directory environment, providing detailed information
about DC health, replication status, performance metrics, and potential issues.

.NOTES
File Name      : DCAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Active Directory module, and appropriate AD permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\DCAnalyzer.ps1
#>

# Import required modules
Import-Module ActiveDirectory

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Domain Controller Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Perform DC Health Check"
    Write-Host "2. Analyze Replication Status"
    Write-Host "3. Check FSMO Roles"
    Write-Host "4. Analyze DC Performance Metrics"
    Write-Host "5. Check AD Services Status"
    Write-Host "6. Verify DNS Configuration"
    Write-Host "7. Analyze SYSVOL and NETLOGON Shares"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Performs a health check on all Domain Controllers.

.OUTPUTS
Array of PSObjects containing DC health check results.
#>
function Perform-DCHealthCheck {
    Write-Host "`nPerforming DC Health Check..." -ForegroundColor Yellow
    $dcs = Get-ADDomainController -Filter *
    $healthResults = @()
    foreach ($dc in $dcs) {
        $dcdiag = Invoke-Command -ComputerName $dc.HostName -ScriptBlock {
            dcdiag /test:services /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount /test:replications /test:netlogons /test:systemlog
        } -ErrorAction SilentlyContinue

        $healthResults += [PSCustomObject]@{
            DomainController = $dc.HostName
            Services = if ($dcdiag -match "passed test Services") { "Passed" } else { "Failed" }
            Advertising = if ($dcdiag -match "passed test Advertising") { "Passed" } else { "Failed" }
            FSMORoles = if ($dcdiag -match "passed test FsmoCheck") { "Passed" } else { "Failed" }
            RidManager = if ($dcdiag -match "passed test RidManager") { "Passed" } else { "Failed" }
            MachineAccount = if ($dcdiag -match "passed test MachineAccount") { "Passed" } else { "Failed" }
            Replications = if ($dcdiag -match "passed test Replications") { "Passed" } else { "Failed" }
            Netlogons = if ($dcdiag -match "passed test NetLogons") { "Passed" } else { "Failed" }
            SystemLog = if ($dcdiag -match "passed test SystemLog") { "Passed" } else { "Failed" }
        }
    }
    $healthResults | Format-Table -AutoSize
    return $healthResults
}

<#
.SYNOPSIS
Analyzes replication status between Domain Controllers.

.OUTPUTS
Array of PSObjects containing replication status details.
#>
function Analyze-ReplicationStatus {
    Write-Host "`nAnalyzing Replication Status..." -ForegroundColor Yellow
    $replicationStatus = @()
    $dcs = Get-ADDomainController -Filter *
    foreach ($dc in $dcs) {
        $replStatus = repadmin /showrepl $dc.HostName | Select-String "Last attempt" -Context 2,0
        foreach ($status in $replStatus) {
            $replicationStatus += [PSCustomObject]@{
                SourceDC = $dc.HostName
                DestinationDC = ($status.Context.PreContext[0] -split ":")[1].Trim()
                LastAttempt = ($status.Line -split "@")[1].Trim()
                Result = $status.Context.PostContext[0].Trim()
            }
        }
    }
    $replicationStatus | Format-Table -AutoSize
    return $replicationStatus
}

<#
.SYNOPSIS
Checks FSMO roles distribution.

.OUTPUTS
PSObject containing FSMO roles information.
#>
function Check-FSMORoles {
    Write-Host "`nChecking FSMO Roles..." -ForegroundColor Yellow
    $forest = Get-ADForest
    $domain = Get-ADDomain

    $fsmoRoles = [PSCustomObject]@{
        SchemaMaster = $forest.SchemaMaster
        DomainNamingMaster = $forest.DomainNamingMaster
        PDCEmulator = $domain.PDCEmulator
        RIDMaster = $domain.RIDMaster
        InfrastructureMaster = $domain.InfrastructureMaster
    }

    $fsmoRoles | Format-List
    return $fsmoRoles
}

<#
.SYNOPSIS
Analyzes performance metrics of Domain Controllers.

.OUTPUTS
Array of PSObjects containing DC performance metrics.
#>
function Analyze-DCPerformanceMetrics {
    Write-Host "`nAnalyzing DC Performance Metrics..." -ForegroundColor Yellow
    $dcs = Get-ADDomainController -Filter *
    $performanceMetrics = @()
    foreach ($dc in $dcs) {
        $cpu = Get-WmiObject Win32_Processor -ComputerName $dc.HostName | Measure-Object -Property LoadPercentage -Average | Select-Object -ExpandProperty Average
        $memory = Get-WmiObject Win32_OperatingSystem -ComputerName $dc.HostName | Select-Object @{Name="MemoryUsage";Expression={"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize)}}
        $disk = Get-WmiObject Win32_LogicalDisk -ComputerName $dc.HostName -Filter "DeviceID='C:'" | Select-Object @{Name="FreeSpace";Expression={"{0:N2}" -f ($_.FreeSpace/1GB)}}

        $performanceMetrics += [PSCustomObject]@{
            DomainController = $dc.HostName
            CPUUsage = "$cpu%"
            MemoryUsage = "$($memory.MemoryUsage)%"
            FreeDiskSpace = "$($disk.FreeSpace) GB"
        }
    }
    $performanceMetrics | Format-Table -AutoSize
    return $performanceMetrics
}

<#
.SYNOPSIS
Checks the status of critical AD services on Domain Controllers.

.OUTPUTS
Array of PSObjects containing AD services status.
#>
function Check-ADServicesStatus {
    Write-Host "`nChecking AD Services Status..." -ForegroundColor Yellow
    $dcs = Get-ADDomainController -Filter *
    $servicesStatus = @()
    $criticalServices = @("NTDS", "Netlogon", "DNS", "DFSR", "KDC")

    foreach ($dc in $dcs) {
        $services = Get-Service -ComputerName $dc.HostName -Name $criticalServices -ErrorAction SilentlyContinue
        $servicesStatus += [PSCustomObject]@{
            DomainController = $dc.HostName
            NTDS = ($services | Where-Object {$_.Name -eq "NTDS"}).Status
            Netlogon = ($services | Where-Object {$_.Name -eq "Netlogon"}).Status
            DNS = ($services | Where-Object {$_.Name -eq "DNS"}).Status
            DFSR = ($services | Where-Object {$_.Name -eq "DFSR"}).Status
            KDC = ($services | Where-Object {$_.Name -eq "KDC"}).Status
        }
    }
    $servicesStatus | Format-Table -AutoSize
    return $servicesStatus
}

<#
.SYNOPSIS
Verifies DNS configuration on Domain Controllers.

.OUTPUTS
Array of PSObjects containing DNS configuration details.
#>
function Verify-DNSConfiguration {
    Write-Host "`nVerifying DNS Configuration..." -ForegroundColor Yellow
    $dcs = Get-ADDomainController -Filter *
    $dnsConfig = @()
    foreach ($dc in $dcs) {
        $dnsServers = Get-DnsClientServerAddress -CimSession $dc.HostName -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -notlike "*Loopback*"}
        $dnsConfig += [PSCustomObject]@{
            DomainController = $dc.HostName
            DNSServers = ($dnsServers.ServerAddresses -join ", ")
            HasDNSRole = [bool](Get-WindowsFeature -ComputerName $dc.HostName -Name DNS).Installed
        }
    }
    $dnsConfig | Format-Table -AutoSize
    return $dnsConfig
}

<#
.SYNOPSIS
Analyzes SYSVOL and NETLOGON shares on Domain Controllers.

.OUTPUTS
Array of PSObjects containing SYSVOL and NETLOGON share details.
#>
function Analyze-SYSVOLandNETLOGON {
    Write-Host "`nAnalyzing SYSVOL and NETLOGON Shares..." -ForegroundColor Yellow
    $dcs = Get-ADDomainController -Filter *
    $shareAnalysis = @()
    foreach ($dc in $dcs) {
        $sysvol = Get-WmiObject -Class Win32_Share -ComputerName $dc.HostName -Filter "Name='SYSVOL'"
        $netlogon = Get-WmiObject -Class Win32_Share -ComputerName $dc.HostName -Filter "Name='NETLOGON'"
        $shareAnalysis += [PSCustomObject]@{
            DomainController = $dc.HostName
            SYSVOLPath = $sysvol.Path
            NETLOGONPath = $netlogon.Path
            SYSVOLAccessible = Test-Path "\\$($dc.HostName)\SYSVOL" -ErrorAction SilentlyContinue
            NETLOGONAccessible = Test-Path "\\$($dc.HostName)\NETLOGON" -ErrorAction SilentlyContinue
        }
    }
    $shareAnalysis | Format-Table -AutoSize
    return $shareAnalysis
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>Domain Controller Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>Domain Controller Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>DC Health Check</h2>
    $($AllResults.HealthCheck | ConvertTo-Html -Fragment)

    <h2>Replication Status</h2>
    $($AllResults.ReplicationStatus | ConvertTo-Html -Fragment)

    <h2>FSMO Roles</h2>
    $($AllResults.FSMORoles | ConvertTo-Html -Fragment)

    <h2>DC Performance Metrics</h2>
    $($AllResults.PerformanceMetrics | ConvertTo-Html -Fragment)

    <h2>AD Services Status</h2>
    $($AllResults.ServicesStatus | ConvertTo-Html -Fragment)

    <h2>DNS Configuration</h2>
    $($AllResults.DNSConfig | ConvertTo-Html -Fragment)

    <h2>SYSVOL and NETLOGON Analysis</h2>
    $($AllResults.ShareAnalysis | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.HealthCheck = Perform-DCHealthCheck }
        "2" { $allResults.ReplicationStatus = Analyze-ReplicationStatus }
        "3" { $allResults.FSMORoles = Check-FSMORoles }
        "4" { $allResults.PerformanceMetrics = Analyze-DCPerformanceMetrics }
        "5" { $allResults.ServicesStatus = Check-ADServicesStatus }
        "6" { $allResults.DNSConfig = Verify-DNSConfiguration }
        "7" { $allResults.ShareAnalysis = Analyze-SYSVOLandNETLOGON }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Domain Controller Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of Domain Controllers:
    • DC Health Check using dcdiag
    • Replication Status analysis
    • FSMO Roles check
    • Performance Metrics analysis
    • AD Services Status check
    • DNS Configuration verification
    • SYSVOL and NETLOGON share analysis
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed health check of all Domain Controllers
  • Analysis of replication status between DCs
  • Verification of FSMO roles distribution
  • Performance metrics collection (CPU, Memory, Disk)
  • Status check of critical AD services
  • DNS configuration verification
  • SYSVOL and NETLOGON share accessibility check
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Active Directory administrators
  • System administrators managing Domain Controllers
  • IT professionals troubleshooting AD issues
  • Security teams auditing AD infrastructure

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query Domain Controllers
  3. Have the Active Directory PowerShell module installed

This script provides a comprehensive overview of Domain Controllers in an Active Directory environment, making it easier to identify issues, performance bottlenecks, or misconfigurations. It can significantly streamline the process of maintaining and troubleshooting Domain Controllers in organizations of any size.

Microsoft 365 Analyzer Tool

<#
.SYNOPSIS
Microsoft 365 Analyzer Tool

.DESCRIPTION
This script analyzes various aspects of a Microsoft 365 environment, including user accounts,
licenses, Exchange Online, SharePoint Online, and Teams.

.NOTES
File Name      : Microsoft365Analyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Microsoft 365 PowerShell modules, and appropriate admin permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\Microsoft365Analyzer.ps1
#>

# Check and install required modules
$requiredModules = @("MSOnline", "ExchangeOnlineManagement", "Microsoft.Online.SharePoint.PowerShell", "MicrosoftTeams")
foreach ($module in $requiredModules) {
    if (!(Get-Module -ListAvailable -Name $module)) {
        Write-Host "Installing $module module..." -ForegroundColor Yellow
        Install-Module -Name $module -Force -AllowClobber
    }
}

# Import required modules
Import-Module MSOnline
Import-Module ExchangeOnlineManagement
Import-Module Microsoft.Online.SharePoint.PowerShell
Import-Module MicrosoftTeams

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Microsoft 365 Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze User Accounts and Licenses"
    Write-Host "2. Check Exchange Online Configuration"
    Write-Host "3. Analyze SharePoint Online Usage"
    Write-Host "4. Review Teams Configuration"
    Write-Host "5. Check Security and Compliance Settings"
    Write-Host "6. Analyze Azure AD Configuration"
    Write-Host "7. Generate Comprehensive HTML Report"
    Write-Host "8. Exit"
}

<#
.SYNOPSIS
Connects to Microsoft 365 services.
#>
function Connect-Microsoft365Services {
    Write-Host "Connecting to Microsoft 365 services..." -ForegroundColor Yellow
    Connect-MsolService
    Connect-ExchangeOnline
    $orgName = (Get-MsolCompanyInformation).DisplayName
    $adminSiteUrl = "https://$($orgName.Replace(' ', ''))-admin.sharepoint.com"
    Connect-SPOService -Url $adminSiteUrl
    Connect-MicrosoftTeams
}

<#
.SYNOPSIS
Analyzes user accounts and licenses.

.OUTPUTS
PSObject containing user account and license analysis.
#>
function Analyze-UserAccountsAndLicenses {
    Write-Host "`nAnalyzing User Accounts and Licenses..." -ForegroundColor Yellow
    $users = Get-MsolUser -All
    $licenses = Get-MsolAccountSku

    $analysis = [PSCustomObject]@{
        TotalUsers = $users.Count
        LicensedUsers = ($users | Where-Object {$_.IsLicensed -eq $true}).Count
        UnlicensedUsers = ($users | Where-Object {$_.IsLicensed -eq $false}).Count
        BlockedUsers = ($users | Where-Object {$_.BlockCredential -eq $true}).Count
        LicenseTypes = $licenses | Select-Object AccountSkuId, ActiveUnits, ConsumedUnits
    }

    $analysis | Format-List
    return $analysis
}

<#
.SYNOPSIS
Checks Exchange Online configuration.

.OUTPUTS
PSObject containing Exchange Online configuration details.
#>
function Check-ExchangeOnlineConfiguration {
    Write-Host "`nChecking Exchange Online Configuration..." -ForegroundColor Yellow
    $mailboxes = Get-Mailbox -ResultSize Unlimited
    $transportRules = Get-TransportRule

    $exchangeConfig = [PSCustomObject]@{
        TotalMailboxes = $mailboxes.Count
        SharedMailboxes = ($mailboxes | Where-Object {$_.RecipientTypeDetails -eq "SharedMailbox"}).Count
        ResourceMailboxes = ($mailboxes | Where-Object {$_.RecipientTypeDetails -eq "RoomMailbox" -or $_.RecipientTypeDetails -eq "EquipmentMailbox"}).Count
        TransportRules = $transportRules.Count
    }

    $exchangeConfig | Format-List
    return $exchangeConfig
}

<#
.SYNOPSIS
Analyzes SharePoint Online usage.

.OUTPUTS
PSObject containing SharePoint Online usage details.
#>
function Analyze-SharePointOnlineUsage {
    Write-Host "`nAnalyzing SharePoint Online Usage..." -ForegroundColor Yellow
    $sites = Get-SPOSite -Limit All
    $oneDriveUsage = Get-SPOTenantOneDriveUsageReport

    $spUsage = [PSCustomObject]@{
        TotalSites = $sites.Count
        TotalStorage = [math]::Round(($sites | Measure-Object StorageUsageCurrent -Sum).Sum / 1024, 2)
        AverageStoragePerSite = [math]::Round(($sites | Measure-Object StorageUsageCurrent -Average).Average / 1024, 2)
        OneDriveUsage = $oneDriveUsage
    }

    $spUsage | Format-List
    return $spUsage
}

<#
.SYNOPSIS
Reviews Teams configuration.

.OUTPUTS
PSObject containing Teams configuration details.
#>
function Review-TeamsConfiguration {
    Write-Host "`nReviewing Teams Configuration..." -ForegroundColor Yellow
    $teams = Get-Team
    $policies = Get-CsTeamsClientConfiguration

    $teamsConfig = [PSCustomObject]@{
        TotalTeams = $teams.Count
        PublicTeams = ($teams | Where-Object {$_.Visibility -eq "Public"}).Count
        PrivateTeams = ($teams | Where-Object {$_.Visibility -eq "Private"}).Count
        AllowEmailIntoChannel = $policies.AllowEmailIntoChannel
        AllowGiphy = $policies.AllowGiphy
        AllowStickers = $policies.AllowStickers
        AllowUserEditMessages = $policies.AllowUserEditMessages
    }

    $teamsConfig | Format-List
    return $teamsConfig
}

<#
.SYNOPSIS
Checks security and compliance settings.

.OUTPUTS
PSObject containing security and compliance settings.
#>
function Check-SecurityAndComplianceSettings {
    Write-Host "`nChecking Security and Compliance Settings..." -ForegroundColor Yellow
    $mfaStatus = Get-MsolUser -All | Where-Object {$_.StrongAuthenticationRequirements.State}
    $alertPolicies = Get-ProtectionAlert

    $securitySettings = [PSCustomObject]@{
        MFAEnabledUsers = $mfaStatus.Count
        AlertPolicies = $alertPolicies.Count
    }

    $securitySettings | Format-List
    return $securitySettings
}

<#
.SYNOPSIS
Analyzes Azure AD configuration.

.OUTPUTS
PSObject containing Azure AD configuration details.
#>
function Analyze-AzureADConfiguration {
    Write-Host "`nAnalyzing Azure AD Configuration..." -ForegroundColor Yellow
    $domains = Get-MsolDomain
    $devices = Get-MsolDevice -All

    $azureADConfig = [PSCustomObject]@{
        TotalDomains = $domains.Count
        VerifiedDomains = ($domains | Where-Object {$_.Status -eq "Verified"}).Count
        TotalDevices = $devices.Count
        AzureADJoinedDevices = ($devices | Where-Object {$_.DeviceTrustType -eq "Azure AD Joined"}).Count
    }

    $azureADConfig | Format-List
    return $azureADConfig
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>Microsoft 365 Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>Microsoft 365 Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>User Accounts and Licenses</h2>
    $($AllResults.UserAccountsAndLicenses | ConvertTo-Html -Fragment)

    <h2>Exchange Online Configuration</h2>
    $($AllResults.ExchangeOnlineConfig | ConvertTo-Html -Fragment)

    <h2>SharePoint Online Usage</h2>
    $($AllResults.SharePointOnlineUsage | ConvertTo-Html -Fragment)

    <h2>Teams Configuration</h2>
    $($AllResults.TeamsConfig | ConvertTo-Html -Fragment)

    <h2>Security and Compliance Settings</h2>
    $($AllResults.SecuritySettings | ConvertTo-Html -Fragment)

    <h2>Azure AD Configuration</h2>
    $($AllResults.AzureADConfig | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
Connect-Microsoft365Services
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.UserAccountsAndLicenses = Analyze-UserAccountsAndLicenses }
        "2" { $allResults.ExchangeOnlineConfig = Check-ExchangeOnlineConfiguration }
        "3" { $allResults.SharePointOnlineUsage = Analyze-SharePointOnlineUsage }
        "4" { $allResults.TeamsConfig = Review-TeamsConfiguration }
        "5" { $allResults.SecuritySettings = Check-SecurityAndComplianceSettings }
        "6" { $allResults.AzureADConfig = Analyze-AzureADConfiguration }
        "7" { Generate-HTMLReport -AllResults $allResults }
        "8" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

# Disconnect from services
Disconnect-ExchangeOnline -Confirm:$false
Disconnect-SPOService
Disconnect-MicrosoftTeams

This Microsoft 365 Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of Microsoft 365:
    • User accounts and licenses
    • Exchange Online configuration
    • SharePoint Online usage
    • Teams configuration
    • Security and compliance settings
    • Azure AD configuration
  3. Automatic installation of required PowerShell modules.
  4. Connection to necessary Microsoft 365 services.
  5. A function to generate an HTML report of all collected data.

Key features:

  • Comprehensive analysis of Microsoft 365 environment
  • Detailed insights into user accounts, licenses, and service configurations
  • Security and compliance overview
  • Azure AD configuration analysis
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Microsoft 365 administrators
  • IT professionals managing Microsoft 365 environments
  • Security teams auditing Microsoft 365 configurations
  • Consultants performing Microsoft 365 health checks

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to access Microsoft 365 services (Global Administrator or appropriate admin roles)
  3. Have an active internet connection

This script provides a comprehensive overview of a Microsoft 365 environment, making it easier to identify configuration issues, security concerns, or areas for optimization. It can significantly streamline the process of auditing and maintaining Microsoft 365 services in organizations of any size.

Active Directory Computer Analysis Tool

<#
.SYNOPSIS
Active Directory Computer Analysis Tool

.DESCRIPTION
This script analyzes computer accounts in Active Directory, providing detailed information
about computer properties, group memberships, operating systems, and potential issues.

.NOTES
File Name      : ADComputerAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Active Directory module, and appropriate AD permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\ADComputerAnalyzer.ps1
#>

# Import required modules
Import-Module ActiveDirectory

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Active Directory Computer Analysis Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze Computer Account Statuses"
    Write-Host "2. Check Operating System Distribution"
    Write-Host "3. Analyze Group Memberships"
    Write-Host "4. Identify Inactive Computer Accounts"
    Write-Host "5. Check for Outdated Operating Systems"
    Write-Host "6. Analyze Computer Account Properties"
    Write-Host "7. Check DNS Registration Status"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes computer account statuses.

.OUTPUTS
Array of PSObjects containing computer account status details.
#>
function Analyze-ComputerAccountStatuses {
    Write-Host "`nAnalyzing Computer Account Statuses..." -ForegroundColor Yellow
    $computers = Get-ADComputer -Filter * -Properties Enabled, PasswordLastSet
    $statuses = @()
    foreach ($computer in $computers) {
        $statuses += [PSCustomObject]@{
            ComputerName = $computer.Name
            Enabled = $computer.Enabled
            PasswordLastSet = $computer.PasswordLastSet
            DaysSincePasswordSet = if ($computer.PasswordLastSet) { ((Get-Date) - $computer.PasswordLastSet).Days } else { "N/A" }
        }
    }
    $statuses | Format-Table -AutoSize
    return $statuses
}

<#
.SYNOPSIS
Checks operating system distribution.

.OUTPUTS
Array of PSObjects containing OS distribution details.
#>
function Check-OSDistribution {
    Write-Host "`nChecking Operating System Distribution..." -ForegroundColor Yellow
    $computers = Get-ADComputer -Filter * -Properties OperatingSystem
    $osDistribution = $computers | Group-Object -Property OperatingSystem | Select-Object Name, Count
    $osDistribution | Format-Table -AutoSize
    return $osDistribution
}

<#
.SYNOPSIS
Analyzes group memberships.

.OUTPUTS
Array of PSObjects containing group membership details.
#>
function Analyze-GroupMemberships {
    Write-Host "`nAnalyzing Group Memberships..." -ForegroundColor Yellow
    $computers = Get-ADComputer -Filter * -Properties MemberOf
    $memberships = @()
    foreach ($computer in $computers) {
        $groups = $computer.MemberOf | ForEach-Object { (Get-ADGroup $_).Name }
        $memberships += [PSCustomObject]@{
            ComputerName = $computer.Name
            GroupCount = $groups.Count
            Groups = $groups -join ", "
        }
    }
    $memberships | Format-Table -AutoSize
    return $memberships
}

<#
.SYNOPSIS
Identifies inactive computer accounts.

.OUTPUTS
Array of PSObjects containing inactive computer account details.
#>
function Identify-InactiveComputerAccounts {
    Write-Host "`nIdentifying Inactive Computer Accounts..." -ForegroundColor Yellow
    $inactiveThreshold = (Get-Date).AddDays(-90)
    $computers = Get-ADComputer -Filter {Enabled -eq $true} -Properties LastLogonDate
    $inactiveComputers = @()
    foreach ($computer in $computers) {
        if ($computer.LastLogonDate -lt $inactiveThreshold) {
            $inactiveComputers += [PSCustomObject]@{
                ComputerName = $computer.Name
                LastLogonDate = $computer.LastLogonDate
                DaysSinceLastLogon = ((Get-Date) - $computer.LastLogonDate).Days
            }
        }
    }
    $inactiveComputers | Format-Table -AutoSize
    return $inactiveComputers
}

<#
.SYNOPSIS
Checks for outdated operating systems.

.OUTPUTS
Array of PSObjects containing outdated OS details.
#>
function Check-OutdatedOS {
    Write-Host "`nChecking for Outdated Operating Systems..." -ForegroundColor Yellow
    $computers = Get-ADComputer -Filter * -Properties OperatingSystem, OperatingSystemVersion
    $outdatedOS = @()
    foreach ($computer in $computers) {
        if ($computer.OperatingSystem -like "*Windows 7*" -or 
            $computer.OperatingSystem -like "*Windows 8*" -or 
            $computer.OperatingSystem -like "*Windows Server 2008*" -or 
            $computer.OperatingSystem -like "*Windows Server 2012*") {
            $outdatedOS += [PSCustomObject]@{
                ComputerName = $computer.Name
                OperatingSystem = $computer.OperatingSystem
                OSVersion = $computer.OperatingSystemVersion
            }
        }
    }
    $outdatedOS | Format-Table -AutoSize
    return $outdatedOS
}

<#
.SYNOPSIS
Analyzes computer account properties.

.OUTPUTS
Array of PSObjects containing computer account property details.
#>
function Analyze-ComputerAccountProperties {
    Write-Host "`nAnalyzing Computer Account Properties..." -ForegroundColor Yellow
    $computers = Get-ADComputer -Filter * -Properties *
    $properties = @()
    foreach ($computer in $computers) {
        $properties += [PSCustomObject]@{
            ComputerName = $computer.Name
            OperatingSystem = $computer.OperatingSystem
            IPAddress = $computer.IPv4Address
            Created = $computer.Created
            LastModified = $computer.Modified
            Description = $computer.Description
        }
    }
    $properties | Format-Table -AutoSize
    return $properties
}

<#
.SYNOPSIS
Checks DNS registration status.

.OUTPUTS
Array of PSObjects containing DNS registration status details.
#>
function Check-DNSRegistrationStatus {
    Write-Host "`nChecking DNS Registration Status..." -ForegroundColor Yellow
    $computers = Get-ADComputer -Filter * -Properties DNSHostName
    $dnsStatus = @()
    foreach ($computer in $computers) {
        $pingResult = Test-Connection -ComputerName $computer.DNSHostName -Count 1 -ErrorAction SilentlyContinue
        $dnsStatus += [PSCustomObject]@{
            ComputerName = $computer.Name
            DNSHostName = $computer.DNSHostName
            Pingable = if ($pingResult) { $true } else { $false }
        }
    }
    $dnsStatus | Format-Table -AutoSize
    return $dnsStatus
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>AD Computer Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>Active Directory Computer Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Computer Account Statuses</h2>
    $($AllResults.AccountStatuses | ConvertTo-Html -Fragment)

    <h2>Operating System Distribution</h2>
    $($AllResults.OSDistribution | ConvertTo-Html -Fragment)

    <h2>Group Memberships</h2>
    $($AllResults.GroupMemberships | ConvertTo-Html -Fragment)

    <h2>Inactive Computer Accounts</h2>
    $($AllResults.InactiveAccounts | ConvertTo-Html -Fragment)

    <h2>Outdated Operating Systems</h2>
    $($AllResults.OutdatedOS | ConvertTo-Html -Fragment)

    <h2>Computer Account Properties</h2>
    $($AllResults.AccountProperties | ConvertTo-Html -Fragment)

    <h2>DNS Registration Status</h2>
    $($AllResults.DNSStatus | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.AccountStatuses = Analyze-ComputerAccountStatuses }
        "2" { $allResults.OSDistribution = Check-OSDistribution }
        "3" { $allResults.GroupMemberships = Analyze-GroupMemberships }
        "4" { $allResults.InactiveAccounts = Identify-InactiveComputerAccounts }
        "5" { $allResults.OutdatedOS = Check-OutdatedOS }
        "6" { $allResults.AccountProperties = Analyze-ComputerAccountProperties }
        "7" { $allResults.DNSStatus = Check-DNSRegistrationStatus }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Active Directory Computer Analysis Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of computer accounts:
    • Computer account statuses (enabled, password last set)
    • Operating system distribution
    • Group memberships
    • Inactive computer accounts
    • Outdated operating systems
    • Computer account properties
    • DNS registration status
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of computer account statuses and properties
  • Overview of operating system distribution across the domain
  • Identification of inactive computer accounts
  • Detection of outdated operating systems
  • Analysis of group memberships for computer accounts
  • Checking DNS registration status and connectivity
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Active Directory administrators managing computer accounts
  • IT security professionals auditing computer account security
  • System administrators planning OS upgrades or migrations
  • Network administrators troubleshooting DNS and connectivity issues

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query AD computer information
  3. Have the Active Directory PowerShell module installed

This script provides a comprehensive overview of computer accounts in an Active Directory environment, making it easier to identify security issues, outdated systems, or potential network problems. It can significantly streamline the process of auditing and maintaining computer accounts in large or complex AD environments.

Active Directory User Analysis Tool

<#
.SYNOPSIS
Active Directory User Analysis Tool

.DESCRIPTION
This script analyzes user accounts in Active Directory, providing detailed information
about user properties, group memberships, account statuses, and potential security issues.

.NOTES
File Name      : ADUserAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Active Directory module, and appropriate AD permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\ADUserAnalyzer.ps1
#>

# Import required modules
Import-Module ActiveDirectory

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Active Directory User Analysis Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze User Account Statuses"
    Write-Host "2. Check Password Policies Compliance"
    Write-Host "3. Analyze Group Memberships"
    Write-Host "4. Identify Inactive User Accounts"
    Write-Host "5. Check for Privileged Accounts"
    Write-Host "6. Analyze User Account Properties"
    Write-Host "7. Check for Expired Accounts"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes user account statuses.

.OUTPUTS
Array of PSObjects containing user account status details.
#>
function Analyze-UserAccountStatuses {
    Write-Host "`nAnalyzing User Account Statuses..." -ForegroundColor Yellow
    $users = Get-ADUser -Filter * -Properties Enabled, LockedOut, PasswordExpired, PasswordNeverExpires
    $statuses = @()
    foreach ($user in $users) {
        $statuses += [PSCustomObject]@{
            Username = $user.SamAccountName
            Enabled = $user.Enabled
            LockedOut = $user.LockedOut
            PasswordExpired = $user.PasswordExpired
            PasswordNeverExpires = $user.PasswordNeverExpires
        }
    }
    $statuses | Format-Table -AutoSize
    return $statuses
}

<#
.SYNOPSIS
Checks password policies compliance.

.OUTPUTS
Array of PSObjects containing password policy compliance details.
#>
function Check-PasswordPoliciesCompliance {
    Write-Host "`nChecking Password Policies Compliance..." -ForegroundColor Yellow
    $defaultPolicy = Get-ADDefaultDomainPasswordPolicy
    $users = Get-ADUser -Filter * -Properties PasswordLastSet, PasswordNeverExpires
    $compliance = @()
    foreach ($user in $users) {
        $passwordAge = (Get-Date) - $user.PasswordLastSet
        $compliance += [PSCustomObject]@{
            Username = $user.SamAccountName
            PasswordLastSet = $user.PasswordLastSet
            PasswordAge = "$($passwordAge.Days) days"
            CompliantMaxAge = if ($user.PasswordNeverExpires) { "N/A" } elseif ($passwordAge.Days -le $defaultPolicy.MaxPasswordAge.Days) { $true } else { $false }
            PasswordNeverExpires = $user.PasswordNeverExpires
        }
    }
    $compliance | Format-Table -AutoSize
    return $compliance
}

<#
.SYNOPSIS
Analyzes group memberships.

.OUTPUTS
Array of PSObjects containing group membership details.
#>
function Analyze-GroupMemberships {
    Write-Host "`nAnalyzing Group Memberships..." -ForegroundColor Yellow
    $users = Get-ADUser -Filter * -Properties MemberOf
    $memberships = @()
    foreach ($user in $users) {
        $groups = $user.MemberOf | ForEach-Object { (Get-ADGroup $_).Name }
        $memberships += [PSCustomObject]@{
            Username = $user.SamAccountName
            GroupCount = $groups.Count
            Groups = $groups -join ", "
        }
    }
    $memberships | Format-Table -AutoSize
    return $memberships
}

<#
.SYNOPSIS
Identifies inactive user accounts.

.OUTPUTS
Array of PSObjects containing inactive user account details.
#>
function Identify-InactiveUserAccounts {
    Write-Host "`nIdentifying Inactive User Accounts..." -ForegroundColor Yellow
    $inactiveThreshold = (Get-Date).AddDays(-90)
    $users = Get-ADUser -Filter {Enabled -eq $true} -Properties LastLogonDate
    $inactiveUsers = @()
    foreach ($user in $users) {
        if ($user.LastLogonDate -lt $inactiveThreshold) {
            $inactiveUsers += [PSCustomObject]@{
                Username = $user.SamAccountName
                LastLogonDate = $user.LastLogonDate
                DaysSinceLastLogon = ((Get-Date) - $user.LastLogonDate).Days
            }
        }
    }
    $inactiveUsers | Format-Table -AutoSize
    return $inactiveUsers
}

<#
.SYNOPSIS
Checks for privileged accounts.

.OUTPUTS
Array of PSObjects containing privileged account details.
#>
function Check-PrivilegedAccounts {
    Write-Host "`nChecking for Privileged Accounts..." -ForegroundColor Yellow
    $privilegedGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators")
    $privilegedAccounts = @()
    foreach ($group in $privilegedGroups) {
        $members = Get-ADGroupMember -Identity $group -Recursive | Where-Object {$_.objectClass -eq "user"}
        foreach ($member in $members) {
            $privilegedAccounts += [PSCustomObject]@{
                Username = $member.SamAccountName
                PrivilegedGroup = $group
            }
        }
    }
    $privilegedAccounts | Format-Table -AutoSize
    return $privilegedAccounts
}

<#
.SYNOPSIS
Analyzes user account properties.

.OUTPUTS
Array of PSObjects containing user account property details.
#>
function Analyze-UserAccountProperties {
    Write-Host "`nAnalyzing User Account Properties..." -ForegroundColor Yellow
    $users = Get-ADUser -Filter * -Properties *
    $properties = @()
    foreach ($user in $users) {
        $properties += [PSCustomObject]@{
            Username = $user.SamAccountName
            FullName = $user.Name
            Email = $user.EmailAddress
            Department = $user.Department
            Title = $user.Title
            Manager = if ($user.Manager) { (Get-ADUser $user.Manager).Name } else { "N/A" }
            Created = $user.Created
            LastModified = $user.Modified
        }
    }
    $properties | Format-Table -AutoSize
    return $properties
}

<#
.SYNOPSIS
Checks for expired accounts.

.OUTPUTS
Array of PSObjects containing expired account details.
#>
function Check-ExpiredAccounts {
    Write-Host "`nChecking for Expired Accounts..." -ForegroundColor Yellow
    $users = Get-ADUser -Filter {Enabled -eq $true -and AccountExpirationDate -lt (Get-Date)} -Properties AccountExpirationDate
    $expiredAccounts = @()
    foreach ($user in $users) {
        $expiredAccounts += [PSCustomObject]@{
            Username = $user.SamAccountName
            ExpirationDate = $user.AccountExpirationDate
            DaysExpired = ((Get-Date) - $user.AccountExpirationDate).Days
        }
    }
    $expiredAccounts | Format-Table -AutoSize
    return $expiredAccounts
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>AD User Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>Active Directory User Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>User Account Statuses</h2>
    $($AllResults.AccountStatuses | ConvertTo-Html -Fragment)

    <h2>Password Policies Compliance</h2>
    $($AllResults.PasswordCompliance | ConvertTo-Html -Fragment)

    <h2>Group Memberships</h2>
    $($AllResults.GroupMemberships | ConvertTo-Html -Fragment)

    <h2>Inactive User Accounts</h2>
    $($AllResults.InactiveAccounts | ConvertTo-Html -Fragment)

    <h2>Privileged Accounts</h2>
    $($AllResults.PrivilegedAccounts | ConvertTo-Html -Fragment)

    <h2>User Account Properties</h2>
    $($AllResults.AccountProperties | ConvertTo-Html -Fragment)

    <h2>Expired Accounts</h2>
    $($AllResults.ExpiredAccounts | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.AccountStatuses = Analyze-UserAccountStatuses }
        "2" { $allResults.PasswordCompliance = Check-PasswordPoliciesCompliance }
        "3" { $allResults.GroupMemberships = Analyze-GroupMemberships }
        "4" { $allResults.InactiveAccounts = Identify-InactiveUserAccounts }
        "5" { $allResults.PrivilegedAccounts = Check-PrivilegedAccounts }
        "6" { $allResults.AccountProperties = Analyze-UserAccountProperties }
        "7" { $allResults.ExpiredAccounts = Check-ExpiredAccounts }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Active Directory User Analysis Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of user accounts:
    • User account statuses (enabled, locked out, password expired)
    • Password policies compliance
    • Group memberships
    • Inactive user accounts
    • Privileged accounts
    • User account properties
    • Expired accounts
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of user account statuses and properties
  • Checking password policy compliance across all users
  • Identification of inactive and expired accounts
  • Analysis of group memberships, including privileged groups
  • Comprehensive overview of user account properties
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Active Directory administrators managing user accounts
  • IT security professionals auditing user account security
  • HR departments needing reports on user account statuses and properties
  • Compliance officers ensuring adherence to password policies

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query AD user information
  3. Have the Active Directory PowerShell module installed

This script provides a comprehensive overview of user accounts in an Active Directory environment, making it easier to identify security issues, compliance problems, or outdated account information. It can significantly streamline the process of auditing and maintaining user accounts in large or complex AD environments.

Active Directory Replication Analysis Tool

<#
.SYNOPSIS
Active Directory Replication Analysis Tool

.DESCRIPTION
This script analyzes Active Directory replication status, identifies issues,
and provides detailed information about replication topology and health.

.NOTES
File Name      : ADReplicationAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, Active Directory module, and appropriate AD permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\ADReplicationAnalyzer.ps1
#>

# Import required modules
Import-Module ActiveDirectory

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Active Directory Replication Analysis Tool ===" -ForegroundColor Cyan
    Write-Host "1. Check Replication Status"
    Write-Host "2. Analyze Replication Topology"
    Write-Host "3. Identify Replication Errors"
    Write-Host "4. Check Inter-Site Replication"
    Write-Host "5. Verify Domain Controller Metadata"
    Write-Host "6. Check KCC Connectivity"
    Write-Host "7. Analyze Replication Latency"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Checks the overall replication status.

.OUTPUTS
Array of PSObjects containing replication status details.
#>
function Check-ReplicationStatus {
    Write-Host "`nChecking Replication Status..." -ForegroundColor Yellow
    $results = @()
    $dcs = Get-ADDomainController -Filter *
    foreach ($dc in $dcs) {
        $replicationStatus = repadmin /showrepl $dc.HostName
        $lastReplication = ($replicationStatus | Select-String "Last attempt" | Select-Object -First 1) -replace "Last attempt @ ",""
        $results += [PSCustomObject]@{
            DomainController = $dc.HostName
            LastReplication = $lastReplication
            Status = if ($replicationStatus -match "was successful") { "Successful" } else { "Failed" }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes the replication topology.

.OUTPUTS
Array of PSObjects containing replication topology details.
#>
function Analyze-ReplicationTopology {
    Write-Host "`nAnalyzing Replication Topology..." -ForegroundColor Yellow
    $topology = @()
    $sites = Get-ADReplicationSite -Filter *
    foreach ($site in $sites) {
        $siteLinks = Get-ADReplicationSiteLink -Filter {SitesIncluded -eq $site.DistinguishedName}
        $dcs = Get-ADDomainController -Filter {Site -eq $site.Name}
        $topology += [PSCustomObject]@{
            SiteName = $site.Name
            DomainControllers = ($dcs | ForEach-Object { $_.Name }) -join ", "
            ConnectedSites = ($siteLinks | ForEach-Object { ($_.SitesIncluded | Where-Object { $_ -ne $site.DistinguishedName }) -replace "CN=|,.*" }) -join ", "
        }
    }
    $topology | Format-Table -AutoSize
    return $topology
}

<#
.SYNOPSIS
Identifies replication errors.

.OUTPUTS
Array of PSObjects containing replication error details.
#>
function Identify-ReplicationErrors {
    Write-Host "`nIdentifying Replication Errors..." -ForegroundColor Yellow
    $errors = @()
    $dcs = Get-ADDomainController -Filter *
    foreach ($dc in $dcs) {
        $replicationStatus = repadmin /showrepl $dc.HostName
        $errorLines = $replicationStatus | Select-String "Error"
        foreach ($line in $errorLines) {
            $errors += [PSCustomObject]@{
                DomainController = $dc.HostName
                Error = $line.Line.Trim()
            }
        }
    }
    if ($errors.Count -eq 0) {
        Write-Host "No replication errors found." -ForegroundColor Green
    } else {
        $errors | Format-Table -AutoSize
    }
    return $errors
}

<#
.SYNOPSIS
Checks inter-site replication.

.OUTPUTS
Array of PSObjects containing inter-site replication details.
#>
function Check-InterSiteReplication {
    Write-Host "`nChecking Inter-Site Replication..." -ForegroundColor Yellow
    $interSiteRepl = @()
    $siteLinks = Get-ADReplicationSiteLink -Filter *
    foreach ($link in $siteLinks) {
        $interSiteRepl += [PSCustomObject]@{
            SiteLinkName = $link.Name
            Sites = ($link.SitesIncluded | ForEach-Object { ($_ -replace "CN=|,.*") }) -join ", "
            ReplicationInterval = $link.ReplicationFrequencyInMinutes
            Cost = $link.Cost
        }
    }
    $interSiteRepl | Format-Table -AutoSize
    return $interSiteRepl
}

<#
.SYNOPSIS
Verifies domain controller metadata.

.OUTPUTS
Array of PSObjects containing DC metadata details.
#>
function Verify-DCMetadata {
    Write-Host "`nVerifying Domain Controller Metadata..." -ForegroundColor Yellow
    $metadata = @()
    $dcs = Get-ADDomainController -Filter *
    foreach ($dc in $dcs) {
        $dcMetadata = Get-ADReplicationPartnerMetadata -Target $dc.HostName
        $metadata += [PSCustomObject]@{
            DomainController = $dc.HostName
            LastReplicationAttempt = $dcMetadata.LastReplicationAttempt
            LastReplicationResult = $dcMetadata.LastReplicationResult
            LastReplicationSuccess = $dcMetadata.LastReplicationSuccess
        }
    }
    $metadata | Format-Table -AutoSize
    return $metadata
}

<#
.SYNOPSIS
Checks KCC connectivity.

.OUTPUTS
Array of PSObjects containing KCC connectivity details.
#>
function Check-KCCConnectivity {
    Write-Host "`nChecking KCC Connectivity..." -ForegroundColor Yellow
    $kccConnectivity = @()
    $dcs = Get-ADDomainController -Filter *
    foreach ($dc in $dcs) {
        $kccStatus = repadmin /showkcc $dc.HostName
        $kccConnectivity += [PSCustomObject]@{
            DomainController = $dc.HostName
            Status = if ($kccStatus -match "completed successfully") { "Successful" } else { "Failed" }
            Details = ($kccStatus | Select-String "Intra" -Context 0,1).Context.PostContext
        }
    }
    $kccConnectivity | Format-Table -AutoSize
    return $kccConnectivity
}

<#
.SYNOPSIS
Analyzes replication latency.

.OUTPUTS
Array of PSObjects containing replication latency details.
#>
function Analyze-ReplicationLatency {
    Write-Host "`nAnalyzing Replication Latency..." -ForegroundColor Yellow
    $latency = @()
    $dcs = Get-ADDomainController -Filter *
    foreach ($dc in $dcs) {
        $replPartners = Get-ADReplicationPartnerMetadata -Target $dc.HostName
        foreach ($partner in $replPartners) {
            $latency += [PSCustomObject]@{
                SourceDC = $dc.HostName
                PartnerDC = $partner.Partner
                LastReplicationAttempt = $partner.LastReplicationAttempt
                LastReplicationSuccess = $partner.LastReplicationSuccess
                LatencyMinutes = if ($partner.LastReplicationSuccess) {
                    [math]::Round(($partner.LastReplicationAttempt - $partner.LastReplicationSuccess).TotalMinutes, 2)
                } else { "N/A" }
            }
        }
    }
    $latency | Format-Table -AutoSize
    return $latency
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>AD Replication Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>Active Directory Replication Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Replication Status</h2>
    $($AllResults.ReplicationStatus | ConvertTo-Html -Fragment)

    <h2>Replication Topology</h2>
    $($AllResults.ReplicationTopology | ConvertTo-Html -Fragment)

    <h2>Replication Errors</h2>
    $($AllResults.ReplicationErrors | ConvertTo-Html -Fragment)

    <h2>Inter-Site Replication</h2>
    $($AllResults.InterSiteReplication | ConvertTo-Html -Fragment)

    <h2>Domain Controller Metadata</h2>
    $($AllResults.DCMetadata | ConvertTo-Html -Fragment)

    <h2>KCC Connectivity</h2>
    $($AllResults.KCCConnectivity | ConvertTo-Html -Fragment)

    <h2>Replication Latency</h2>
    $($AllResults.ReplicationLatency | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.ReplicationStatus = Check-ReplicationStatus }
        "2" { $allResults.ReplicationTopology = Analyze-ReplicationTopology }
        "3" { $allResults.ReplicationErrors = Identify-ReplicationErrors }
        "4" { $allResults.InterSiteReplication = Check-InterSiteReplication }
        "5" { $allResults.DCMetadata = Verify-DCMetadata }
        "6" { $allResults.KCCConnectivity = Check-KCCConnectivity }
        "7" { $allResults.ReplicationLatency = Analyze-ReplicationLatency }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Active Directory Replication Analysis Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of AD replication:
    • Overall replication status check
    • Replication topology analysis
    • Identification of replication errors
    • Inter-site replication check
    • Domain controller metadata verification
    • KCC (Knowledge Consistency Checker) connectivity check
    • Replication latency analysis
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of replication status across all domain controllers
  • Visualization of replication topology, including sites and links
  • Identification and reporting of replication errors
  • Analysis of inter-site replication configuration
  • Verification of domain controller metadata for replication health
  • Check of KCC connectivity to ensure proper replication partner selection
  • Analysis of replication latency to identify slow replication issues
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • Active Directory administrators managing complex multi-site environments
  • IT professionals troubleshooting AD replication issues
  • System administrators performing regular health checks on AD infrastructure

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query AD replication in your domain
  3. Have the Active Directory PowerShell module installed

This script provides a comprehensive overview of the AD replication status and health in an Active Directory environment, making it easier to identify issues, bottlenecks, or misconfigurations related to replication. It can significantly streamline the process of troubleshooting and maintaining AD replication in large or complex environments.

Active Directory Certificate Services (AD CS) Analyzer

<#
.SYNOPSIS
Active Directory Certificate Services (AD CS) Analyzer

.DESCRIPTION
This script analyzes the configuration and health of Active Directory Certificate Services,
providing detailed information about Certificate Authorities, templates, and potential issues.

.NOTES
File Name      : ADCSAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, PSPKI module, and appropriate AD CS permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\ADCSAnalyzer.ps1
#>

# Check if PSPKI module is installed, if not, attempt to install it
if (-not (Get-Module -ListAvailable -Name PSPKI)) {
    Write-Host "PSPKI module not found. Attempting to install..." -ForegroundColor Yellow
    try {
        Install-Module -Name PSPKI -Force -AllowClobber
    }
    catch {
        Write-Host "Failed to install PSPKI module. Please install it manually." -ForegroundColor Red
        exit
    }
}

# Import required modules
Import-Module PSPKI

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Active Directory Certificate Services Analyzer ===" -ForegroundColor Cyan
    Write-Host "1. Analyze Certificate Authorities"
    Write-Host "2. Review Certificate Templates"
    Write-Host "3. Check CA Health Status"
    Write-Host "4. Analyze Certificate Revocation Lists (CRLs)"
    Write-Host "5. Review CA Security Permissions"
    Write-Host "6. Analyze Certificate Issuance Policies"
    Write-Host "7. Check for Vulnerable Certificate Templates"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes Certificate Authorities in the environment.

.OUTPUTS
Array of PSObjects containing CA details.
#>
function Analyze-CertificateAuthorities {
    Write-Host "`nAnalyzing Certificate Authorities..." -ForegroundColor Yellow
    $cas = Get-CertificationAuthority
    $caDetails = @()
    foreach ($ca in $cas) {
        $caDetails += [PSCustomObject]@{
            Name = $ca.Name
            Status = $ca.Status
            Type = $ca.Type
            Version = $ca.Version
            KeyLength = $ca.KeyLength
            HashAlgorithm = $ca.HashAlgorithm
            ValidityPeriod = $ca.ValidityPeriod
        }
    }
    $caDetails | Format-Table -AutoSize
    return $caDetails
}

<#
.SYNOPSIS
Reviews Certificate Templates.

.OUTPUTS
Array of PSObjects containing template details.
#>
function Review-CertificateTemplates {
    Write-Host "`nReviewing Certificate Templates..." -ForegroundColor Yellow
    $templates = Get-CertificateTemplate
    $templateDetails = @()
    foreach ($template in $templates) {
        $templateDetails += [PSCustomObject]@{
            Name = $template.Name
            DisplayName = $template.DisplayName
            SchemaVersion = $template.SchemaVersion
            ValidityPeriod = $template.ValidityPeriod
            RenewalPeriod = $template.RenewalPeriod
            AuthorizedSignatures = $template.AuthorizedSignatures
            EnrollmentFlags = $template.EnrollmentFlags
        }
    }
    $templateDetails | Format-Table -AutoSize
    return $templateDetails
}

<#
.SYNOPSIS
Checks the health status of Certificate Authorities.

.OUTPUTS
Array of PSObjects containing CA health status.
#>
function Check-CAHealthStatus {
    Write-Host "`nChecking CA Health Status..." -ForegroundColor Yellow
    $cas = Get-CertificationAuthority
    $healthStatus = @()
    foreach ($ca in $cas) {
        $status = Test-CertificationAuthority -CertificationAuthority $ca.Name
        $healthStatus += [PSCustomObject]@{
            CAName = $ca.Name
            IsAccessible = $status.IsAccessible
            IsCaAccessible = $status.IsCaAccessible
            IsRoleAccessible = $status.IsRoleAccessible
            IsWebEnrollmentAccessible = $status.IsWebEnrollmentAccessible
        }
    }
    $healthStatus | Format-Table -AutoSize
    return $healthStatus
}

<#
.SYNOPSIS
Analyzes Certificate Revocation Lists (CRLs).

.OUTPUTS
Array of PSObjects containing CRL details.
#>
function Analyze-CRLs {
    Write-Host "`nAnalyzing Certificate Revocation Lists..." -ForegroundColor Yellow
    $cas = Get-CertificationAuthority
    $crlDetails = @()
    foreach ($ca in $cas) {
        $crl = Get-CACrlDistributionPoint -CertificationAuthority $ca.Name
        foreach ($point in $crl) {
            $crlDetails += [PSCustomObject]@{
                CAName = $ca.Name
                URI = $point.URI
                PublishToServer = $point.PublishToServer
                PublishToDeltaServer = $point.PublishToDeltaServer
                PublishToDS = $point.PublishToDS
            }
        }
    }
    $crlDetails | Format-Table -AutoSize
    return $crlDetails
}

<#
.SYNOPSIS
Reviews CA Security Permissions.

.OUTPUTS
Array of PSObjects containing CA security permission details.
#>
function Review-CASecurityPermissions {
    Write-Host "`nReviewing CA Security Permissions..." -ForegroundColor Yellow
    $cas = Get-CertificationAuthority
    $securityPermissions = @()
    foreach ($ca in $cas) {
        $permissions = Get-CASecurityDescriptor -CertificationAuthority $ca.Name
        foreach ($ace in $permissions.Access) {
            $securityPermissions += [PSCustomObject]@{
                CAName = $ca.Name
                IdentityReference = $ace.IdentityReference
                AccessControlType = $ace.AccessControlType
                Rights = $ace.Rights
            }
        }
    }
    $securityPermissions | Format-Table -AutoSize
    return $securityPermissions
}

<#
.SYNOPSIS
Analyzes Certificate Issuance Policies.

.OUTPUTS
Array of PSObjects containing issuance policy details.
#>
function Analyze-CertificateIssuancePolicies {
    Write-Host "`nAnalyzing Certificate Issuance Policies..." -ForegroundColor Yellow
    $cas = Get-CertificationAuthority
    $issuancePolicies = @()
    foreach ($ca in $cas) {
        $policies = Get-CAPolicy -CertificationAuthority $ca.Name
        foreach ($policy in $policies) {
            $issuancePolicies += [PSCustomObject]@{
                CAName = $ca.Name
                PolicyName = $policy.Name
                OID = $policy.OID
                Enabled = $policy.Enabled
            }
        }
    }
    $issuancePolicies | Format-Table -AutoSize
    return $issuancePolicies
}

<#
.SYNOPSIS
Checks for potentially vulnerable certificate templates.

.OUTPUTS
Array of PSObjects containing vulnerable template details.
#>
function Check-VulnerableCertificateTemplates {
    Write-Host "`nChecking for Vulnerable Certificate Templates..." -ForegroundColor Yellow
    $templates = Get-CertificateTemplate
    $vulnerableTemplates = @()
    foreach ($template in $templates) {
        $isVulnerable = $false
        $vulnerabilities = @()

        if ($template.EnrollmentFlags -band 0x00000008) {
            $isVulnerable = $true
            $vulnerabilities += "No CA signature required"
        }
        if ($template.AuthorizedSignatures -eq 0) {
            $isVulnerable = $true
            $vulnerabilities += "No authorized signatures required"
        }
        if ($template.PrivateKeyFlags -band 0x00000001) {
            $isVulnerable = $true
            $vulnerabilities += "Exportable private key"
        }

        if ($isVulnerable) {
            $vulnerableTemplates += [PSCustomObject]@{
                TemplateName = $template.Name
                Vulnerabilities = $vulnerabilities -join ", "
            }
        }
    }
    $vulnerableTemplates | Format-Table -AutoSize
    return $vulnerableTemplates
}

<#
.SYNOPSIS
Generates a comprehensive HTML report of all analyses.

.PARAMETER AllResults
Hashtable containing all analysis results.

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>AD CS Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { 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>Active Directory Certificate Services Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Certificate Authorities</h2>
    $($AllResults.CertificateAuthorities | ConvertTo-Html -Fragment)

    <h2>Certificate Templates</h2>
    $($AllResults.CertificateTemplates | ConvertTo-Html -Fragment)

    <h2>CA Health Status</h2>
    $($AllResults.CAHealthStatus | ConvertTo-Html -Fragment)

    <h2>Certificate Revocation Lists (CRLs)</h2>
    $($AllResults.CRLs | ConvertTo-Html -Fragment)

    <h2>CA Security Permissions</h2>
    $($AllResults.SecurityPermissions | ConvertTo-Html -Fragment)

    <h2>Certificate Issuance Policies</h2>
    $($AllResults.IssuancePolicies | ConvertTo-Html -Fragment)

    <h2>Vulnerable Certificate Templates</h2>
    $($AllResults.VulnerableTemplates | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.CertificateAuthorities = Analyze-CertificateAuthorities }
        "2" { $allResults.CertificateTemplates = Review-CertificateTemplates }
        "3" { $allResults.CAHealthStatus = Check-CAHealthStatus }
        "4" { $allResults.CRLs = Analyze-CRLs }
        "5" { $allResults.SecurityPermissions = Review-CASecurityPermissions }
        "6" { $allResults.IssuancePolicies = Analyze-CertificateIssuancePolicies }
        "7" { $allResults.VulnerableTemplates = Check-VulnerableCertificateTemplates }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Active Directory Certificate Services Analyzer includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of AD CS:
    • Certificate Authorities analysis
    • Certificate Templates review
    • CA Health Status check
    • Certificate Revocation Lists (CRLs) analysis
    • CA Security Permissions review
    • Certificate Issuance Policies analysis
    • Vulnerable Certificate Templates check
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of CA configurations and health
  • Review of certificate templates and their settings
  • Analysis of CRL distribution points
  • Security permissions review for CAs
  • Identification of potentially vulnerable certificate templates
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • PKI administrators managing AD CS environments
  • Security auditors reviewing certificate services configurations
  • IT professionals troubleshooting PKI issues in an AD environment

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query AD CS in your domain
  3. Have the PSPKI PowerShell module installed (the script attempts to install it if not present)

This script provides a comprehensive overview of the AD CS configuration in an Active Directory environment, making it easier to identify issues, security concerns, or misconfigurations related to your PKI infrastructure. It can significantly streamline the process of auditing and maintaining AD CS in large or complex environments.