Comprehensive Logging Tool

<#
.SYNOPSIS
Comprehensive Logging Tool

.DESCRIPTION
This script provides functionality for creating, managing, and analyzing log files
in various formats. It includes features for creating logs, appending to existing logs,
searching logs, and performing basic log analysis.

.NOTES
File Name      : LoggingTool.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\LoggingTool.ps1
#>

# Global variables
$global:logPath = "$env:USERPROFILE\Desktop\Logs"
$global:currentLogFile = ""

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Comprehensive Logging Tool ===" -ForegroundColor Cyan
    Write-Host "Current Log File: $global:currentLogFile"
    Write-Host "1. Create New Log File"
    Write-Host "2. Append to Existing Log"
    Write-Host "3. View Log Content"
    Write-Host "4. Search Log"
    Write-Host "5. Analyze Log (Basic Statistics)"
    Write-Host "6. Export Log to CSV"
    Write-Host "7. Rotate Log File"
    Write-Host "8. Delete Log File"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Creates a new log file.
#>
function Create-NewLogFile {
    $logName = Read-Host "Enter the name for the new log file (without extension)"
    $logFormat = Read-Host "Enter log format (txt/json/xml)"
    
    $fileName = "$logName.$(Get-Date -Format 'yyyyMMdd').$logFormat"
    $global:currentLogFile = Join-Path $global:logPath $fileName

    if (!(Test-Path $global:logPath)) {
        New-Item -ItemType Directory -Path $global:logPath | Out-Null
    }

    switch ($logFormat) {
        "txt" { "" | Out-File -FilePath $global:currentLogFile }
        "json" { "[]" | Out-File -FilePath $global:currentLogFile }
        "xml" { '<?xml version="1.0" encoding="UTF-8"?><log></log>' | Out-File -FilePath $global:currentLogFile }
        default { Write-Host "Invalid format. Creating a txt file." -ForegroundColor Yellow; "" | Out-File -FilePath $global:currentLogFile }
    }

    Write-Host "Log file created: $global:currentLogFile" -ForegroundColor Green
}

<#
.SYNOPSIS
Appends an entry to the current log file.
#>
function Append-ToLog {
    if ([string]::IsNullOrEmpty($global:currentLogFile)) {
        Write-Host "No log file selected. Please create or select a log file first." -ForegroundColor Red
        return
    }

    $logEntry = Read-Host "Enter the log entry"
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

    $fileExtension = [System.IO.Path]::GetExtension($global:currentLogFile)
    switch ($fileExtension) {
        ".txt" { 
            "$timestamp - $logEntry" | Out-File -FilePath $global:currentLogFile -Append 
        }
        ".json" { 
            $jsonContent = Get-Content -Raw -Path $global:currentLogFile | ConvertFrom-Json
            $newEntry = @{
                "timestamp" = $timestamp
                "message" = $logEntry
            }
            $jsonContent += $newEntry
            $jsonContent | ConvertTo-Json | Set-Content -Path $global:currentLogFile
        }
        ".xml" { 
            [xml]$xmlContent = Get-Content -Path $global:currentLogFile
            $newEntry = $xmlContent.CreateElement("entry")
            $newEntry.SetAttribute("timestamp", $timestamp)
            $newEntry.InnerText = $logEntry
            $xmlContent.log.AppendChild($newEntry) | Out-Null
            $xmlContent.Save($global:currentLogFile)
        }
    }

    Write-Host "Log entry added successfully." -ForegroundColor Green
}

<#
.SYNOPSIS
Views the content of the current log file.
#>
function View-LogContent {
    if ([string]::IsNullOrEmpty($global:currentLogFile)) {
        Write-Host "No log file selected. Please create or select a log file first." -ForegroundColor Red
        return
    }

    Get-Content -Path $global:currentLogFile | Out-Host
    Read-Host "Press Enter to continue..."
}

<#
.SYNOPSIS
Searches the current log file for a specific term.
#>
function Search-Log {
    if ([string]::IsNullOrEmpty($global:currentLogFile)) {
        Write-Host "No log file selected. Please create or select a log file first." -ForegroundColor Red
        return
    }

    $searchTerm = Read-Host "Enter the search term"
    $results = Get-Content -Path $global:currentLogFile | Select-String -Pattern $searchTerm

    if ($results) {
        Write-Host "Search Results:" -ForegroundColor Yellow
        $results | ForEach-Object { Write-Host $_ }
    } else {
        Write-Host "No matches found." -ForegroundColor Yellow
    }

    Read-Host "Press Enter to continue..."
}

<#
.SYNOPSIS
Performs basic analysis on the current log file.
#>
function Analyze-Log {
    if ([string]::IsNullOrEmpty($global:currentLogFile)) {
        Write-Host "No log file selected. Please create or select a log file first." -ForegroundColor Red
        return
    }

    $content = Get-Content -Path $global:currentLogFile
    $totalEntries = $content.Count
    $uniqueEntries = ($content | Select-Object -Unique).Count
    $firstEntry = $content | Select-Object -First 1
    $lastEntry = $content | Select-Object -Last 1

    Write-Host "Log Analysis:" -ForegroundColor Yellow
    Write-Host "Total Entries: $totalEntries"
    Write-Host "Unique Entries: $uniqueEntries"
    Write-Host "First Entry: $firstEntry"
    Write-Host "Last Entry: $lastEntry"

    Read-Host "Press Enter to continue..."
}

<#
.SYNOPSIS
Exports the current log file to CSV format.
#>
function Export-LogToCSV {
    if ([string]::IsNullOrEmpty($global:currentLogFile)) {
        Write-Host "No log file selected. Please create or select a log file first." -ForegroundColor Red
        return
    }

    $csvPath = [System.IO.Path]::ChangeExtension($global:currentLogFile, "csv")
    $content = Get-Content -Path $global:currentLogFile

    $csvData = $content | ForEach-Object {
        if ($_ -match "^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) - (.*)$") {
            [PSCustomObject]@{
                Timestamp = $matches[1]
                Message = $matches[2]
            }
        }
    }

    $csvData | Export-Csv -Path $csvPath -NoTypeInformation
    Write-Host "Log exported to CSV: $csvPath" -ForegroundColor Green
}

<#
.SYNOPSIS
Rotates the current log file.
#>
function Rotate-LogFile {
    if ([string]::IsNullOrEmpty($global:currentLogFile)) {
        Write-Host "No log file selected. Please create or select a log file first." -ForegroundColor Red
        return
    }

    $directory = [System.IO.Path]::GetDirectoryName($global:currentLogFile)
    $fileName = [System.IO.Path]::GetFileNameWithoutExtension($global:currentLogFile)
    $extension = [System.IO.Path]::GetExtension($global:currentLogFile)

    $newFileName = "{0}_{1}{2}" -f $fileName, (Get-Date -Format "yyyyMMddHHmmss"), $extension
    $newFilePath = Join-Path $directory $newFileName

    Move-Item -Path $global:currentLogFile -Destination $newFilePath
    Write-Host "Log file rotated. New file: $newFilePath" -ForegroundColor Green

    # Create a new empty log file
    "" | Out-File -FilePath $global:currentLogFile
    Write-Host "New empty log file created: $global:currentLogFile" -ForegroundColor Green
}

