Active Directory Group Policy Analyzer

<#
.SYNOPSIS
Active Directory Group Policy Analyzer

.DESCRIPTION
This script analyzes Group Policy Objects (GPOs) in an Active Directory environment,
providing detailed information about policy settings, links, and potential issues.

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

.EXAMPLE
.\ADGroupPolicyAnalyzer.ps1
#>

# Import required modules
Import-Module GroupPolicy
Import-Module ActiveDirectory

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\GPO_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 Group Policy Analyzer ===" -ForegroundColor Cyan
    Write-Host "1. Analyze All GPOs"
    Write-Host "2. Find Unlinked GPOs"
    Write-Host "3. Identify GPOs with No Settings"
    Write-Host "4. Check for Conflicting GPO Settings"
    Write-Host "5. Analyze GPO Links"
    Write-Host "6. Review GPO Permissions"
    Write-Host "7. Check GPO Version Numbers"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes all GPOs in the domain.

.OUTPUTS
Array of PSObjects containing GPO details.
#>
function Analyze-AllGPOs {
    Write-Host "`nAnalyzing All GPOs..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $results = @()
    foreach ($gpo in $gpos) {
        $report = Get-GPOReport -Guid $gpo.Id -ReportType XML
        $settingsCount = ([xml]$report).GPO.Computer.ExtensionData.Extension.Policy.Count + 
                         ([xml]$report).GPO.User.ExtensionData.Extension.Policy.Count
        $results += [PSCustomObject]@{
            Name = $gpo.DisplayName
            ID = $gpo.Id
            CreationTime = $gpo.CreationTime
            ModificationTime = $gpo.ModificationTime
            SettingsCount = $settingsCount
            Status = $gpo.GpoStatus
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Finds unlinked GPOs in the domain.

.OUTPUTS
Array of PSObjects containing unlinked GPO details.
#>
function Find-UnlinkedGPOs {
    Write-Host "`nFinding Unlinked GPOs..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $unlinkedGPOs = @()
    foreach ($gpo in $gpos) {
        $linkedOUs = Get-ADOrganizationalUnit -Filter * | Where-Object {(Get-GPInheritance -Target $_.DistinguishedName).GpoLinks.DisplayName -contains $gpo.DisplayName}
        if ($linkedOUs.Count -eq 0) {
            $unlinkedGPOs += [PSCustomObject]@{
                Name = $gpo.DisplayName
                ID = $gpo.Id
                CreationTime = $gpo.CreationTime
            }
        }
    }
    $unlinkedGPOs | Format-Table -AutoSize
    return $unlinkedGPOs
}

<#
.SYNOPSIS
Identifies GPOs with no settings configured.

.OUTPUTS
Array of PSObjects containing empty GPO details.
#>
function Identify-EmptyGPOs {
    Write-Host "`nIdentifying GPOs with No Settings..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $emptyGPOs = @()
    foreach ($gpo in $gpos) {
        $report = Get-GPOReport -Guid $gpo.Id -ReportType XML
        $settingsCount = ([xml]$report).GPO.Computer.ExtensionData.Extension.Policy.Count + 
                         ([xml]$report).GPO.User.ExtensionData.Extension.Policy.Count
        if ($settingsCount -eq 0) {
            $emptyGPOs += [PSCustomObject]@{
                Name = $gpo.DisplayName
                ID = $gpo.Id
                CreationTime = $gpo.CreationTime
            }
        }
    }
    $emptyGPOs | Format-Table -AutoSize
    return $emptyGPOs
}

<#
.SYNOPSIS
Checks for potentially conflicting GPO settings.

.OUTPUTS
Array of PSObjects containing conflicting GPO details.
#>
function Check-ConflictingGPOSettings {
    Write-Host "`nChecking for Conflicting GPO Settings..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $conflictingSettings = @()
    $allSettings = @{}

    foreach ($gpo in $gpos) {
        $report = ([xml](Get-GPOReport -Guid $gpo.Id -ReportType XML))
        $settings = $report.GPO.Computer.ExtensionData.Extension.Policy + $report.GPO.User.ExtensionData.Extension.Policy
        
        foreach ($setting in $settings) {
            $key = "$($setting.Name):$($setting.Class)"
            if ($allSettings.ContainsKey($key)) {
                $conflictingSettings += [PSCustomObject]@{
                    SettingName = $setting.Name
                    GPO1 = $allSettings[$key]
                    GPO2 = $gpo.DisplayName
                }
            } else {
                $allSettings[$key] = $gpo.DisplayName
            }
        }
    }
    $conflictingSettings | Format-Table -AutoSize
    return $conflictingSettings
}

<#
.SYNOPSIS
Analyzes GPO links across the domain.

.OUTPUTS
Array of PSObjects containing GPO link details.
#>
function Analyze-GPOLinks {
    Write-Host "`nAnalyzing GPO Links..." -ForegroundColor Yellow
    $domain = Get-ADDomain
    $ous = Get-ADOrganizationalUnit -Filter *
    $gpoLinks = @()

    foreach ($ou in $ous) {
        $links = (Get-GPInheritance -Target $ou.DistinguishedName).GpoLinks
        foreach ($link in $links) {
            $gpoLinks += [PSCustomObject]@{
                GPOName = $link.DisplayName
                LinkedOU = $ou.Name
                Enabled = $link.Enabled
                Enforced = $link.Enforced
                Order = $link.Order
            }
        }
    }
    $gpoLinks | Format-Table -AutoSize
    return $gpoLinks
}

<#
.SYNOPSIS
Reviews GPO permissions.

.OUTPUTS
Array of PSObjects containing GPO permission details.
#>
function Review-GPOPermissions {
    Write-Host "`nReviewing GPO Permissions..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $gpoPermissions = @()

    foreach ($gpo in $gpos) {
        $permissions = Get-GPPermission -Guid $gpo.Id -All
        foreach ($perm in $permissions) {
            $gpoPermissions += [PSCustomObject]@{
                GPOName = $gpo.DisplayName
                Trustee = $perm.Trustee.Name
                Permission = $perm.Permission
            }
        }
    }
    $gpoPermissions | Format-Table -AutoSize
    return $gpoPermissions
}

<#
.SYNOPSIS
Checks GPO version numbers.

.OUTPUTS
Array of PSObjects containing GPO version details.
#>
function Check-GPOVersions {
    Write-Host "`nChecking GPO Version Numbers..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $gpoVersions = @()

    foreach ($gpo in $gpos) {
        $gpoVersions += [PSCustomObject]@{
            Name = $gpo.DisplayName
            ComputerVersion = $gpo.Computer.DSVersion
            UserVersion = $gpo.User.DSVersion
        }
    }
    $gpoVersions | Format-Table -AutoSize
    return $gpoVersions
}

<#
.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>Group Policy 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>Group Policy Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>All GPOs</h2>
    $($AllResults.AllGPOs | ConvertTo-Html -Fragment)

    <h2>Unlinked GPOs</h2>
    $($AllResults.UnlinkedGPOs | ConvertTo-Html -Fragment)

    <h2>Empty GPOs</h2>
    $($AllResults.EmptyGPOs | ConvertTo-Html -Fragment)

    <h2>Conflicting GPO Settings</h2>
    $($AllResults.ConflictingSettings | ConvertTo-Html -Fragment)

    <h2>GPO Links</h2>
    $($AllResults.GPOLinks | ConvertTo-Html -Fragment)

    <h2>GPO Permissions</h2>
    $($AllResults.GPOPermissions | ConvertTo-Html -Fragment)

    <h2>GPO Versions</h2>
    $($AllResults.GPOVersions | 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.AllGPOs = Analyze-AllGPOs }
        "2" { $allResults.UnlinkedGPOs = Find-UnlinkedGPOs }
        "3" { $allResults.EmptyGPOs = Identify-EmptyGPOs }
        "4" { $allResults.ConflictingSettings = Check-ConflictingGPOSettings }
        "5" { $allResults.GPOLinks = Analyze-GPOLinks }
        "6" { $allResults.GPOPermissions = Review-GPOPermissions }
        "7" { $allResults.GPOVersions = Check-GPOVersions }
        "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 Group Policy Analyzer includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of Group Policy Objects:
    • Overview of all GPOs
    • Identification of unlinked GPOs
    • Detection of GPOs with no settings
    • Analysis of potentially conflicting GPO settings
    • Review of GPO links across the domain
    • Examination of GPO permissions
    • Checking of GPO version numbers
  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 GPO configurations and links
  • Identification of potential issues like unlinked or empty GPOs
  • Detection of conflicting policy settings
  • Review of GPO permissions for security analysis
  • Version number checks to identify potential replication issues

This tool is particularly useful for:

  • Active Directory administrators managing complex GPO environments
  • IT auditors reviewing Group Policy configurations
  • System administrators troubleshooting Group Policy issues

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to query GPOs in your domain
  3. Have the GroupPolicy and ActiveDirectory PowerShell modules installed

This script provides a comprehensive overview of Group Policy configurations in an Active Directory environment, making it easier to identify issues, inconsistencies, or security concerns related to GPOs. It can significantly streamline the process of auditing and maintaining Group Policies in large or complex AD environments.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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