<#
.SYNOPSIS
Deletes the current log file.
#>
function Delete-LogFile {
    if ([string]::IsNullOrEmpty($global:currentLogFile)) {
        Write-Host "No log file selected. Please create or select a log file first." -ForegroundColor Red
        return
    }

    $confirmation = Read-Host "Are you sure you want to delete the current log file? (Y/N)"
    if ($confirmation -eq "Y") {
        Remove-Item -Path $global:currentLogFile -Force
        Write-Host "Log file deleted: $global:currentLogFile" -ForegroundColor Green
        $global:currentLogFile = ""
    } else {
        Write-Host "Deletion cancelled." -ForegroundColor Yellow
    }
}

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

    switch ($choice) {
        "1" { Create-NewLogFile }
        "2" { Append-ToLog }
        "3" { View-LogContent }
        "4" { Search-Log }
        "5" { Analyze-Log }
        "6" { Export-LogToCSV }
        "7" { Rotate-LogFile }
        "8" { Delete-LogFile }
        "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 Comprehensive Logging Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to manage and analyze log files:
    • Creating new log files in various formats (txt, json, xml)
    • Appending entries to existing logs
    • Viewing log content
    • Searching logs for specific terms
    • Performing basic log analysis
    • Exporting logs to CSV format
    • Rotating log files
    • Deleting log files
  3. Support for different log formats (txt, json, xml)
  4. Error handling and user confirmations for critical operations

Key features:

  • Flexible log creation in multiple formats
  • Easy log entry addition with automatic timestamps
  • Search functionality for quick information retrieval
  • Basic log analysis for insights
  • Log rotation for managing file sizes
  • CSV export for further analysis in spreadsheet applications
  • Safe log file deletion with user confirmation

This tool is particularly useful for:

  • Developers needing to implement logging in their applications
  • System administrators managing log files
  • IT professionals troubleshooting issues using logs
  • Anyone needing to create, manage, or analyze log files

To use this script effectively:

  1. Run PowerShell with appropriate permissions to create and modify files in the specified log directory
  2. Ensure you have write access to the desktop or modify the $global:logPath variable to a suitable location
  3. Be cautious when deleting log files, as this operation is irreversible

This script provides a comprehensive set of features for log management and analysis, making it easier to maintain, search, and gain insights from log files in various formats.

Dr. Scripto and the Template of Destiny

It was a crisp autumn morning at the PowerShell Academy. The leaves were turning golden, and there was a hint of pumpkin spice in the air. Dr. Scripto, the renowned PowerShell wizard, was preparing for his most ambitious class yet: “Advanced Script Templating for Enterprise Automation.”

As he adjusted his PowerShell-themed bowtie in the mirror, Dr. Scripto couldn’t help but feel a mix of excitement and trepidation. He had spent months perfecting what he called the “Template of Destiny” – a PowerShell script template so versatile and powerful that it could potentially automate any task in any environment.

The classroom was buzzing with anticipation as students filed in. They had heard rumors about this legendary template and were eager to see it in action.

“Good morning, class!” Dr. Scripto beamed, his mustache twitching with excitement. “Today, we embark on a journey that will revolutionize the way we approach PowerShell scripting!”

He dramatically unveiled a massive whiteboard covered with intricate PowerShell code. The students gasped in awe.

“Behold,” Dr. Scripto announced, “the Template of Destiny!”

He began to explain each section of the template, from the comprehensive comment-based help to the error handling and logging mechanisms. The students were captivated, furiously taking notes and asking insightful questions.

Just as Dr. Scripto was about to demonstrate the template’s adaptability, the classroom door burst open. In stumbled Ernie, the academy’s notoriously clumsy IT intern.

“Dr. Scripto!” Ernie panted, “We have an emergency! The entire academy’s infrastructure is down. Nothing’s working!”

The class fell silent. Dr. Scripto stroked his beard thoughtfully. “Well, class,” he said with a twinkle in his eye, “it seems we have the perfect opportunity to test our Template of Destiny in a real-world scenario!”

The students cheered as Dr. Scripto led them to the server room. The place was in chaos, with blinking lights and beeping alarms everywhere.

“Now,” Dr. Scripto announced, “let’s adapt our template to diagnose and fix the issue!”

He quickly began modifying the template, explaining each change as he went:

$TargetSystem = "AcademyInfrastructure"
$LogPath = "C:\Logs\AcademyEmergency.log"

function Invoke-PreflightChecks {
    Write-Log "Checking network connectivity"
    Test-NetConnection -ComputerName $TargetSystem
}

function Invoke-MainOperation {
    Write-Log "Diagnosing issues"
    $services = Get-Service | Where-Object {$_.Status -ne 'Running'}
    foreach ($service in $services) {
        Write-Log "Attempting to start $($service.Name)"
        Start-Service $service.Name
    }
    
    Write-Log "Checking disk space"
    Get-WmiObject Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3} |
        ForEach-Object {
            if(($_.FreeSpace / $_.Size) -lt 0.1) {
                Write-Log "Low disk space on $($_.DeviceID)"
                # Add disk cleanup logic here
            }
        }
}

function Invoke-Cleanup {
    Write-Log "Restarting critical services"
    Restart-Service -Name "DHCP", "DNS", "IIS" -Force
}

As Dr. Scripto ran the modified script, the students watched in amazement. Services started coming back online, disk space issues were identified and resolved, and slowly but surely, the chaos in the server room began to subside.

“You see, class,” Dr. Scripto said proudly, “with a well-designed template, we can quickly adapt to any situation. The Template of Destiny isn’t just a script; it’s a framework for problem-solving!”

Just then, the academy’s headmistress walked in. “Dr. Scripto,” she said, looking around the now-calm server room, “I don’t know how you did it, but you’ve saved the academy. Thank you!”

Dr. Scripto blushed modestly. “It wasn’t just me,” he said, gesturing to his students. “It was the power of PowerShell and a well-crafted template.”

As they walked back to the classroom, the students chattered excitedly about what they had just witnessed. They had seen firsthand how a flexible, robust template could be adapted to solve real-world problems in minutes.

Back in the classroom, Dr. Scripto turned to his students with a smile. “Now, who’s ready to create their own Template of Destiny?”

The rest of the semester flew by in a flurry of PowerShell scripting. Students created templates for everything from user management to complex cloud deployments. The Template of Destiny had sparked a revolution in how they approached scripting.

On the last day of class, Dr. Scripto looked at his students with pride. “Remember,” he said, his eyes twinkling, “a good template is like a Swiss Army knife for PowerShell. It may not be flashy, but with the right modifications, it can solve almost any problem you encounter.”

As the students filed out, ready to take on the world with their newfound skills, Dr. Scripto sat back in his chair, twirling his PowerShell-themed pen. He couldn’t help but smile, knowing that he had equipped a new generation of IT professionals with the tools they needed to succeed.

“PowerShell and templates,” he mused to himself, “truly a combination worthy of destiny.”

And with that, Dr. Scripto began planning his next class, already dreaming up new ways to push the boundaries of what PowerShell could do. For in the world of IT, there was always a new challenge waiting, and with PowerShell and a good template, Dr. Scripto knew he and his students would always be ready to face it.

PowerShell Tester Tool Template

<#
.SYNOPSIS
PowerShell Tester Tool Template

.DESCRIPTION
This script provides a template for a PowerShell-based tester tool that can be customized
for various testing scenarios. It includes functions for defining tests, running them,
and generating reports.

.NOTES
File Name      : TesterToolTemplate.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\TesterToolTemplate.ps1
#>

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

<#
.SYNOPSIS
Displays the main menu of the tester tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== PowerShell Tester Tool ===" -ForegroundColor Cyan
    Write-Host "1. Run All Tests"
    Write-Host "2. Run Specific Test"
    Write-Host "3. View Test Results"
    Write-Host "4. Generate HTML Report"
    Write-Host "5. Exit"
}

<#
.SYNOPSIS
Defines the test cases. Add your test functions here.
#>
function Define-Tests {
    $global:tests = @{
        "Test1" = { Test-Case1 }
        "Test2" = { Test-Case2 }
        "Test3" = { Test-Case3 }
        # Add more test cases as needed
    }
}

<#
.SYNOPSIS
Example test case 1. Replace with your actual test logic.
#>
function Test-Case1 {
    $testName = "Test Case 1"
    $description = "Description of Test Case 1"
    try {
        # Your test logic here
        $result = $true
        $message = "Test Case 1 passed successfully"
    }
    catch {
        $result = $false
        $message = "Test Case 1 failed: $_"
    }
    return [PSCustomObject]@{
        TestName = $testName
        Description = $description
        Result = $result
        Message = $message
    }
}

<#
.SYNOPSIS
Example test case 2. Replace with your actual test logic.
#>
function Test-Case2 {
    $testName = "Test Case 2"
    $description = "Description of Test Case 2"
    try {
        # Your test logic here
        $result = $true
        $message = "Test Case 2 passed successfully"
    }
    catch {
        $result = $false
        $message = "Test Case 2 failed: $_"
    }
    return [PSCustomObject]@{
        TestName = $testName
        Description = $description
        Result = $result
        Message = $message
    }
}

<#
.SYNOPSIS
Example test case 3. Replace with your actual test logic.
#>
function Test-Case3 {
    $testName = "Test Case 3"
    $description = "Description of Test Case 3"
    try {
        # Your test logic here
        $result = $true
        $message = "Test Case 3 passed successfully"
    }
    catch {
        $result = $false
        $message = "Test Case 3 failed: $_"
    }
    return [PSCustomObject]@{
        TestName = $testName
        Description = $description
        Result = $result
        Message = $message
    }
}

<#
.SYNOPSIS
Runs all defined tests.
#>
function Run-AllTests {
    Write-Host "`nRunning All Tests..." -ForegroundColor Yellow
    $global:testResults = @()
    foreach ($test in $global:tests.GetEnumerator()) {
        Write-Host "Running $($test.Key)..." -ForegroundColor Cyan
        $result = & $test.Value
        $global:testResults += $result
        if ($result.Result) {
            Write-Host "  Passed: $($result.Message)" -ForegroundColor Green
        } else {
            Write-Host "  Failed: $($result.Message)" -ForegroundColor Red
        }
    }
}

<#
.SYNOPSIS
Runs a specific test based on user input.
#>
function Run-SpecificTest {
    Write-Host "`nAvailable Tests:" -ForegroundColor Yellow
    $global:tests.Keys | ForEach-Object { Write-Host "  $_" }
    $testName = Read-Host "`nEnter the name of the test to run"
    if ($global:tests.ContainsKey($testName)) {
        Write-Host "Running $testName..." -ForegroundColor Cyan
        $result = & $global:tests[$testName]
        $global:testResults += $result
        if ($result.Result) {
            Write-Host "  Passed: $($result.Message)" -ForegroundColor Green
        } else {
            Write-Host "  Failed: $($result.Message)" -ForegroundColor Red
        }
    } else {
        Write-Host "Test not found." -ForegroundColor Red
    }
}

<#
.SYNOPSIS
Displays the results of all run tests.
#>
function View-TestResults {
    if ($global:testResults.Count -eq 0) {
        Write-Host "`nNo tests have been run yet." -ForegroundColor Yellow
    } else {
        Write-Host "`nTest Results:" -ForegroundColor Yellow
        $global:testResults | Format-Table -AutoSize
    }
}

<#
.SYNOPSIS
Generates an HTML report of the test results.
#>
function Generate-HTMLReport {
    Write-Host "`nGenerating 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>Test Results Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }
        h1 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-top: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .pass { color: green; }
        .fail { color: red; }
    </style>
</head>
<body>
    <h1>Test Results Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <table>
        <tr>
            <th>Test Name</th>
            <th>Description</th>
            <th>Result</th>
            <th>Message</th>
        </tr>
        $(foreach ($result in $global:testResults) {
            $resultClass = if ($result.Result) { "pass" } else { "fail" }
            "<tr>
                <td>$($result.TestName)</td>
                <td>$($result.Description)</td>
                <td class='$resultClass'>$(if ($result.Result) { "Pass" } else { "Fail" })</td>
                <td>$($result.Message)</td>
            </tr>"
        })
    </table>
</body>
</html>
"@

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

# Main program loop
Define-Tests
do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-5)"

    switch ($choice) {
        "1" { Run-AllTests }
        "2" { Run-SpecificTest }
        "3" { View-TestResults }
        "4" { Generate-HTMLReport }
        "5" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This PowerShell Tester Tool Template includes:

  1. A menu-driven interface for easy navigation.
  2. Functions for defining and running tests.
  3. Placeholder test case functions that you can replace with your actual test logic.
  4. Ability to run all tests or a specific test.
  5. Function to view test results.
  6. HTML report generation for test results.

Key features:

  • Flexible structure for defining multiple test cases
  • Easy-to-use menu for running tests and viewing results
  • Detailed test result tracking, including test name, description, result, and message
  • HTML report generation for easy sharing and documentation of test results
  • Modular design for easy expansion and modification

To use this template effectively:

  1. Replace the placeholder test case functions (Test-Case1, Test-Case2, Test-Case3) with your specific test logic.
  2. Add more test cases as needed in the Define-Tests function.
  3. Customize the test result object properties if you need to capture additional information.
  4. Modify the HTML report generation function if you want to change the report format or add more details.
  5. Add any necessary module imports or additional global variables at the beginning of the script.

This template provides a solid foundation for creating various types of testing tools in PowerShell, whether you’re testing system configurations, application functionality, or any other scenario that requires structured testing and reporting.

Template Menu-Driven PowerShell Tool

<#
.SYNOPSIS
Template Menu-Driven PowerShell Tool

.DESCRIPTION
This script provides a template for a menu-driven PowerShell tool that can be customized
for various administrative or analysis tasks.

.NOTES
File Name      : TemplateMenuTool.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\TemplateMenuTool.ps1
#>

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Template Menu-Driven Tool ===" -ForegroundColor Cyan
    Write-Host "1. Set Target (e.g., computer, path, etc.)"
    Write-Host "2. Perform Analysis Task 1"
    Write-Host "3. Perform Analysis Task 2"
    Write-Host "4. Perform Analysis Task 3"
    Write-Host "5. Perform Analysis Task 4"
    Write-Host "6. Perform Analysis Task 5"
    Write-Host "7. Generate Comprehensive HTML Report"
    Write-Host "8. Exit"
}

<#
.SYNOPSIS
Sets the target for analysis (e.g., computer name, file path, etc.).
#>
function Set-Target {
    $target = Read-Host "Enter the target for analysis (e.g., computer name, file path)"
    if (-not [string]::IsNullOrWhiteSpace($target)) {
        $global:target = $target
        Write-Host "Target set to: $global:target" -ForegroundColor Green
    } else {
        Write-Host "Invalid target. Please try again." -ForegroundColor Red
    }
}

<#
.SYNOPSIS
Performs Analysis Task 1.

.OUTPUTS
Array of PSObjects containing analysis results.
#>
function Perform-AnalysisTask1 {
    Write-Host "`nPerforming Analysis Task 1..." -ForegroundColor Yellow
    # Add your analysis logic here
    $results = @([PSCustomObject]@{
        Property1 = "Value1"
        Property2 = "Value2"
    })
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Performs Analysis Task 2.

.OUTPUTS
Array of PSObjects containing analysis results.
#>
function Perform-AnalysisTask2 {
    Write-Host "`nPerforming Analysis Task 2..." -ForegroundColor Yellow
    # Add your analysis logic here
    $results = @([PSCustomObject]@{
        Property1 = "Value1"
        Property2 = "Value2"
    })
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Performs Analysis Task 3.

.OUTPUTS
Array of PSObjects containing analysis results.
#>
function Perform-AnalysisTask3 {
    Write-Host "`nPerforming Analysis Task 3..." -ForegroundColor Yellow
    # Add your analysis logic here
    $results = @([PSCustomObject]@{
        Property1 = "Value1"
        Property2 = "Value2"
    })
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Performs Analysis Task 4.

.OUTPUTS
Array of PSObjects containing analysis results.
#>
function Perform-AnalysisTask4 {
    Write-Host "`nPerforming Analysis Task 4..." -ForegroundColor Yellow
    # Add your analysis logic here
    $results = @([PSCustomObject]@{
        Property1 = "Value1"
        Property2 = "Value2"
    })
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Performs Analysis Task 5.

.OUTPUTS
Array of PSObjects containing analysis results.
#>
function Perform-AnalysisTask5 {
    Write-Host "`nPerforming Analysis Task 5..." -ForegroundColor Yellow
    # Add your analysis logic here
    $results = @([PSCustomObject]@{
        Property1 = "Value1"
        Property2 = "Value2"
    })
    $results | Format-Table -AutoSize
    return $results
}

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

    <h2>Analysis Task 1 Results</h2>
    $($AllResults.Task1Results | ConvertTo-Html -Fragment)

    <h2>Analysis Task 2 Results</h2>
    $($AllResults.Task2Results | ConvertTo-Html -Fragment)

    <h2>Analysis Task 3 Results</h2>
    $($AllResults.Task3Results | ConvertTo-Html -Fragment)

    <h2>Analysis Task 4 Results</h2>
    $($AllResults.Task4Results | ConvertTo-Html -Fragment)

    <h2>Analysis Task 5 Results</h2>
    $($AllResults.Task5Results | 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" { Set-Target }
        "2" { $allResults.Task1Results = Perform-AnalysisTask1 }
        "3" { $allResults.Task2Results = Perform-AnalysisTask2 }
        "4" { $allResults.Task3Results = Perform-AnalysisTask3 }
        "5" { $allResults.Task4Results = Perform-AnalysisTask4 }
        "6" { $allResults.Task5Results = Perform-AnalysisTask5 }
        "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 Template Menu-Driven Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Placeholder functions for five different analysis tasks.
  3. A function to set a target for analysis (which can be customized based on your needs).
  4. A function to generate an HTML report of all collected data.
  5. Basic error handling and user input validation.

Key features:

  • Easy-to-customize menu structure
  • Placeholder functions for various analysis tasks
  • Ability to set and use a global target variable
  • HTML report generation capability
  • Modular design for easy expansion and modification

To use this template effectively:

  1. Replace the placeholder analysis functions (Perform-AnalysisTask1, Perform-AnalysisTask2, etc.) with your specific analysis logic.
  2. Customize the Set-Target function to handle the type of target you need (e.g., computer name, file path, etc.).
  3. Modify the menu options and corresponding switch statement in the main program loop to match your specific tasks.
  4. Adjust the HTML report generation function to include the specific results you want to display.
  5. Add any necessary module imports or additional global variables at the beginning of the script.

This template provides a solid foundation for creating various types of menu-driven PowerShell tools for system administration, security analysis, or any other task that requires user interaction and multiple analysis steps.

Certificates Analyzer Tool

<#
.SYNOPSIS
Certificates Analyzer Tool

.DESCRIPTION
This script analyzes and audits certificates on a Windows system, including those in the
certificate store and those used by IIS. It provides insights into certificate expiration,
usage, and potential issues.

.NOTES
File Name      : CertificatesAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights, and IIS if analyzing IIS certificates
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\CertificatesAnalyzer.ps1
#>

# Import required modules
Import-Module WebAdministration -ErrorAction SilentlyContinue

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Certificates Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze All Certificates in Local Machine Store"
    Write-Host "2. Check for Expiring Certificates"
    Write-Host "3. Analyze IIS Binding Certificates"
    Write-Host "4. Check for Weak Key Certificates"
    Write-Host "5. Analyze Certificate Chain"
    Write-Host "6. Check for Duplicate Certificates"
    Write-Host "7. Analyze Certificate Usage"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes all certificates in the Local Machine store.

.OUTPUTS
Array of PSObjects containing certificate details.
#>
function Analyze-AllCertificates {
    Write-Host "`nAnalyzing All Certificates in Local Machine Store..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Issuer = $cert.Issuer
            Thumbprint = $cert.Thumbprint
            NotBefore = $cert.NotBefore
            NotAfter = $cert.NotAfter
            Store = $cert.PSParentPath.Split('\')[-1]
            HasPrivateKey = $cert.HasPrivateKey
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for expiring certificates.

.OUTPUTS
Array of PSObjects containing expiring certificate details.
#>
function Check-ExpiringCertificates {
    Write-Host "`nChecking for Expiring Certificates..." -ForegroundColor Yellow
    $expirationThreshold = (Get-Date).AddDays(30)
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false -and $_.NotAfter -le $expirationThreshold }
    $results = @()
    foreach ($cert in $certs) {
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Thumbprint = $cert.Thumbprint
            ExpirationDate = $cert.NotAfter
            DaysUntilExpiration = ($cert.NotAfter - (Get-Date)).Days
            Store = $cert.PSParentPath.Split('\')[-1]
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes IIS binding certificates.

.OUTPUTS
Array of PSObjects containing IIS binding certificate details.
#>
function Analyze-IISBindingCertificates {
    Write-Host "`nAnalyzing IIS Binding Certificates..." -ForegroundColor Yellow
    $results = @()
    if (Get-Module -ListAvailable -Name WebAdministration) {
        $websites = Get-Website
        foreach ($site in $websites) {
            $bindings = $site.Bindings.Collection | Where-Object { $_.Protocol -eq "https" }
            foreach ($binding in $bindings) {
                $cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq $binding.CertificateHash }
                if ($cert) {
                    $results += [PSCustomObject]@{
                        Website = $site.Name
                        Binding = $binding.BindingInformation
                        CertSubject = $cert.Subject
                        Thumbprint = $cert.Thumbprint
                        ExpirationDate = $cert.NotAfter
                        DaysUntilExpiration = ($cert.NotAfter - (Get-Date)).Days
                    }
                }
            }
        }
    } else {
        Write-Host "WebAdministration module not available. Unable to analyze IIS bindings." -ForegroundColor Red
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for certificates with weak keys.

.OUTPUTS
Array of PSObjects containing weak key certificate details.
#>
function Check-WeakKeyCertificates {
    Write-Host "`nChecking for Weak Key Certificates..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        if ($cert.PublicKey.Key.KeySize -lt 2048) {
            $results += [PSCustomObject]@{
                Subject = $cert.Subject
                Thumbprint = $cert.Thumbprint
                KeySize = $cert.PublicKey.Key.KeySize
                Store = $cert.PSParentPath.Split('\')[-1]
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes certificate chains.

.OUTPUTS
Array of PSObjects containing certificate chain details.
#>
function Analyze-CertificateChain {
    Write-Host "`nAnalyzing Certificate Chain..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        $chain = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Chain
        $chain.Build($cert) | Out-Null
        $chainStatus = $chain.ChainStatus | ForEach-Object { $_.Status }
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Thumbprint = $cert.Thumbprint
            ChainValid = $chain.ChainStatus.Length -eq 0
            ChainStatus = if ($chainStatus) { $chainStatus -join ", " } else { "Valid" }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks for duplicate certificates.

.OUTPUTS
Array of PSObjects containing duplicate certificate details.
#>
function Check-DuplicateCertificates {
    Write-Host "`nChecking for Duplicate Certificates..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $duplicates = $certs | Group-Object -Property Thumbprint | Where-Object { $_.Count -gt 1 }
    $results = @()
    foreach ($duplicate in $duplicates) {
        foreach ($cert in $duplicate.Group) {
            $results += [PSCustomObject]@{
                Subject = $cert.Subject
                Thumbprint = $cert.Thumbprint
                Store = $cert.PSParentPath.Split('\')[-1]
                NotAfter = $cert.NotAfter
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes certificate usage.

.OUTPUTS
Array of PSObjects containing certificate usage details.
#>
function Analyze-CertificateUsage {
    Write-Host "`nAnalyzing Certificate Usage..." -ForegroundColor Yellow
    $certs = Get-ChildItem -Path Cert:\LocalMachine -Recurse | Where-Object { $_.PSIsContainer -eq $false }
    $results = @()
    foreach ($cert in $certs) {
        $enhancedKeyUsage = $cert.EnhancedKeyUsageList | ForEach-Object { $_.FriendlyName }
        $results += [PSCustomObject]@{
            Subject = $cert.Subject
            Thumbprint = $cert.Thumbprint
            KeyUsage = $cert.KeyUsages -join ", "
            EnhancedKeyUsage = if ($enhancedKeyUsage) { $enhancedKeyUsage -join ", " } else { "Not specified" }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

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

    <h2>All Certificates</h2>
    $($AllResults.AllCertificates | ConvertTo-Html -Fragment)

    <h2>Expiring Certificates</h2>
    $($AllResults.ExpiringCertificates | ConvertTo-Html -Fragment)

    <h2>IIS Binding Certificates</h2>
    $($AllResults.IISBindingCertificates | ConvertTo-Html -Fragment)

    <h2>Weak Key Certificates</h2>
    $($AllResults.WeakKeyCertificates | ConvertTo-Html -Fragment)

    <h2>Certificate Chain Analysis</h2>
    $($AllResults.CertificateChain | ConvertTo-Html -Fragment)

    <h2>Duplicate Certificates</h2>
    $($AllResults.DuplicateCertificates | ConvertTo-Html -Fragment)

    <h2>Certificate Usage</h2>
    $($AllResults.CertificateUsage | 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.AllCertificates = Analyze-AllCertificates }
        "2" { $allResults.ExpiringCertificates = Check-ExpiringCertificates }
        "3" { $allResults.IISBindingCertificates = Analyze-IISBindingCertificates }
        "4" { $allResults.WeakKeyCertificates = Check-WeakKeyCertificates }
        "5" { $allResults.CertificateChain = Analyze-CertificateChain }
        "6" { $allResults.DuplicateCertificates = Check-DuplicateCertificates }
        "7" { $allResults.CertificateUsage = Analyze-CertificateUsage }
        "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 Certificates Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of certificates:
    • Analysis of all certificates in the Local Machine store
    • Check for expiring certificates
    • Analysis of IIS binding certificates
    • Check for weak key certificates
    • Analysis of certificate chains
    • Check for duplicate certificates
    • Analysis of certificate usage
  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 all certificates in the Local Machine store
  • Identification of certificates nearing expiration
  • Review of certificates used in IIS bindings
  • Detection of certificates with weak keys
  • Analysis of certificate chains for validity
  • Identification of duplicate certificates across stores
  • Examination of certificate usage and purposes
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • System administrators managing certificates
  • Security professionals auditing certificate deployments
  • IT professionals troubleshooting certificate-related issues
  • DevOps engineers managing SSL/TLS certificates

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions to access certificate stores
  3. Have the WebAdministration module available if you want to analyze IIS certificates

This script provides a comprehensive overview of certificates on a Windows system, making it easier to audit and maintain certificate deployments, identify potential issues, and ensure the security of SSL/TLS implementations.

IIS (Internet Information Services) Analyzer Tool

<#
.SYNOPSIS
IIS (Internet Information Services) Analyzer Tool

.DESCRIPTION
This script analyzes and audits IIS configurations, including websites, application pools,
bindings, SSL certificates, and other related settings on Windows Servers.

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

.EXAMPLE
.\IISAnalyzer.ps1
#>

# Check if WebAdministration module is available
if (-not (Get-Module -ListAvailable -Name WebAdministration)) {
    Write-Host "WebAdministration module not found. Please ensure IIS is installed with management tools." -ForegroundColor Red
    exit
}

# Import required module
Import-Module WebAdministration

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== IIS Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze Websites"
    Write-Host "2. Review Application Pools"
    Write-Host "3. Analyze Bindings and SSL Certificates"
    Write-Host "4. Check Virtual Directories"
    Write-Host "5. Review HTTP Response Headers"
    Write-Host "6. Analyze Authentication Settings"
    Write-Host "7. Check Logging Configuration"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes IIS Websites.

.OUTPUTS
Array of PSObjects containing Website details.
#>
function Analyze-Websites {
    Write-Host "`nAnalyzing Websites..." -ForegroundColor Yellow
    $websites = Get-Website
    $results = @()
    foreach ($site in $websites) {
        $results += [PSCustomObject]@{
            Name = $site.Name
            ID = $site.ID
            State = $site.State
            PhysicalPath = $site.PhysicalPath
            ApplicationPool = $site.ApplicationPool
            Bindings = ($site.Bindings.Collection | ForEach-Object { "$($_.Protocol)/$($_.BindingInformation)" }) -join ", "
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Reviews Application Pools.

.OUTPUTS
Array of PSObjects containing Application Pool details.
#>
function Review-ApplicationPools {
    Write-Host "`nReviewing Application Pools..." -ForegroundColor Yellow
    $appPools = Get-IISAppPool
    $results = @()
    foreach ($pool in $appPools) {
        $results += [PSCustomObject]@{
            Name = $pool.Name
            State = $pool.State
            ManagedRuntimeVersion = $pool.ManagedRuntimeVersion
            ManagedPipelineMode = $pool.ManagedPipelineMode
            StartMode = $pool.StartMode
            IdentityType = $pool.ProcessModel.IdentityType
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes Bindings and SSL Certificates.

.OUTPUTS
Array of PSObjects containing Binding and SSL Certificate details.
#>
function Analyze-BindingsAndSSL {
    Write-Host "`nAnalyzing Bindings and SSL Certificates..." -ForegroundColor Yellow
    $websites = Get-Website
    $results = @()
    foreach ($site in $websites) {
        foreach ($binding in $site.Bindings.Collection) {
            $cert = $null
            if ($binding.Protocol -eq "https") {
                $cert = Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object {$_.Thumbprint -eq $binding.CertificateHash}
            }
            $results += [PSCustomObject]@{
                Website = $site.Name
                Protocol = $binding.Protocol
                BindingInfo = $binding.BindingInformation
                SSLThumbprint = if ($cert) { $cert.Thumbprint } else { "N/A" }
                SSLExpirationDate = if ($cert) { $cert.NotAfter } else { "N/A" }
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks Virtual Directories.

.OUTPUTS
Array of PSObjects containing Virtual Directory details.
#>
function Check-VirtualDirectories {
    Write-Host "`nChecking Virtual Directories..." -ForegroundColor Yellow
    $vdirs = Get-WebVirtualDirectory
    $results = @()
    foreach ($vdir in $vdirs) {
        $results += [PSCustomObject]@{
            Name = $vdir.Name
            PhysicalPath = $vdir.PhysicalPath
            Application = $vdir.Application
            Website = $vdir.Website
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Reviews HTTP Response Headers.

.OUTPUTS
Array of PSObjects containing HTTP Response Header details.
#>
function Review-HTTPResponseHeaders {
    Write-Host "`nReviewing HTTP Response Headers..." -ForegroundColor Yellow
    $websites = Get-Website
    $results = @()
    foreach ($site in $websites) {
        $headers = Get-WebConfigurationProperty -Filter "system.webServer/httpProtocol/customHeaders" -PSPath "IIS:\Sites\$($site.Name)" -Name "."
        foreach ($header in $headers.Collection) {
            $results += [PSCustomObject]@{
                Website = $site.Name
                HeaderName = $header.Name
                HeaderValue = $header.Value
            }
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes Authentication Settings.

.OUTPUTS
Array of PSObjects containing Authentication Setting details.
#>
function Analyze-AuthenticationSettings {
    Write-Host "`nAnalyzing Authentication Settings..." -ForegroundColor Yellow
    $websites = Get-Website
    $results = @()
    foreach ($site in $websites) {
        $authTypes = @("Anonymous", "Basic", "Windows", "Digest")
        $authSettings = @{}
        foreach ($authType in $authTypes) {
            $authSettings[$authType] = (Get-WebConfigurationProperty -Filter "system.webServer/security/authentication/$authType`Authentication" -PSPath "IIS:\Sites\$($site.Name)" -Name "enabled").Value
        }
        $results += [PSCustomObject]@{
            Website = $site.Name
            AnonymousAuth = $authSettings["Anonymous"]
            BasicAuth = $authSettings["Basic"]
            WindowsAuth = $authSettings["Windows"]
            DigestAuth = $authSettings["Digest"]
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks Logging Configuration.

.OUTPUTS
Array of PSObjects containing Logging Configuration details.
#>
function Check-LoggingConfiguration {
    Write-Host "`nChecking Logging Configuration..." -ForegroundColor Yellow
    $websites = Get-Website
    $results = @()
    foreach ($site in $websites) {
        $logFile = Get-WebConfigurationProperty -Filter "system.applicationHost/sites/site[@name='$($site.Name)']/logFile" -PSPath "MACHINE/WEBROOT/APPHOST" -Name "."
        $results += [PSCustomObject]@{
            Website = $site.Name
            LogFormat = $logFile.logFormat
            Directory = $logFile.directory
            Enabled = $logFile.enabled
            Period = $logFile.period
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

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

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

    <h2>Application Pools</h2>
    $($AllResults.ApplicationPools | ConvertTo-Html -Fragment)

    <h2>Bindings and SSL Certificates</h2>
    $($AllResults.BindingsAndSSL | ConvertTo-Html -Fragment)

    <h2>Virtual Directories</h2>
    $($AllResults.VirtualDirectories | ConvertTo-Html -Fragment)

    <h2>HTTP Response Headers</h2>
    $($AllResults.HTTPResponseHeaders | ConvertTo-Html -Fragment)

    <h2>Authentication Settings</h2>
    $($AllResults.AuthenticationSettings | ConvertTo-Html -Fragment)

    <h2>Logging Configuration</h2>
    $($AllResults.LoggingConfiguration | 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.Websites = Analyze-Websites }
        "2" { $allResults.ApplicationPools = Review-ApplicationPools }
        "3" { $allResults.BindingsAndSSL = Analyze-BindingsAndSSL }
        "4" { $allResults.VirtualDirectories = Check-VirtualDirectories }
        "5" { $allResults.HTTPResponseHeaders = Review-HTTPResponseHeaders }
        "6" { $allResults.AuthenticationSettings = Analyze-AuthenticationSettings }
        "7" { $allResults.LoggingConfiguration = Check-LoggingConfiguration }
        "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 IIS Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of IIS:
    • Website analysis
    • Application Pool review
    • Bindings and SSL Certificate analysis
    • Virtual Directory check
    • HTTP Response Header review
    • Authentication Settings analysis
    • Logging Configuration 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 IIS Websites and their configurations
  • Review of Application Pools and their settings
  • Analysis of Bindings and SSL Certificates, including expiration dates
  • Examination of Virtual Directories
  • Overview of custom HTTP Response Headers
  • Analysis of Authentication Settings for each website
  • Review of Logging Configurations
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • IIS Administrators managing web servers
  • System administrators overseeing IIS configurations
  • Security professionals auditing web server settings
  • DevOps engineers managing IIS deployments

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure IIS is installed with the management tools (which includes the WebAdministration module)
  3. Have the necessary permissions to query IIS configurations

This script provides a comprehensive overview of IIS configurations on a Windows Server, making it easier to audit and maintain IIS settings, websites, and application pools. It can significantly streamline the process of managing and documenting IIS configurations in enterprise environments.

File Server Resource Manager (FSRM) Analyzer Tool

<#
.SYNOPSIS
File Server Resource Manager (FSRM) Analyzer Tool

.DESCRIPTION
This script analyzes and audits File Server Resource Manager configurations, including
quotas, file screens, file groups, and classification rules on Windows Servers.

.NOTES
File Name      : FSRMAnalyzer.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, FSRM feature installed, and appropriate permissions
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\FSRMAnalyzer.ps1
#>

# Check if FSRM module is available
if (-not (Get-Module -ListAvailable -Name FileServerResourceManager)) {
    Write-Host "File Server Resource Manager module not found. Please ensure FSRM is installed." -ForegroundColor Red
    exit
}

# Import required module
Import-Module FileServerResourceManager

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== File Server Resource Manager Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze Quota Templates"
    Write-Host "2. Review File Screen Templates"
    Write-Host "3. Analyze File Groups"
    Write-Host "4. Review Classification Rules"
    Write-Host "5. Check File Management Tasks"
    Write-Host "6. Analyze Storage Reports"
    Write-Host "7. Review FSRM Settings"
    Write-Host "8. Generate Comprehensive HTML Report"
    Write-Host "9. Exit"
}

<#
.SYNOPSIS
Analyzes Quota Templates.

.OUTPUTS
Array of PSObjects containing Quota Template details.
#>
function Analyze-QuotaTemplates {
    Write-Host "`nAnalyzing Quota Templates..." -ForegroundColor Yellow
    $quotaTemplates = Get-FsrmQuotaTemplate
    $results = @()
    foreach ($template in $quotaTemplates) {
        $results += [PSCustomObject]@{
            Name = $template.Name
            Size = $template.Size
            SoftLimit = $template.SoftLimit
            ThresholdPercentages = $template.Threshold -join ", "
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Reviews File Screen Templates.

.OUTPUTS
Array of PSObjects containing File Screen Template details.
#>
function Review-FileScreenTemplates {
    Write-Host "`nReviewing File Screen Templates..." -ForegroundColor Yellow
    $screenTemplates = Get-FsrmFileScreenTemplate
    $results = @()
    foreach ($template in $screenTemplates) {
        $results += [PSCustomObject]@{
            Name = $template.Name
            IncludeGroup = $template.IncludeGroup -join ", "
            Active = $template.Active
            Description = $template.Description
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes File Groups.

.OUTPUTS
Array of PSObjects containing File Group details.
#>
function Analyze-FileGroups {
    Write-Host "`nAnalyzing File Groups..." -ForegroundColor Yellow
    $fileGroups = Get-FsrmFileGroup
    $results = @()
    foreach ($group in $fileGroups) {
        $results += [PSCustomObject]@{
            Name = $group.Name
            IncludePattern = $group.IncludePattern -join ", "
            ExcludePattern = $group.ExcludePattern -join ", "
            Description = $group.Description
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Reviews Classification Rules.

.OUTPUTS
Array of PSObjects containing Classification Rule details.
#>
function Review-ClassificationRules {
    Write-Host "`nReviewing Classification Rules..." -ForegroundColor Yellow
    $classRules = Get-FsrmClassificationRule
    $results = @()
    foreach ($rule in $classRules) {
        $results += [PSCustomObject]@{
            Name = $rule.Name
            Property = $rule.Property
            PropertyValue = $rule.PropertyValue
            Description = $rule.Description
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Checks File Management Tasks.

.OUTPUTS
Array of PSObjects containing File Management Task details.
#>
function Check-FileManagementTasks {
    Write-Host "`nChecking File Management Tasks..." -ForegroundColor Yellow
    $fmTasks = Get-FsrmFileManagementJob
    $results = @()
    foreach ($task in $fmTasks) {
        $results += [PSCustomObject]@{
            Name = $task.Name
            Namespace = $task.Namespace
            Action = $task.Action
            Enabled = $task.Enabled
            Schedule = $task.Schedule
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Analyzes Storage Reports.

.OUTPUTS
Array of PSObjects containing Storage Report details.
#>
function Analyze-StorageReports {
    Write-Host "`nAnalyzing Storage Reports..." -ForegroundColor Yellow
    $reports = Get-FsrmStorageReport
    $results = @()
    foreach ($report in $reports) {
        $results += [PSCustomObject]@{
            Name = $report.Name
            NameSpace = $report.NameSpace
            ReportFormats = $report.ReportFormats -join ", "
            Schedule = $report.Schedule
        }
    }
    $results | Format-Table -AutoSize
    return $results
}

<#
.SYNOPSIS
Reviews FSRM Settings.

.OUTPUTS
PSObject containing FSRM Settings.
#>
function Review-FSRMSettings {
    Write-Host "`nReviewing FSRM Settings..." -ForegroundColor Yellow
    $settings = Get-FsrmSetting
    $results = [PSCustomObject]@{
        SmtpServer = $settings.SmtpServer
        AdminEmailAddress = $settings.AdminEmailAddress
        FromEmailAddress = $settings.FromEmailAddress
        CommandNotificationLimit = $settings.CommandNotificationLimit
        EmailNotificationLimit = $settings.EmailNotificationLimit
        EventNotificationLimit = $settings.EventNotificationLimit
    }
    $results | Format-List
    return $results
}

<#
.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>FSRM 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>File Server Resource Manager Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>Quota Templates</h2>
    $($AllResults.QuotaTemplates | ConvertTo-Html -Fragment)

    <h2>File Screen Templates</h2>
    $($AllResults.FileScreenTemplates | ConvertTo-Html -Fragment)

    <h2>File Groups</h2>
    $($AllResults.FileGroups | ConvertTo-Html -Fragment)

    <h2>Classification Rules</h2>
    $($AllResults.ClassificationRules | ConvertTo-Html -Fragment)

    <h2>File Management Tasks</h2>
    $($AllResults.FileManagementTasks | ConvertTo-Html -Fragment)

    <h2>Storage Reports</h2>
    $($AllResults.StorageReports | ConvertTo-Html -Fragment)

    <h2>FSRM Settings</h2>
    $($AllResults.FSRMSettings | 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.QuotaTemplates = Analyze-QuotaTemplates }
        "2" { $allResults.FileScreenTemplates = Review-FileScreenTemplates }
        "3" { $allResults.FileGroups = Analyze-FileGroups }
        "4" { $allResults.ClassificationRules = Review-ClassificationRules }
        "5" { $allResults.FileManagementTasks = Check-FileManagementTasks }
        "6" { $allResults.StorageReports = Analyze-StorageReports }
        "7" { $allResults.FSRMSettings = Review-FSRMSettings }
        "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 File Server Resource Manager (FSRM) Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of FSRM:
    • Quota Templates analysis
    • File Screen Templates review
    • File Groups analysis
    • Classification Rules review
    • File Management Tasks check
    • Storage Reports analysis
    • FSRM Settings review
  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 Quota Templates and their thresholds
  • Review of File Screen Templates and their included file groups
  • Analysis of File Groups and their patterns
  • Examination of Classification Rules
  • Overview of File Management Tasks and their schedules
  • Analysis of configured Storage Reports
  • Review of general FSRM settings like email configurations
  • Comprehensive HTML report generation

This tool is particularly useful for:

  • System administrators managing file servers
  • Storage administrators overseeing quota and file screening policies
  • IT auditors reviewing file server configurations
  • Compliance officers ensuring adherence to file management policies

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure the File Server Resource Manager feature is installed on the server
  3. Have the necessary permissions to query FSRM configurations

This script provides a comprehensive overview of File Server Resource Manager configurations on a Windows Server, making it easier to audit and maintain FSRM policies, quotas, and file screening rules. It can significantly streamline the process of managing and documenting FSRM configurations in enterprise environments.

Group Policy Analyzer Tool

<#
.SYNOPSIS
Group Policy Analyzer Tool

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

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

.EXAMPLE
.\GroupPolicyAnalyzer.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 "=== Group Policy Analyzer Tool ===" -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. Analyze GPO WMI Filters"
    Write-Host "9. Generate Comprehensive HTML Report"
    Write-Host "10. 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
Analyzes GPO WMI Filters.

.OUTPUTS
Array of PSObjects containing GPO WMI Filter details.
#>
function Analyze-GPOWMIFilters {
    Write-Host "`nAnalyzing GPO WMI Filters..." -ForegroundColor Yellow
    $gpos = Get-GPO -All
    $wmiFilters = @()

    foreach ($gpo in $gpos) {
        $filter = $gpo.WmiFilter
        if ($filter) {
            $wmiFilters += [PSCustomObject]@{
                GPOName = $gpo.DisplayName
                WMIFilterName = $filter.Name
                WMIFilterDescription = $filter.Description
            }
        }
    }
    $wmiFilters | Format-Table -AutoSize
    return $wmiFilters
}

<#
.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)

    <h2>GPO WMI Filters</h2>
    $($AllResults.WMIFilters | 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-10)"

    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" { $allResults.WMIFilters = Analyze-GPOWMIFilters }
        "9" { Generate-HTMLReport -AllResults $allResults }
        "10" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Group Policy Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of Group Policy:
    • Analysis of all GPOs
    • Identification of unlinked GPOs
    • Detection of GPOs with no settings
    • Checking for conflicting GPO settings
    • Analysis of GPO links
    • Review of GPO permissions
    • Checking GPO version numbers
    • Analysis of GPO WMI filters
  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 all GPOs in the domain
  • Identification of potential issues like unlinked or empty GPOs
  • Detection of conflicting policy settings
  • Review of GPO links and their order
  • Analysis of GPO permissions for security auditing
  • Version number checks to identify potential replication issues
  • WMI filter analysis
  • Comprehensive HTML report generation

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
  • Security professionals assessing GPO-based security settings

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.

Network Traffic Analyzer Tool

<#
.SYNOPSIS
Network Traffic Analyzer Tool

.DESCRIPTION
This script analyzes network traffic, connections, and performance across servers in your network.

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

.EXAMPLE
.\NetworkTrafficAnalyzer.ps1
#>

# Import required modules
Import-Module NetAdapter
Import-Module NetTCPIP

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== Network Traffic Analyzer Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze Network Adapter Performance"
    Write-Host "2. Check Active TCP Connections"
    Write-Host "3. Analyze Network Bandwidth Usage"
    Write-Host "4. Check Network Latency"
    Write-Host "5. Analyze IP Configuration"
    Write-Host "6. Check Network Protocol Statistics"
    Write-Host "7. Analyze Firewall Rules"
    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 (L)ocal machine, (S)pecific servers, or (F)ile input? (L/S/F)"
    switch ($option.ToUpper()) {
        "L" {
            return @($env:COMPUTERNAME)
        }
        "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 local machine." -ForegroundColor Yellow
            return @($env:COMPUTERNAME)
        }
    }
}

<#
.SYNOPSIS
Analyzes network adapter performance.

.PARAMETER Servers
Array of server names to analyze.

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

    Write-Host "`nAnalyzing Network Adapter Performance..." -ForegroundColor Yellow
    $adapterResults = @()
    foreach ($server in $Servers) {
        try {
            $adapters = Get-NetAdapter -CimSession $server -ErrorAction Stop
            foreach ($adapter in $adapters) {
                $stats = $adapter | Get-NetAdapterStatistics
                $adapterResults += [PSCustomObject]@{
                    Server = $server
                    AdapterName = $adapter.Name
                    LinkSpeed = $adapter.LinkSpeed
                    BytesReceived = $stats.ReceivedBytes
                    BytesSent = $stats.SentBytes
                    Status = $adapter.Status
                }
            }
        }
        catch {
            Write-Host "Error analyzing network adapters on $server : $_" -ForegroundColor Red
        }
    }
    $adapterResults | Format-Table -AutoSize
    return $adapterResults
}

<#
.SYNOPSIS
Checks active TCP connections.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing active TCP connection details.
#>
function Check-ActiveTCPConnections {
    param([string[]]$Servers)

    Write-Host "`nChecking Active TCP Connections..." -ForegroundColor Yellow
    $connectionResults = @()
    foreach ($server in $Servers) {
        try {
            $connections = Get-NetTCPConnection -CimSession $server -ErrorAction Stop | 
                           Where-Object {$_.State -eq 'Established'}
            foreach ($conn in $connections) {
                $connectionResults += [PSCustomObject]@{
                    Server = $server
                    LocalAddress = $conn.LocalAddress
                    LocalPort = $conn.LocalPort
                    RemoteAddress = $conn.RemoteAddress
                    RemotePort = $conn.RemotePort
                    State = $conn.State
                }
            }
        }
        catch {
            Write-Host "Error checking TCP connections on $server : $_" -ForegroundColor Red
        }
    }
    $connectionResults | Format-Table -AutoSize
    return $connectionResults
}

<#
.SYNOPSIS
Analyzes network bandwidth usage.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing network bandwidth usage details.
#>
function Analyze-NetworkBandwidthUsage {
    param([string[]]$Servers)

    Write-Host "`nAnalyzing Network Bandwidth Usage..." -ForegroundColor Yellow
    $bandwidthResults = @()
    foreach ($server in $Servers) {
        try {
            $adapters = Get-NetAdapter -CimSession $server -ErrorAction Stop
            foreach ($adapter in $adapters) {
                $initialStats = $adapter | Get-NetAdapterStatistics
                Start-Sleep -Seconds 5
                $finalStats = $adapter | Get-NetAdapterStatistics
                $receivedBps = ($finalStats.ReceivedBytes - $initialStats.ReceivedBytes) / 5
                $sentBps = ($finalStats.SentBytes - $initialStats.SentBytes) / 5
                
                $bandwidthResults += [PSCustomObject]@{
                    Server = $server
                    AdapterName = $adapter.Name
                    ReceiveBandwidth = "$([math]::Round($receivedBps / 1MB, 2)) MBps"
                    SendBandwidth = "$([math]::Round($sentBps / 1MB, 2)) MBps"
                }
            }
        }
        catch {
            Write-Host "Error analyzing bandwidth usage on $server : $_" -ForegroundColor Red
        }
    }
    $bandwidthResults | Format-Table -AutoSize
    return $bandwidthResults
}

<#
.SYNOPSIS
Checks network latency.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing network latency details.
#>
function Check-NetworkLatency {
    param([string[]]$Servers)

    Write-Host "`nChecking Network Latency..." -ForegroundColor Yellow
    $latencyResults = @()
    foreach ($server in $Servers) {
        try {
            $ping = Test-Connection -ComputerName $server -Count 4 -ErrorAction Stop
            $latencyResults += [PSCustomObject]@{
                Server = $server
                MinLatency = ($ping | Measure-Object -Property ResponseTime -Minimum).Minimum
                MaxLatency = ($ping | Measure-Object -Property ResponseTime -Maximum).Maximum
                AverageLatency = ($ping | Measure-Object -Property ResponseTime -Average).Average
            }
        }
        catch {
            Write-Host "Error checking network latency for $server : $_" -ForegroundColor Red
        }
    }
    $latencyResults | Format-Table -AutoSize
    return $latencyResults
}

<#
.SYNOPSIS
Analyzes IP configuration.

.PARAMETER Servers
Array of server names to analyze.

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

    Write-Host "`nAnalyzing IP Configuration..." -ForegroundColor Yellow
    $ipConfigResults = @()
    foreach ($server in $Servers) {
        try {
            $ipConfig = Get-NetIPConfiguration -CimSession $server -ErrorAction Stop
            foreach ($config in $ipConfig) {
                $ipConfigResults += [PSCustomObject]@{
                    Server = $server
                    InterfaceAlias = $config.InterfaceAlias
                    IPv4Address = $config.IPv4Address.IPAddress
                    IPv6Address = $config.IPv6Address.IPAddress
                    DefaultGateway = $config.IPv4DefaultGateway.NextHop
                    DNSServer = ($config.DNSServer | Where-Object {$_.AddressFamily -eq 2}).ServerAddresses -join ', '
                }
            }
        }
        catch {
            Write-Host "Error analyzing IP configuration on $server : $_" -ForegroundColor Red
        }
    }
    $ipConfigResults | Format-Table -AutoSize
    return $ipConfigResults
}

<#
.SYNOPSIS
Checks network protocol statistics.

.PARAMETER Servers
Array of server names to analyze.

.OUTPUTS
Array of PSObjects containing network protocol statistics.
#>
function Check-NetworkProtocolStatistics {
    param([string[]]$Servers)

    Write-Host "`nChecking Network Protocol Statistics..." -ForegroundColor Yellow
    $protocolStats = @()
    foreach ($server in $Servers) {
        try {
            $tcpStats = Get-NetTCPStatistics -CimSession $server -ErrorAction Stop
            $udpStats = Get-NetUDPStatistics -CimSession $server -ErrorAction Stop
            $protocolStats += [PSCustomObject]@{
                Server = $server
                TCPSegmentsSent = $tcpStats.SegmentsSent
                TCPSegmentsReceived = $tcpStats.SegmentsReceived
                TCPConnectionsReset = $tcpStats.ConnectionsReset
                UDPDatagramsReceived = $udpStats.DatagramsReceived
                UDPDatagramsSent = $udpStats.DatagramsSent
            }
        }
        catch {
            Write-Host "Error checking network protocol statistics on $server : $_" -ForegroundColor Red
        }
    }
    $protocolStats | Format-Table -AutoSize
    return $protocolStats
}

<#
.SYNOPSIS
Analyzes firewall rules.

.PARAMETER Servers
Array of server names to analyze.

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

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

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

    <h2>Network Adapter Performance</h2>
    $($AllResults.AdapterPerformance | ConvertTo-Html -Fragment)

    <h2>Active TCP Connections</h2>
    $($AllResults.TCPConnections | ConvertTo-Html -Fragment)

    <h2>Network Bandwidth Usage</h2>
    $($AllResults.BandwidthUsage | ConvertTo-Html -Fragment)

    <h2>Network Latency</h2>
    $($AllResults.NetworkLatency | ConvertTo-Html -Fragment)

    <h2>IP Configuration</h2>
    $($AllResults.IPConfiguration | ConvertTo-Html -Fragment)

    <h2>Network Protocol Statistics</h2>
    $($AllResults.ProtocolStats | ConvertTo-Html -Fragment)

    <h2>Firewall Rules</h2>
    $($AllResults.FirewallRules | 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.AdapterPerformance = Analyze-NetworkAdapterPerformance -Servers $targetServers }
        "2" { $allResults.TCPConnections = Check-ActiveTCPConnections -Servers $targetServers }
        "3" { $allResults.BandwidthUsage = Analyze-NetworkBandwidthUsage -Servers $targetServers }
        "4" { $allResults.NetworkLatency = Check-NetworkLatency -Servers $targetServers }
        "5" { $allResults.IPConfiguration = Analyze-IPConfiguration -Servers $targetServers }
        "6" { $allResults.ProtocolStats = Check-NetworkProtocolStatistics -Servers $targetServers }
        "7" { $allResults.FirewallRules = Analyze-FirewallRules -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 Network Traffic Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of network traffic and performance:
    • Network Adapter Performance analysis
    • Active TCP Connections check
    • Network Bandwidth Usage analysis
    • Network Latency check
    • IP Configuration analysis
    • Network Protocol Statistics check
    • Firewall Rules analysis
  3. Flexible server selection (local machine, 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 network adapter performance across multiple servers
  • Checking of active TCP connections
  • Real-time bandwidth usage measurement
  • Network latency analysis
  • Comprehensive IP configuration review
  • Analysis of TCP and UDP protocol statistics
  • Overview of firewall rules
  • HTML report generation for easy sharing and viewing of results

This tool is particularly useful for:

  • Network administrators troubleshooting performance issues
  • System administrators managing server networks
  • IT professionals performing network health checks
  • Security teams reviewing network configurations

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 (NetAdapter and NetTCPIP)

This script provides a comprehensive overview of network traffic and performance across multiple servers in your network. It can significantly streamline the process of diagnosing network issues, optimizing performance, and maintaining network security.

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.