Tag Archive for: Program

PowerShell Administrative Toolkit

# PowerShell Administrative Toolkit

# Function to get system information
function Get-SystemInfo {
    $systemInfo = @{
        "OS" = (Get-CimInstance -ClassName Win32_OperatingSystem).Caption
        "Architecture" = (Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture
        "CPU" = (Get-CimInstance -ClassName Win32_Processor).Name
        "Memory" = [math]::round((Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 2)
    }
    $systemInfo | Format-Table -AutoSize
}

# Function to create a new user
function New-User {
    param (
        [string]$Username,
        [string]$Password,
        [string]$FullName
    )
    $securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
    New-LocalUser -Name $Username -Password $securePassword -FullName $FullName -Description "Created by PowerShell Toolkit"
    Add-LocalGroupMember -Group "Administrators" -Member $Username
    Write-Host "User $Username created and added to Administrators group."
}

# Function to remove a user
function Remove-User {
    param (
        [string]$Username
    )
    Remove-LocalUser -Name $Username -Force
    Write-Host "User $Username removed."
}

# Function to back up files
function Backup-Files {
    param (
        [string]$SourcePath,
        [string]$DestinationPath
    )
    Copy-Item -Path $SourcePath -Destination $DestinationPath -Recurse -Force
    Write-Host "Files from $SourcePath backed up to $DestinationPath."
}

# Function to clean old files
function Clean-OldFiles {
    param (
        [string]$Path,
        [int]$Days
    )
    $cutoffDate = (Get-Date).AddDays(-$Days)
    Get-ChildItem -Path $Path -File | Where-Object { $_.LastWriteTime -lt $cutoffDate } | Remove-Item -Force
    Write-Host "Files older than $Days days have been removed from $Path."
}

# Function to start a service
function Start-Service {
    param (
        [string]$ServiceName
    )
    Start-Service -Name $ServiceName
    Write-Host "Service $ServiceName started."
}

# Function to stop a service
function Stop-Service {
    param (
        [string]$ServiceName
    )
    Stop-Service -Name $ServiceName
    Write-Host "Service $ServiceName stopped."
}

# Function to get service status
function Get-ServiceStatus {
    param (
        [string]$ServiceName
    )
    Get-Service -Name $ServiceName | Select-Object Name, Status
}

# Function to get network information
function Get-NetworkInfo {
    Get-NetIPAddress | Select-Object InterfaceAlias, IPAddress, AddressFamily | Format-Table -AutoSize
}

# Function to set IP configuration
function Set-IPConfiguration {
    param (
        [string]$InterfaceAlias,
        [string]$IPAddress,
        [string]$SubnetMask,
        [string]$DefaultGateway
    )
    New-NetIPAddress -InterfaceAlias $InterfaceAlias -IPAddress $IPAddress -PrefixLength $SubnetMask -DefaultGateway $DefaultGateway
    Write-Host "IP configuration set for $InterfaceAlias."
}

# Function to set file permissions
function Set-FilePermissions {
    param (
        [string]$FilePath,
        [string]$User,
        [string]$AccessRule
    )
    $acl = Get-Acl -Path $FilePath
    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($User, $AccessRule, "Allow")
    $acl.AddAccessRule($rule)
    Set-Acl -Path $FilePath -AclObject $acl
    Write-Host "Permissions set for $FilePath."
}

# Function to display the menu and handle user choices
function Show-Menu {
    Clear-Host
    Write-Host "PowerShell Administrative Toolkit"
    Write-Host "1: Get System Information"
    Write-Host "2: Create New User"
    Write-Host "3: Remove User"
    Write-Host "4: Backup Files"
    Write-Host "5: Clean Old Files"
    Write-Host "6: Start Service"
    Write-Host "7: Stop Service"
    Write-Host "8: Get Service Status"
    Write-Host "9: Get Network Information"
    Write-Host "10: Set IP Configuration"
    Write-Host "11: Set File Permissions"
    Write-Host "Q: Quit"
    $choice = Read-Host "Enter your choice"
    
    switch ($choice) {
        "1" { Get-SystemInfo }
        "2" {
            $username = Read-Host "Enter username"
            $password = Read-Host "Enter password" -AsSecureString
            $fullname = Read-Host "Enter full name"
            New-User -Username $username -Password $password -FullName $fullname
        }
        "3" {
            $username = Read-Host "Enter username"
            Remove-User -Username $username
        }
        "4" {
            $source = Read-Host "Enter source path"
            $destination = Read-Host "Enter destination path"
            Backup-Files -SourcePath $source -DestinationPath $destination
        }
        "5" {
            $path = Read-Host "Enter path"
            $days = Read-Host "Enter number of days"
            Clean-OldFiles -Path $path -Days $days
        }
        "6" {
            $service = Read-Host "Enter service name"
            Start-Service -ServiceName $service
        }
        "7" {
            $service = Read-Host "Enter service name"
            Stop-Service -ServiceName $service
        }
        "8" {
            $service = Read-Host "Enter service name"
            Get-ServiceStatus -ServiceName $service
        }
        "9" { Get-NetworkInfo }
        "10" {
            $interface = Read-Host "Enter interface alias"
            $ip = Read-Host "Enter IP address"
            $subnet = Read-Host "Enter subnet mask"
            $gateway = Read-Host "Enter default gateway"
            Set-IPConfiguration -InterfaceAlias $interface -IPAddress $ip -SubnetMask $subnet -DefaultGateway $gateway
        }
        "11" {
            $file = Read-Host "Enter file path"
            $user = Read-Host "Enter user"
            $rule = Read-Host "Enter access rule"
            Set-FilePermissions -FilePath $file -User $user -AccessRule $rule
        }
        "Q" { exit }
        default { Write-Host "Invalid choice, please try again." }
    }
}

# Main loop to display the menu and process user choices
while ($true) {
    Show-Menu
}

Installing and Updating PowerShell

Introduction: PowerShell is a powerful task automation and configuration management framework from Microsoft. It’s an essential tool for system administrators, IT professionals, and developers. This guide will walk you through the process of installing and updating PowerShell on various operating systems.

  1. PowerShell Versions: Before we begin, it’s important to understand the different versions of PowerShell:
  • Windows PowerShell: Built into Windows, latest version is 5.1
  • PowerShell Core (6.x): Cross-platform, open-source version
  • PowerShell 7+: The latest cross-platform, open-source version (recommended)
  1. Installing PowerShell on Windows:

2.1 Windows PowerShell: Windows PowerShell 5.1 comes pre-installed on Windows 10 and Windows Server 2016 and later. For older versions of Windows, you can download it from the Microsoft website.

2.2 PowerShell 7 (recommended): a) Visit the GitHub releases page: https://github.com/PowerShell/PowerShell/releases b) Download the latest .msi file for your system architecture (x64 or x86) c) Run the installer and follow the prompts d) Launch PowerShell 7 from the Start menu

  1. Installing PowerShell on macOS:

3.1 Using Homebrew: a) Install Homebrew if you haven’t already: /bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)” b) Run: brew install –cask powershell

3.2 Manual installation: a) Visit the GitHub releases page b) Download the latest .pkg file c) Open the package and follow the installation wizard

  1. Installing PowerShell on Linux:

4.1 Ubuntu: a) Download the Microsoft repository GPG keys: wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb b) Register the Microsoft repository GPG keys: sudo dpkg -i packages-microsoft-prod.deb c) Update the list of products: sudo apt-get update d) Install PowerShell: sudo apt-get install -y powershell

4.2 Other Linux distributions: Refer to the official Microsoft documentation for specific instructions for your distribution.

  1. Updating PowerShell:

5.1 Windows: a) Check your current version: $PSVersionTable.PSVersion b) Visit the GitHub releases page and download the latest version c) Run the installer to update

5.2 macOS (Homebrew): a) Run: brew update b) Then: brew upgrade powershell –cask

5.3 Linux (Ubuntu): a) Update the package list: sudo apt-get update b) Upgrade PowerShell: sudo apt-get upgrade powershell

  1. Using the Update-Help cmdlet: After installation or update, it’s a good practice to update the help files: a) Open PowerShell as an administrator b) Run: Update-Help
  2. Verifying the Installation: To verify that PowerShell is installed correctly: a) Open PowerShell b) Run: $PSVersionTable This will display information about your PowerShell version and environment.
  3. Setting Up a Profile: Consider setting up a PowerShell profile to customize your environment: a) Check if a profile exists: Test-Path $PROFILE b) If it doesn’t exist, create one: New-Item -Path $PROFILE -Type File -Force c) Edit the profile: notepad $PROFILE
  4. Best Practices:
  • Always keep PowerShell updated for the latest features and security patches
  • Use the latest version (PowerShell 7+) when possible for cross-platform compatibility
  • Familiarize yourself with PowerShell’s execution policies for security
  • Regularly update the help files using Update-Help

Installing and updating PowerShell is a straightforward process that varies slightly depending on your operating system. By following this guide, you should now have PowerShell installed and ready to use. Remember to keep it updated and explore its vast capabilities to enhance your productivity and automation skills.

Website Security Checker Tool

<#
.SYNOPSIS
Website Security Checker Tool

.DESCRIPTION
This script analyzes a website for various security aspects and provides a report.

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

.EXAMPLE
.\WebsiteSecurityChecker.ps1
#>

# Import required modules
Add-Type -AssemblyName System.Net.Http

# Global variables
$script:reportPath = "$env:USERPROFILE\Desktop\Website_Security_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$script:httpClient = New-Object System.Net.Http.HttpClient

function Show-Menu {
    Clear-Host
    Write-Host "=== Website Security Checker Tool ===" -ForegroundColor Cyan
    Write-Host "1. Analyze Website"
    Write-Host "2. View Last Report"
    Write-Host "3. Exit"
}

function Analyze-Website {
    $url = Read-Host "Enter the website URL to analyze (include http:// or https://)"
    
    if (-not ($url -match "^https?://")) {
        Write-Host "Invalid URL. Please include http:// or https://" -ForegroundColor Red
        return
    }

    Write-Host "`nAnalyzing $url..." -ForegroundColor Yellow

    try {
        $results = @{
            URL = $url
            SSLImplementation = Check-SSLImplementation $url
            HTTPSRedirect = Check-HTTPSRedirect $url
            SecurityHeaders = Check-SecurityHeaders $url
            ContentSecurityPolicy = Check-ContentSecurityPolicy $url
            XFrameOptions = Check-XFrameOptions $url
            XSSProtection = Check-XSSProtection $url
            HSTS = Check-HSTS $url
            ServerInformation = Check-ServerInformation $url
            Cookies = Check-Cookies $url
            OpenPorts = Check-OpenPorts $url
        }

        Generate-Report $results
    }
    catch {
        Write-Host "Error analyzing website: $_" -ForegroundColor Red
    }
}

function Check-SSLImplementation($url) {
    if ($url.StartsWith("https://")) {
        try {
            $request = [System.Net.WebRequest]::Create($url)
            $request.AllowAutoRedirect = $false
            $response = $request.GetResponse()
            $cert = $response.GetResponseStream().GetType().GetField("m_HttpResponseStream", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance).GetValue($response.GetResponseStream()).GetType().GetField("m_Socket", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance).GetValue($response.GetResponseStream().GetType().GetField("m_HttpResponseStream", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance).GetValue($response.GetResponseStream())).RemoteCertificate

            return @{
                Implemented = $true
                Issuer = $cert.Issuer
                ExpirationDate = $cert.GetExpirationDateString()
                Protocol = $response.ProtocolVersion
            }
        }
        catch {
            return @{
                Implemented = $false
                Error = $_.Exception.Message
            }
        }
        finally {
            if ($response) { $response.Close() }
        }
    }
    else {
        return @{
            Implemented = $false
            Error = "Not using HTTPS"
        }
    }
}

function Check-HTTPSRedirect($url) {
    if ($url.StartsWith("http://")) {
        try {
            $request = [System.Net.WebRequest]::Create($url)
            $request.AllowAutoRedirect = $false
            $response = $request.GetResponse()
            $statusCode = [int]$response.StatusCode
            $location = $response.GetResponseHeader("Location")

            return @{
                Redirects = ($statusCode -ge 300 -and $statusCode -lt 400)
                StatusCode = $statusCode
                Location = $location
            }
        }
        catch {
            return @{
                Redirects = $false
                Error = $_.Exception.Message
            }
        }
        finally {
            if ($response) { $response.Close() }
        }
    }
    else {
        return @{
            Redirects = "N/A (Already using HTTPS)"
        }
    }
}

function Check-SecurityHeaders($url) {
    try {
        $response = $script:httpClient.GetAsync($url).Result
        $headers = $response.Headers
        return @{
            "X-Content-Type-Options" = $headers.GetValues("X-Content-Type-Options")
            "X-XSS-Protection" = $headers.GetValues("X-XSS-Protection")
            "X-Frame-Options" = $headers.GetValues("X-Frame-Options")
            "Strict-Transport-Security" = $headers.GetValues("Strict-Transport-Security")
            "Content-Security-Policy" = $headers.GetValues("Content-Security-Policy")
            "Referrer-Policy" = $headers.GetValues("Referrer-Policy")
        }
    }
    catch {
        return @{
            Error = $_.Exception.Message
        }
    }
}

function Check-ContentSecurityPolicy($url) {
    $headers = Check-SecurityHeaders $url
    return $headers."Content-Security-Policy"
}

function Check-XFrameOptions($url) {
    $headers = Check-SecurityHeaders $url
    return $headers."X-Frame-Options"
}

function Check-XSSProtection($url) {
    $headers = Check-SecurityHeaders $url
    return $headers."X-XSS-Protection"
}

function Check-HSTS($url) {
    $headers = Check-SecurityHeaders $url
    return $headers."Strict-Transport-Security"
}

function Check-ServerInformation($url) {
    try {
        $response = $script:httpClient.GetAsync($url).Result
        return $response.Headers.GetValues("Server")
    }
    catch {
        return "Unable to retrieve server information"
    }
}

function Check-Cookies($url) {
    try {
        $response = $script:httpClient.GetAsync($url).Result
        $cookies = $response.Headers.GetValues("Set-Cookie")
        $secureCookies = $cookies | Where-Object { $_ -match "Secure" }
        $httpOnlyCookies = $cookies | Where-Object { $_ -match "HttpOnly" }
        return @{
            TotalCookies = $cookies.Count
            SecureCookies = $secureCookies.Count
            HttpOnlyCookies = $httpOnlyCookies.Count
        }
    }
    catch {
        return @{
            Error = $_.Exception.Message
        }
    }
}

function Check-OpenPorts($url) {
    $uri = [System.Uri]$url
    $hostname = $uri.Host
    $commonPorts = @(80, 443, 8080, 8443)
    $openPorts = @()

    foreach ($port in $commonPorts) {
        try {
            $tcpClient = New-Object System.Net.Sockets.TcpClient
            $connect = $tcpClient.BeginConnect($hostname, $port, $null, $null)
            $wait = $connect.AsyncWaitHandle.WaitOne(1000, $false)
            if ($wait) {
                $tcpClient.EndConnect($connect)
                $openPorts += $port
            }
        }
        catch {}
        finally {
            if ($tcpClient -ne $null) { $tcpClient.Close() }
        }
    }

    return $openPorts
}

function Generate-Report($results) {
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Website Security Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }
        h1, h2 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .good { color: green; }
        .warning { color: orange; }
        .bad { color: red; }
    </style>
</head>
<body>
    <h1>Website Security Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>URL: $($results.URL)</p>

    <h2>SSL Implementation</h2>
    <table>
        <tr><th>Implemented</th><td>$(if ($results.SSLImplementation.Implemented) { "<span class='good'>Yes</span>" } else { "<span class='bad'>No</span>" })</td></tr>
        <tr><th>Issuer</th><td>$($results.SSLImplementation.Issuer)</td></tr>
        <tr><th>Expiration Date</th><td>$($results.SSLImplementation.ExpirationDate)</td></tr>
        <tr><th>Protocol</th><td>$($results.SSLImplementation.Protocol)</td></tr>
    </table>

    <h2>HTTPS Redirect</h2>
    <table>
        <tr><th>Redirects to HTTPS</th><td>$(if ($results.HTTPSRedirect.Redirects -eq $true) { "<span class='good'>Yes</span>" } elseif ($results.HTTPSRedirect.Redirects -eq $false) { "<span class='bad'>No</span>" } else { $results.HTTPSRedirect.Redirects })</td></tr>
        <tr><th>Status Code</th><td>$($results.HTTPSRedirect.StatusCode)</td></tr>
        <tr><th>Redirect Location</th><td>$($results.HTTPSRedirect.Location)</td></tr>
    </table>

    <h2>Security Headers</h2>
    <table>
        <tr><th>X-Content-Type-Options</th><td>$(if ($results.SecurityHeaders."X-Content-Type-Options") { "<span class='good'>$($results.SecurityHeaders."X-Content-Type-Options")</span>" } else { "<span class='bad'>Not Set</span>" })</td></tr>
        <tr><th>X-XSS-Protection</th><td>$(if ($results.SecurityHeaders."X-XSS-Protection") { "<span class='good'>$($results.SecurityHeaders."X-XSS-Protection")</span>" } else { "<span class='bad'>Not Set</span>" })</td></tr>
        <tr><th>X-Frame-Options</th><td>$(if ($results.SecurityHeaders."X-Frame-Options") { "<span class='good'>$($results.SecurityHeaders."X-Frame-Options")</span>" } else { "<span class='bad'>Not Set</span>" })</td></tr>
        <tr><th>Strict-Transport-Security</th><td>$(if ($results.SecurityHeaders."Strict-Transport-Security") { "<span class='good'>$($results.SecurityHeaders."Strict-Transport-Security")</span>" } else { "<span class='bad'>Not Set</span>" })</td></tr>
        <tr><th>Content-Security-Policy</th><td>$(if ($results.SecurityHeaders."Content-Security-Policy") { "<span class='good'>Set</span>" } else { "<span class='warning'>Not Set</span>" })</td></tr>
        <tr><th>Referrer-Policy</th><td>$(if ($results.SecurityHeaders."Referrer-Policy") { "<span class='good'>$($results.SecurityHeaders."Referrer-Policy")</span>" } else { "<span class='warning'>Not Set</span>" })</td></tr>
    </table>

    <h2>Server Information</h2>
    <p>$($results.ServerInformation)</p>

    <h2>Cookies</h2>
    <table>
        <tr><th>Total Cookies</th><td>$($results.Cookies.TotalCookies)</td></tr>
        <tr><th>Secure Cookies</th><td>$($results.Cookies.SecureCookies)</td></tr>
        <tr><th>HttpOnly Cookies</th><td>$($results.Cookies.HttpOnlyCookies)</td></tr>
    </table>

    <h2>Open Ports</h2>
    <p>$($results.OpenPorts -join ", ")</p>

    <h2>Recommendations</h2>
    <ul>
        $(if (-not $results.SSLImplementation.Implemented) { "<li class='bad'>Implement SSL/TLS to secure communications.</li>" })
        $(if ($results.HTTPSRedirect.Redirects -eq $false) { "<li class='warning'>Implement HTTPS redirect for all HTTP traffic.</li>" })
        $(if (-not $results.SecurityHeaders."X-Content-Type-Options") { "<li class='warning'>Set X-Content-Type-Options header to prevent MIME type sniffing.</li>" })
        $(if (-not $results.SecurityHeaders."X-XSS-Protection") { "<li class='warning'>Set X-XSS-Protection header to enable browser's XSS filter.</li>" })
        $(if (-not $results.SecurityHeaders."X-Frame-Options") { "<li class='warning'>Set X-Frame-Options header to prevent clickjacking attacks.</li>" })
        $(if (-not $results.SecurityHeaders."Strict-Transport-Security") { "<li class='warning'>Implement HTTP Strict Transport Security (HSTS) to enforce HTTPS connections.</li>" })
        $(if (-not $results.SecurityHeaders."Content-Security-Policy") { "<li class='warning'>Implement Content Security Policy to prevent XSS and data injection attacks.</li>" })
        $(if ($results.Cookies.TotalCookies -gt $results.Cookies.SecureCookies) { "<li class='warning'>Ensure all cookies are set with the Secure flag.</li>" })
        $(if ($results.Cookies.TotalCookies -gt $results.Cookies.HttpOnlyCookies) { "<li class='warning'>Ensure all cookies are set with the HttpOnly flag.</li>" })
        $(if ($results.OpenPorts.Count -gt 2) { "<li class='warning'>Consider closing unnecessary open ports to reduce attack surface.</li>" })
    </ul>
</body>
</html>
"@

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

function View-LastReport {
    if (Test-Path $script:reportPath) {
        Start-Process $script:reportPath
    } else {
        Write-Host "No report found. Please analyze a website first." -ForegroundColor Yellow
    }
}

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

    switch ($choice) {
        "1" { Analyze-Website }
        "2" { View-LastReport }
        "3" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

# Cleanup
$script:httpClient.Dispose()

This Website Security Checker Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various security aspects of a website:
    • SSL/TLS implementation
    • HTTPS redirect
    • Security headers (X-Content-Type-Options, X-XSS-Protection, X-Frame-Options, etc.)
    • Content Security Policy
    • HTTP Strict Transport Security (HSTS)
    • Server information disclosure
    • Cookie security (Secure and HttpOnly flags)
    • Open ports check
  3. A report generation function that creates an HTML report with the analysis results and recommendations.
  4. Option to view the last generated report.

Key features:

  • Analyzes important website security elements
  • Provides a visual HTML report with color-coded results and recommendations
  • Checks for proper SSL/TLS implementation and HTTPS usage
  • Analyzes security headers and their configurations
  • Examines cookie security settings
  • Performs a basic open ports check
  • Offers suggestions for improving website security based on best practices

This tool is particularly useful for:

  • Website owners who want to perform a basic security check
  • Web developers ensuring they’ve implemented basic security best practices
  • IT security professionals performing initial security assessments
  • Anyone learning about web security and wanting to analyze real websites

To use this script effectively:

  1. Run the script in PowerShell
  2. Choose to analyze a website by entering its URL
  3. Review the generated HTML report
  4. Use the recommendations to improve the website’s security

Please note that this is a basic security checker and doesn’t cover all aspects of web security. For a comprehensive security analysis, you would need to consider many more factors and potentially use more advanced tools and techniques. However, this script provides a good starting point for identifying common security issues and misconfigurations.

Simple IIS Security Check Tool

<#
.SYNOPSIS
Simple IIS Security Check Tool

.DESCRIPTION
This script performs basic security checks on an IIS server. It is for educational purposes only
and should only be used on systems you own or have explicit permission to test.

.NOTES
File Name      : SimpleIISSecurityCheck.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights, and proper authorization
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\SimpleIISSecurityCheck.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\IIS_Security_Check_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:targetServer = "localhost"  # Default to local machine

function Show-Menu {
    Clear-Host
    Write-Host "=== Simple IIS Security Check Tool ===" -ForegroundColor Cyan
    Write-Host "Target Server: $global:targetServer"
    Write-Host "1. Set Target Server"
    Write-Host "2. Check IIS Version"
    Write-Host "3. Enumerate Web Sites"
    Write-Host "4. Check for Default Web Pages"
    Write-Host "5. Check Directory Browsing"
    Write-Host "6. Check HTTP Response Headers"
    Write-Host "7. Check SSL/TLS Configuration"
    Write-Host "8. Generate HTML Report"
    Write-Host "9. Exit"
}

function Set-TargetServer {
    $server = Read-Host "Enter the target server name or IP (or press Enter for localhost)"
    if ([string]::IsNullOrWhiteSpace($server)) {
        $global:targetServer = "localhost"
    } else {
        $global:targetServer = $server
    }
    Write-Host "Target server set to: $global:targetServer" -ForegroundColor Green
}

function Check-IISVersion {
    Write-Host "`nChecking IIS Version..." -ForegroundColor Yellow
    try {
        $iisVersion = Invoke-Command -ComputerName $global:targetServer -ScriptBlock {
            Get-ItemProperty HKLM:\SOFTWARE\Microsoft\InetStp\ | Select-Object MajorVersion, MinorVersion
        }
        $version = "$($iisVersion.MajorVersion).$($iisVersion.MinorVersion)"
        Write-Host "IIS Version: $version" -ForegroundColor Green
        return $version
    } catch {
        Write-Host "Error checking IIS version: $_" -ForegroundColor Red
        return "Error"
    }
}

function Enumerate-WebSites {
    Write-Host "`nEnumerating Web Sites..." -ForegroundColor Yellow
    try {
        $sites = Invoke-Command -ComputerName $global:targetServer -ScriptBlock {
            Import-Module WebAdministration
            Get-Website | Select-Object Name, ID, State, PhysicalPath, Bindings
        }
        $sites | Format-Table -AutoSize
        return $sites
    } catch {
        Write-Host "Error enumerating web sites: $_" -ForegroundColor Red
        return $null
    }
}

function Check-DefaultWebPages {
    Write-Host "`nChecking for Default Web Pages..." -ForegroundColor Yellow
    $defaultPages = @("iisstart.htm", "default.aspx", "index.html", "index.htm")
    $results = @()
    
    $sites = Invoke-Command -ComputerName $global:targetServer -ScriptBlock {
        Import-Module WebAdministration
        Get-Website | Select-Object Name, PhysicalPath
    }

    foreach ($site in $sites) {
        foreach ($page in $defaultPages) {
            $path = Join-Path $site.PhysicalPath $page
            $exists = Invoke-Command -ComputerName $global:targetServer -ScriptBlock {
                param($path)
                Test-Path $path
            } -ArgumentList $path

            if ($exists) {
                $results += [PSCustomObject]@{
                    Site = $site.Name
                    DefaultPage = $page
                    Exists = $true
                }
            }
        }
    }

    if ($results.Count -eq 0) {
        Write-Host "No default pages found." -ForegroundColor Green
    } else {
        $results | Format-Table -AutoSize
    }
    return $results
}

function Check-DirectoryBrowsing {
    Write-Host "`nChecking Directory Browsing..." -ForegroundColor Yellow
    try {
        $dirBrowsing = Invoke-Command -ComputerName $global:targetServer -ScriptBlock {
            Import-Module WebAdministration
            Get-WebConfigurationProperty -Filter /system.webServer/directoryBrowse -Name enabled -PSPath 'IIS:\'
        }
        if ($dirBrowsing.Value) {
            Write-Host "Directory Browsing is enabled" -ForegroundColor Red
        } else {
            Write-Host "Directory Browsing is disabled" -ForegroundColor Green
        }
        return $dirBrowsing.Value
    } catch {
        Write-Host "Error checking directory browsing: $_" -ForegroundColor Red
        return $null
    }
}

function Check-HTTPResponseHeaders {
    Write-Host "`nChecking HTTP Response Headers..." -ForegroundColor Yellow
    try {
        $headers = Invoke-Command -ComputerName $global:targetServer -ScriptBlock {
            Import-Module WebAdministration
            Get-WebConfigurationProperty -Filter /system.webServer/httpProtocol/customHeaders -Name . -PSPath 'IIS:\'
        }
        $headers | Format-Table -AutoSize
        return $headers
    } catch {
        Write-Host "Error checking HTTP response headers: $_" -ForegroundColor Red
        return $null
    }
}

function Check-SSLTLSConfiguration {
    Write-Host "`nChecking SSL/TLS Configuration..." -ForegroundColor Yellow
    try {
        $sslSettings = Invoke-Command -ComputerName $global:targetServer -ScriptBlock {
            $protocols = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2")
            $results = @{}
            foreach ($protocol in $protocols) {
                $clientPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$protocol\Client"
                $serverPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$protocol\Server"
                $clientEnabled = (Get-ItemProperty -Path $clientPath -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
                $serverEnabled = (Get-ItemProperty -Path $serverPath -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
                $results[$protocol] = @{
                    "ClientEnabled" = if ($clientEnabled -eq 1) { "Enabled" } elseif ($clientEnabled -eq 0) { "Disabled" } else { "Not Configured" }
                    "ServerEnabled" = if ($serverEnabled -eq 1) { "Enabled" } elseif ($serverEnabled -eq 0) { "Disabled" } else { "Not Configured" }
                }
            }
            return $results
        }
        $sslSettings | Format-Table -AutoSize
        return $sslSettings
    } catch {
        Write-Host "Error checking SSL/TLS configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    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>IIS Security Check 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; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>IIS Security Check Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>Target Server: $global:targetServer</p>

    <h2>IIS Version</h2>
    <p>$($AllResults.IISVersion)</p>

    <h2>Web Sites</h2>
    $($AllResults.WebSites | ConvertTo-Html -Fragment)

    <h2>Default Web Pages</h2>
    $($AllResults.DefaultPages | ConvertTo-Html -Fragment)

    <h2>Directory Browsing</h2>
    <p>$(if ($AllResults.DirectoryBrowsing) { '<span class="critical">Enabled</span>' } else { '<span class="warning">Disabled</span>' })</p>

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

    <h2>SSL/TLS Configuration</h2>
    $($AllResults.SSLTLSConfig | 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" { Set-TargetServer }
        "2" { $allResults.IISVersion = Check-IISVersion }
        "3" { $allResults.WebSites = Enumerate-WebSites }
        "4" { $allResults.DefaultPages = Check-DefaultWebPages }
        "5" { $allResults.DirectoryBrowsing = Check-DirectoryBrowsing }
        "6" { $allResults.HTTPHeaders = Check-HTTPResponseHeaders }
        "7" { $allResults.SSLTLSConfig = Check-SSLTLSConfiguration }
        "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 Simple IIS Security Check Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to perform basic security checks on an IIS server:
    • IIS version check
    • Web site enumeration
    • Default web page detection
    • Directory browsing check
    • HTTP response header analysis
    • SSL/TLS configuration check
  3. Option to set a target server (local or remote)
  4. HTML report generation for easy sharing and viewing of results

Key features:

  • Basic enumeration of IIS configuration
  • Detection of potentially risky settings like enabled directory browsing
  • Analysis of SSL/TLS protocols in use
  • Identification of default web pages that should be removed in production

Important notes:

  1. This tool is for educational purposes only and should not be used for actual penetration testing without proper authorization.
  2. It performs only basic checks and is not a comprehensive security assessment tool.
  3. Always ensure you have explicit permission before running any security checks on systems you don’t own.
  4. Some checks may require administrator privileges on the target server.
  5. Use this tool responsibly and ethically.

To use this script:

  1. Run PowerShell as an administrator
  2. Ensure you have the necessary permissions on the target server
  3. Use caution when testing on production systems

Remember, this is a simple tool for educational purposes. Real penetration testing and security assessments should be performed by trained professionals using comprehensive, up-to-date tools and methodologies.

Web Server Security Toolkit

<#
.SYNOPSIS
Web Server Security Toolkit

.DESCRIPTION
This script provides a comprehensive set of tools for analyzing and enhancing the security of web servers,
with a focus on IIS (Internet Information Services).

.NOTES
File Name      : WebServerSecurityToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights, IIS installed
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\WebServerSecurityToolkit.ps1
#>

# Import required modules
Import-Module WebAdministration
Import-Module IISAdministration

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

function Show-Menu {
    Clear-Host
    Write-Host "=== Web Server Security Toolkit ===" -ForegroundColor Cyan
    Write-Host "1.  Analyze IIS Configuration"
    Write-Host "2.  Check SSL/TLS Configuration"
    Write-Host "3.  Review Web Application Firewall (WAF) Settings"
    Write-Host "4.  Analyze HTTP Response Headers"
    Write-Host "5.  Check File and Folder Permissions"
    Write-Host "6.  Review Application Pool Settings"
    Write-Host "7.  Analyze Logging and Auditing Configuration"
    Write-Host "8.  Check for Unnecessary Services and Features"
    Write-Host "9.  Review Authentication Methods"
    Write-Host "10. Analyze Network Security Settings"
    Write-Host "11. Check for Common Vulnerabilities"
    Write-Host "12. Generate Comprehensive HTML Report"
    Write-Host "13. Exit"
}

function Analyze-IISConfiguration {
    Write-Host "`nAnalyzing IIS Configuration..." -ForegroundColor Yellow
    try {
        $iisVersion = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\InetStp"
        $websites = Get-Website
        $appPools = Get-IISAppPool

        $result = [PSCustomObject]@{
            IISVersion = "$($iisVersion.MajorVersion).$($iisVersion.MinorVersion)"
            WebsitesCount = $websites.Count
            AppPoolsCount = $appPools.Count
            DefaultWebsiteEnabled = (Get-Website "Default Web Site").State -eq "Started"
        }

        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error analyzing IIS configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Check-SSLTLSConfiguration {
    Write-Host "`nChecking SSL/TLS Configuration..." -ForegroundColor Yellow
    try {
        $sslProtocols = @("SSL 2.0", "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2")
        $results = @()

        foreach ($protocol in $sslProtocols) {
            $clientPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$protocol\Client"
            $serverPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$protocol\Server"
            
            $clientEnabled = (Get-ItemProperty -Path $clientPath -Name "Enabled" -ErrorAction SilentlyContinue).Enabled
            $serverEnabled = (Get-ItemProperty -Path $serverPath -Name "Enabled" -ErrorAction SilentlyContinue).Enabled

            $results += [PSCustomObject]@{
                Protocol = $protocol
                ClientEnabled = if ($clientEnabled -eq 0) { "Disabled" } elseif ($clientEnabled -eq 1) { "Enabled" } else { "Not Configured" }
                ServerEnabled = if ($serverEnabled -eq 0) { "Disabled" } elseif ($serverEnabled -eq 1) { "Enabled" } else { "Not Configured" }
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking SSL/TLS configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Review-WAFSettings {
    Write-Host "`nReviewing Web Application Firewall (WAF) Settings..." -ForegroundColor Yellow
    Write-Host "Note: This function checks for common WAF solutions. Actual WAF may vary." -ForegroundColor Yellow
    
    try {
        $wafPresent = $false
        $wafInfo = [PSCustomObject]@{
            WAFDetected = $false
            WAFType = "Unknown"
            Status = "Not Installed"
        }

        # Check for common WAF solutions (this is a simplified check and may need to be adapted)
        if (Get-Service "MicrosoftAzureApplicationGateway" -ErrorAction SilentlyContinue) {
            $wafPresent = $true
            $wafInfo.WAFDetected = $true
            $wafInfo.WAFType = "Azure Application Gateway"
            $wafInfo.Status = "Installed"
        }
        elseif (Get-Website "ARR_*" -ErrorAction SilentlyContinue) {
            $wafPresent = $true
            $wafInfo.WAFDetected = $true
            $wafInfo.WAFType = "Application Request Routing (Potential WAF)"
            $wafInfo.Status = "Installed"
        }

        if (-not $wafPresent) {
            Write-Host "No common WAF solution detected. Manual verification recommended." -ForegroundColor Yellow
        }

        $wafInfo | Format-List
        return $wafInfo
    }
    catch {
        Write-Host "Error reviewing WAF settings: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-HTTPResponseHeaders {
    Write-Host "`nAnalyzing HTTP Response Headers..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $headers = Get-WebConfiguration "/system.webServer/httpProtocol/customHeaders" -PSPath "IIS:\Sites\$($site.Name)"
            $securityHeaders = @(
                "X-Frame-Options",
                "X-XSS-Protection",
                "X-Content-Type-Options",
                "Strict-Transport-Security",
                "Content-Security-Policy",
                "Referrer-Policy"
            )

            $presentHeaders = $headers.Collection | Where-Object { $securityHeaders -contains $_.Name } | Select-Object Name, Value

            $results += [PSCustomObject]@{
                Website = $site.Name
                PresentSecurityHeaders = ($presentHeaders | ForEach-Object { "$($_.Name): $($_.Value)" }) -join ", "
                MissingSecurityHeaders = ($securityHeaders | Where-Object { $_ -notin $presentHeaders.Name }) -join ", "
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing HTTP response headers: $_" -ForegroundColor Red
        return $null
    }
}

function Check-FileAndFolderPermissions {
    Write-Host "`nChecking File and Folder Permissions..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $physicalPath = $site.PhysicalPath -replace "%SystemDrive%", $env:SystemDrive
            $acl = Get-Acl $physicalPath
            $permissions = $acl.Access | Select-Object IdentityReference, FileSystemRights

            $results += [PSCustomObject]@{
                Website = $site.Name
                PhysicalPath = $physicalPath
                Permissions = ($permissions | ForEach-Object { "$($_.IdentityReference): $($_.FileSystemRights)" }) -join "; "
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking file and folder permissions: $_" -ForegroundColor Red
        return $null
    }
}

function Review-ApplicationPoolSettings {
    Write-Host "`nReviewing Application Pool Settings..." -ForegroundColor Yellow
    try {
        $appPools = Get-IISAppPool
        $results = @()

        foreach ($pool in $appPools) {
            $results += [PSCustomObject]@{
                Name = $pool.Name
                ManagedRuntimeVersion = $pool.ManagedRuntimeVersion
                IdentityType = $pool.ProcessModel.IdentityType
                IdleTimeout = $pool.ProcessModel.IdleTimeout
                LoadUserProfile = $pool.ProcessModel.LoadUserProfile
                MaxProcesses = $pool.ProcessModel.MaxProcesses
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error reviewing application pool settings: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-LoggingAndAuditingConfiguration {
    Write-Host "`nAnalyzing Logging and Auditing Configuration..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $logFile = Get-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST/$($site.Name)"  -filter "system.applicationHost/sites/site[@name='$($site.Name)']/logFile" -name *
            
            $results += [PSCustomObject]@{
                Website = $site.Name
                LoggingEnabled = $logFile.enabled
                LogFormat = $logFile.logFormat
                Directory = $logFile.directory
                Period = $logFile.period
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error analyzing logging and auditing configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Check-UnnecessaryServicesAndFeatures {
    Write-Host "`nChecking for Unnecessary Services and Features..." -ForegroundColor Yellow
    try {
        $unnecessaryFeatures = @(
            "IIS-WebDAV",
            "IIS-ASPNET45",
            "IIS-ASP",
            "IIS-CGI",
            "IIS-ServerSideIncludes"
        )

        $installedFeatures = Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq "Enabled" }
        $results = @()

        foreach ($feature in $unnecessaryFeatures) {
            $installed = $installedFeatures | Where-Object { $_.FeatureName -eq $feature }
            $results += [PSCustomObject]@{
                Feature = $feature
                Installed = if ($installed) { $true } else { $false }
                Recommendation = if ($installed) { "Consider removing if not needed" } else { "Not installed (Good)" }
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error checking unnecessary services and features: $_" -ForegroundColor Red
        return $null
    }
}

function Review-AuthenticationMethods {
    Write-Host "`nReviewing Authentication Methods..." -ForegroundColor Yellow
    try {
        $websites = Get-Website
        $results = @()

        foreach ($site in $websites) {
            $authMethods = @(
                "anonymousAuthentication",
                "basicAuthentication",
                "windowsAuthentication",
                "digestAuthentication"
            )

            $enabledMethods = @()

            foreach ($method in $authMethods) {
                $config = Get-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST/$($site.Name)"  -filter "system.webServer/security/authentication/$method" -name "enabled"
                if ($config.Value) {
                    $enabledMethods += $method
                }
            }

            $results += [PSCustomObject]@{
                Website = $site.Name
                EnabledAuthMethods = $enabledMethods -join ", "
            }
        }

        $results | Format-Table -AutoSize
        return $results
    }
    catch {
        Write-Host "Error reviewing authentication methods: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-NetworkSecuritySettings {
    Write-Host "`nAnalyzing Network Security Settings..." -ForegroundColor Yellow
    try {
        $firewallRules = Get-NetFirewallRule | Where-Object { $_.Enabled -and ($_.Direction -eq "Inbound") }
        $openPorts = Get-NetTCPConnection | Where-Object { $_.State -eq "Listen" } | Select-Object LocalPort -Unique

        $results = [PSCustomObject]@{
            FirewallRulesCount = $firewallRules.Count
            OpenPorts = ($openPorts.LocalPort | Sort-Object) -join ", "
        }

        $results | Format-List
        return $results
    }
    catch {
        Write-Host "Error analyzing network security settings: $_" -ForegroundColor Red
        return $null
    }
}

function Check-CommonVulnerabilities {
    Write-Host "`nChecking for Common Vulnerabilities..." -ForegroundColor Yellow
    try {
        $vulnerabilities = @()

        # Check for directory browsing
        $dirBrowsing = Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/directoryBrowse" -name "enabled"
        if ($dirBrowsing.Value) {
            $vulnerabilities += "Directory browsing is enabled"
        }

        # Check for potentially dangerous HTTP methods
        $webDAV = Get-WindowsOptionalFeature -Online -FeatureName IIS-WebDAV
        if ($webDAV.State -eq "Enabled") {
            $vulnerabilities += "WebDAV is enabled, which allows potentially dangerous HTTP methods"
        }

        # Check for default documents
        $defaultDocs = Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/defaultDocument/files/add" -name "value"
        if ($defaultDocs.Value -contains "iisstart.htm") {
            $vulnerabilities += "Default IIS start page is present"
        }

        if ($vulnerabilities.Count -eq 0) {
            Write-Host "No common vulnerabilities detected." -ForegroundColor Green
        } else {
            Write-Host "Vulnerabilities detected:" -ForegroundColor Red
            $vulnerabilities | ForEach-Object { Write-Host "- $_" -ForegroundColor Yellow }
        }

        return $vulnerabilities
    }
    catch {
        Write-Host "Error checking for common vulnerabilities: $_" -ForegroundColor Red
        return $null
    }
}

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>Web Server Security 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; }
        .warning { color: orange; }
        .critical { color: red; }
    </style>
</head>
<body>
    <h1>Web Server Security Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

    <h2>IIS Configuration</h2>
    $($AllResults.IISConfig | ConvertTo-Html -Fragment)

    <h2>SSL/TLS Configuration</h2>
    $($AllResults.SSLTLSConfig | ConvertTo-Html -Fragment)

    <h2>WAF Settings</h2>
    $($AllResults.WAFSettings | ConvertTo-Html -Fragment)

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

    <h2>File and Folder Permissions</h2>
    $($AllResults.Permissions | ConvertTo-Html -Fragment)

    <h2>Application Pool Settings</h2>
    $($AllResults.AppPoolSettings | ConvertTo-Html -Fragment)

    <h2>Logging and Auditing Configuration</h2>
    $($AllResults.LoggingConfig | ConvertTo-Html -Fragment)

    <h2>Unnecessary Services and Features</h2>
    $($AllResults.UnnecessaryFeatures | ConvertTo-Html -Fragment)

    <h2>Authentication Methods</h2>
    $($AllResults.AuthMethods | ConvertTo-Html -Fragment)

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

    <h2>Common Vulnerabilities</h2>
    $($AllResults.Vulnerabilities | 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-13)"

    switch ($choice) {
        "1"  { $allResults.IISConfig = Analyze-IISConfiguration }
        "2"  { $allResults.SSLTLSConfig = Check-SSLTLSConfiguration }
        "3"  { $allResults.WAFSettings = Review-WAFSettings }
        "4"  { $allResults.HTTPHeaders = Analyze-HTTPResponseHeaders }
        "5"  { $allResults.Permissions = Check-FileAndFolderPermissions }
        "6"  { $allResults.AppPoolSettings = Review-ApplicationPoolSettings }
        "7"  { $allResults.LoggingConfig = Analyze-LoggingAndAuditingConfiguration }
        "8"  { $allResults.UnnecessaryFeatures = Check-UnnecessaryServicesAndFeatures }
        "9"  { $allResults.AuthMethods = Review-AuthenticationMethods }
        "10" { $allResults.NetworkSecurity = Analyze-NetworkSecuritySettings }
        "11" { $allResults.Vulnerabilities = Check-CommonVulnerabilities }
        "12" { Generate-HTMLReport -AllResults $allResults }
        "13" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Web Server Security Toolkit includes:

  1. A comprehensive menu-driven interface.
  2. Functions to analyze various aspects of web server security:
    • IIS Configuration Analysis
    • SSL/TLS Configuration Check
    • Web Application Firewall (WAF) Settings Review
    • HTTP Response Headers Analysis
    • File and Folder Permissions Check
    • Application Pool Settings Review
    • Logging and Auditing Configuration Analysis
    • Check for Unnecessary Services and Features
    • Authentication Methods Review
    • Network Security Settings Analysis
    • Common Vulnerabilities Check
  3. Comprehensive HTML report generation.

Key features:

  • Detailed analysis of IIS configuration and settings
  • SSL/TLS protocol and cipher suite checks
  • WAF detection and configuration review
  • Security-related HTTP header analysis
  • File system permissions audit for web directories
  • Application pool security configuration review
  • Logging and auditing settings analysis
  • Identification of potentially unnecessary or risky IIS features
  • Authentication method review across websites
  • Network security analysis including firewall rules and open ports
  • Common web server vulnerability checks
  • Comprehensive HTML report for all analyses

This tool is particularly useful for:

  • Web server administrators
  • Security professionals auditing web server configurations
  • IT professionals setting up or maintaining IIS servers
  • Anyone needing to assess the security posture of a web server

To use this script effectively:

  1. Run PowerShell as an administrator on the web server
  2. Ensure you have the necessary permissions to query IIS and system configurations
  3. Have the IIS PowerShell modules installed (WebAdministration and IISAdministration)
  4. Review the generated HTML report for a comprehensive overview of the web server’s security configuration

This script provides a thorough analysis of web server security settings, helping to identify potential vulnerabilities, misconfigurations, or areas for improvement in the server’s security posture. It’s designed to give administrators a comprehensive view of their web server’s security configuration and highlight areas that may need attention.

First ITIL Check Tool

<#
.SYNOPSIS
First ITIL Check Tool

.DESCRIPTION
This script provides a basic assessment of ITIL practices within an IT organization,
focusing on the five core areas of ITIL: Service Strategy, Service Design, Service Transition,
Service Operation, and Continual Service Improvement.

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

.EXAMPLE
.\FirstITILCheckTool.ps1
#>

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

<#
.SYNOPSIS
Displays the main menu of the tool.
#>
function Show-Menu {
    Clear-Host
    Write-Host "=== First ITIL Check Tool ===" -ForegroundColor Cyan
    Write-Host "1. Assess Service Strategy"
    Write-Host "2. Assess Service Design"
    Write-Host "3. Assess Service Transition"
    Write-Host "4. Assess Service Operation"
    Write-Host "5. Assess Continual Service Improvement"
    Write-Host "6. Generate Comprehensive HTML Report"
    Write-Host "7. Exit"
}

<#
.SYNOPSIS
Conducts an assessment based on provided questions.

.PARAMETER AreaName
The name of the ITIL area being assessed.

.PARAMETER Questions
An array of questions for the assessment.

.OUTPUTS
PSObject containing assessment results.
#>
function Conduct-Assessment {
    param (
        [string]$AreaName,
        [array]$Questions
    )

    Write-Host "`nAssessing $AreaName..." -ForegroundColor Yellow
    $results = @()

    foreach ($question in $Questions) {
        $response = Read-Host "$question (Y/N)"
        $score = if ($response.ToLower() -eq 'y') { 1 } else { 0 }
        $results += [PSCustomObject]@{
            Question = $question
            Implemented = if ($score -eq 1) { "Yes" } else { "No" }
        }
    }

    $implementedCount = ($results | Where-Object { $_.Implemented -eq "Yes" }).Count
    $totalQuestions = $Questions.Count
    $percentageImplemented = [math]::Round(($implementedCount / $totalQuestions) * 100, 2)

    $assessmentSummary = [PSCustomObject]@{
        Area = $AreaName
        ImplementedPractices = $implementedCount
        TotalPractices = $totalQuestions
        PercentageImplemented = $percentageImplemented
    }

    $results | Format-Table -AutoSize
    $assessmentSummary | Format-Table -AutoSize

    return @{
        Details = $results
        Summary = $assessmentSummary
    }
}

<#
.SYNOPSIS
Assesses Service Strategy practices.
#>
function Assess-ServiceStrategy {
    $questions = @(
        "Is there a defined IT service strategy aligned with business goals?",
        "Are service portfolios maintained and regularly reviewed?",
        "Is there a process for demand management?",
        "Are financial management practices in place for IT services?",
        "Is there a defined approach for business relationship management?"
    )
    $global:assessmentResults.ServiceStrategy = Conduct-Assessment -AreaName "Service Strategy" -Questions $questions
}

<#
.SYNOPSIS
Assesses Service Design practices.
#>
function Assess-ServiceDesign {
    $questions = @(
        "Is there a formal process for designing new or changed services?",
        "Are service level agreements (SLAs) defined and managed?",
        "Is there a capacity management process in place?",
        "Is availability management considered in service design?",
        "Is there a formal IT service continuity management process?"
    )
    $global:assessmentResults.ServiceDesign = Conduct-Assessment -AreaName "Service Design" -Questions $questions
}

<#
.SYNOPSIS
Assesses Service Transition practices.
#>
function Assess-ServiceTransition {
    $questions = @(
        "Is there a formal change management process?",
        "Is there a process for managing service assets and configurations?",
        "Is release and deployment management formalized?",
        "Is knowledge management practiced and encouraged?",
        "Are service validations and testing performed before deployment?"
    )
    $global:assessmentResults.ServiceTransition = Conduct-Assessment -AreaName "Service Transition" -Questions $questions
}

<#
.SYNOPSIS
Assesses Service Operation practices.
#>
function Assess-ServiceOperation {
    $questions = @(
        "Is there a formal incident management process?",
        "Is problem management practiced to identify root causes?",
        "Is there a defined process for fulfilling service requests?",
        "Are events monitored and managed across IT infrastructure?",
        "Is access to IT services controlled and managed?"
    )
    $global:assessmentResults.ServiceOperation = Conduct-Assessment -AreaName "Service Operation" -Questions $questions
}

<#
.SYNOPSIS
Assesses Continual Service Improvement practices.
#>
function Assess-ContinualServiceImprovement {
    $questions = @(
        "Is there a process for continually identifying improvements?",
        "Are service performance metrics defined and monitored?",
        "Is customer feedback regularly collected and analyzed?",
        "Are improvement initiatives prioritized and implemented?",
        "Is there a process for reviewing and measuring improvement outcomes?"
    )
    $global:assessmentResults.ContinualServiceImprovement = Conduct-Assessment -AreaName "Continual Service Improvement" -Questions $questions
}

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

.OUTPUTS
Saves an HTML report to the desktop.
#>
function Generate-HTMLReport {
    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ITIL Assessment Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }
        h1, h2, 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; }
        .implemented { color: green; }
        .not-implemented { color: red; }
        .summary { font-weight: bold; }
    </style>
</head>
<body>
    <h1>ITIL Assessment Report</h1>
    <p>Generated on: $(Get-Date)</p>

"@

    foreach ($area in $global:assessmentResults.Keys) {
        $reportContent += @"
    <h2>$area</h2>
    <h3>Detailed Assessment</h3>
    <table>
        <tr>
            <th>Practice</th>
            <th>Implemented</th>
        </tr>
"@
        foreach ($detail in $global:assessmentResults[$area].Details) {
            $class = if ($detail.Implemented -eq "Yes") { "implemented" } else { "not-implemented" }
            $reportContent += @"
        <tr>
            <td>$($detail.Question)</td>
            <td class="$class">$($detail.Implemented)</td>
        </tr>
"@
        }
        $reportContent += @"
    </table>

    <h3>Summary</h3>
    <table>
        <tr>
            <th>Metric</th>
            <th>Value</th>
        </tr>
        <tr>
            <td>Implemented Practices</td>
            <td>$($global:assessmentResults[$area].Summary.ImplementedPractices)</td>
        </tr>
        <tr>
            <td>Total Practices</td>
            <td>$($global:assessmentResults[$area].Summary.TotalPractices)</td>
        </tr>
        <tr>
            <td>Percentage Implemented</td>
            <td class="summary">$($global:assessmentResults[$area].Summary.PercentageImplemented)%</td>
        </tr>
    </table>
"@
    }

    $reportContent += @"
</body>
</html>
"@

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

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

    switch ($choice) {
        "1" { Assess-ServiceStrategy }
        "2" { Assess-ServiceDesign }
        "3" { Assess-ServiceTransition }
        "4" { Assess-ServiceOperation }
        "5" { Assess-ContinualServiceImprovement }
        "6" { Generate-HTMLReport }
        "7" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This First ITIL Check Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to assess the five core areas of ITIL:
    • Service Strategy
    • Service Design
    • Service Transition
    • Service Operation
    • Continual Service Improvement
  3. A generic assessment function that can be used for all ITIL areas.
  4. HTML report generation for a comprehensive overview of the assessment.

Key features:

  • Simple yes/no questions for each ITIL area to assess implementation of key practices
  • Calculation of implementation percentage for each ITIL area
  • Detailed assessment results showing which practices are implemented
  • Summary view of implemented practices, total practices, and implementation percentage
  • Comprehensive HTML report generation with color-coded results

This tool is particularly useful for:

  • IT managers starting to implement ITIL practices
  • Organizations wanting to get a quick overview of their ITIL implementation status
  • IT professionals learning about ITIL and its key practices
  • Teams preparing for a more comprehensive ITIL assessment or certification

To use this script effectively:

  1. Run the script in PowerShell
  2. Go through each ITIL area assessment, answering the questions honestly
  3. Generate the HTML report for a visual representation of your ITIL implementation status

This script provides a basic starting point for assessing ITIL practices within an organization. It’s important to note that this is a simplified tool and doesn’t cover all aspects of ITIL. For a comprehensive ITIL assessment, it’s recommended to consult with ITIL experts or use more detailed assessment tools.

Advanced File and Folder Management Toolkit

<#
.SYNOPSIS
Advanced File and Folder Management Toolkit

.DESCRIPTION
This script provides a comprehensive set of tools for managing, analyzing, and manipulating files and folders.
It includes advanced features like recursive operations, detailed file analysis, and complex search capabilities.

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

.EXAMPLE
.\AdvancedFileAndFolderToolkit.ps1
#>

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

function Show-Menu {
    Clear-Host
    Write-Host "=== Advanced File and Folder Management Toolkit ===" -ForegroundColor Cyan
    Write-Host "Current Source Path: $global:sourcePath"
    Write-Host "Current Destination Path: $global:destinationPath"
    Write-Host "1.  Set Source Path"
    Write-Host "2.  Set Destination Path"
    Write-Host "3.  Copy Files/Folders"
    Write-Host "4.  Move Files/Folders"
    Write-Host "5.  Delete Files/Folders"
    Write-Host "6.  Rename Files/Folders"
    Write-Host "7.  Analyze Folder Structure"
    Write-Host "8.  Advanced File Search"
    Write-Host "9.  Compare Folders"
    Write-Host "10. Generate File Hashes"
    Write-Host "11. Analyze File Types"
    Write-Host "12. Find Duplicate Files"
    Write-Host "13. Compress Folder"
    Write-Host "14. Extract Archive"
    Write-Host "15. Set File Attributes"
    Write-Host "16. Generate Comprehensive HTML Report"
    Write-Host "17. Exit"
}

function Set-SourcePath {
    $path = Read-Host "Enter the source path"
    if (Test-Path -Path $path) {
        $global:sourcePath = $path
        Write-Host "Source path set to: $global:sourcePath" -ForegroundColor Green
    } else {
        Write-Host "Invalid path. Please try again." -ForegroundColor Red
    }
}

function Set-DestinationPath {
    $path = Read-Host "Enter the destination path"
    if (Test-Path -Path $path) {
        $global:destinationPath = $path
        Write-Host "Destination path set to: $global:destinationPath" -ForegroundColor Green
    } else {
        Write-Host "Invalid path. Please try again." -ForegroundColor Red
    }
}

function Copy-FilesAndFolders {
    if ([string]::IsNullOrEmpty($global:sourcePath) -or [string]::IsNullOrEmpty($global:destinationPath)) {
        Write-Host "Please set both source and destination paths first." -ForegroundColor Red
        return
    }

    Write-Host "`nCopying Files and Folders..." -ForegroundColor Yellow
    try {
        $items = Get-ChildItem -Path $global:sourcePath -Recurse
        $totalItems = $items.Count
        $copiedItems = 0

        foreach ($item in $items) {
            $targetPath = $item.FullName.Replace($global:sourcePath, $global:destinationPath)
            Copy-Item -Path $item.FullName -Destination $targetPath -Force
            $copiedItems++
            Write-Progress -Activity "Copying Files and Folders" -Status "$copiedItems of $totalItems copied" -PercentComplete (($copiedItems / $totalItems) * 100)
        }

        Write-Progress -Activity "Copying Files and Folders" -Completed
        Write-Host "Copy operation completed successfully." -ForegroundColor Green
    }
    catch {
        Write-Host "Error during copy operation: $_" -ForegroundColor Red
    }
}

function Move-FilesAndFolders {
    if ([string]::IsNullOrEmpty($global:sourcePath) -or [string]::IsNullOrEmpty($global:destinationPath)) {
        Write-Host "Please set both source and destination paths first." -ForegroundColor Red
        return
    }

    Write-Host "`nMoving Files and Folders..." -ForegroundColor Yellow
    try {
        $items = Get-ChildItem -Path $global:sourcePath -Recurse
        $totalItems = $items.Count
        $movedItems = 0

        foreach ($item in $items) {
            $targetPath = $item.FullName.Replace($global:sourcePath, $global:destinationPath)
            Move-Item -Path $item.FullName -Destination $targetPath -Force
            $movedItems++
            Write-Progress -Activity "Moving Files and Folders" -Status "$movedItems of $totalItems moved" -PercentComplete (($movedItems / $totalItems) * 100)
        }

        Write-Progress -Activity "Moving Files and Folders" -Completed
        Write-Host "Move operation completed successfully." -ForegroundColor Green
    }
    catch {
        Write-Host "Error during move operation: $_" -ForegroundColor Red
    }
}

function Delete-FilesAndFolders {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    $confirmation = Read-Host "Are you sure you want to delete the contents of $global:sourcePath? (Y/N)"
    if ($confirmation -eq "Y") {
        Write-Host "`nDeleting Files and Folders..." -ForegroundColor Yellow
        try {
            $items = Get-ChildItem -Path $global:sourcePath -Recurse
            $totalItems = $items.Count
            $deletedItems = 0

            foreach ($item in $items) {
                Remove-Item -Path $item.FullName -Force -Recurse
                $deletedItems++
                Write-Progress -Activity "Deleting Files and Folders" -Status "$deletedItems of $totalItems deleted" -PercentComplete (($deletedItems / $totalItems) * 100)
            }

            Write-Progress -Activity "Deleting Files and Folders" -Completed
            Write-Host "Delete operation completed successfully." -ForegroundColor Green
        }
        catch {
            Write-Host "Error during delete operation: $_" -ForegroundColor Red
        }
    }
    else {
        Write-Host "Delete operation cancelled." -ForegroundColor Yellow
    }
}

function Rename-FilesAndFolders {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    $pattern = Read-Host "Enter the current name pattern (use * for wildcards)"
    $replacement = Read-Host "Enter the new name pattern"
    
    Write-Host "`nRenaming Files and Folders..." -ForegroundColor Yellow
    try {
        $items = Get-ChildItem -Path $global:sourcePath -Recurse -Filter $pattern
        $totalItems = $items.Count
        $renamedItems = 0

        foreach ($item in $items) {
            $newName = $item.Name -replace $pattern, $replacement
            Rename-Item -Path $item.FullName -NewName $newName
            $renamedItems++
            Write-Progress -Activity "Renaming Files and Folders" -Status "$renamedItems of $totalItems renamed" -PercentComplete (($renamedItems / $totalItems) * 100)
        }

        Write-Progress -Activity "Renaming Files and Folders" -Completed
        Write-Host "Rename operation completed successfully." -ForegroundColor Green
    }
    catch {
        Write-Host "Error during rename operation: $_" -ForegroundColor Red
    }
}

function Analyze-FolderStructure {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    Write-Host "`nAnalyzing Folder Structure..." -ForegroundColor Yellow
    try {
        $analysis = Get-ChildItem -Path $global:sourcePath -Recurse | Measure-Object -Property Length -Sum
        $largestFiles = Get-ChildItem -Path $global:sourcePath -Recurse -File | Sort-Object Length -Descending | Select-Object -First 10
        $oldestFiles = Get-ChildItem -Path $global:sourcePath -Recurse -File | Sort-Object CreationTime | Select-Object -First 10
        $newestFiles = Get-ChildItem -Path $global:sourcePath -Recurse -File | Sort-Object CreationTime -Descending | Select-Object -First 10

        $result = [PSCustomObject]@{
            TotalFiles = $analysis.Count
            TotalSize = "{0:N2} MB" -f ($analysis.Sum / 1MB)
            Directories = (Get-ChildItem -Path $global:sourcePath -Directory -Recurse).Count
            AverageFileSize = "{0:N2} KB" -f (($analysis.Sum / $analysis.Count) / 1KB)
            LargestFiles = $largestFiles | Select-Object Name, @{Name="Size(MB)"; Expression={"{0:N2}" -f ($_.Length / 1MB)}}
            OldestFiles = $oldestFiles | Select-Object Name, CreationTime
            NewestFiles = $newestFiles | Select-Object Name, CreationTime
        }
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error during folder analysis: $_" -ForegroundColor Red
        return $null
    }
}

function Advanced-FileSearch {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    $searchPattern = Read-Host "Enter the search pattern (e.g., *.txt)"
    $contentSearch = Read-Host "Enter content to search for (optional)"
    $minSize = Read-Host "Enter minimum file size in bytes (optional)"
    $maxSize = Read-Host "Enter maximum file size in bytes (optional)"
    $afterDate = Read-Host "Enter 'after' date (yyyy-MM-dd) (optional)"
    $beforeDate = Read-Host "Enter 'before' date (yyyy-MM-dd) (optional)"

    Write-Host "`nPerforming Advanced File Search..." -ForegroundColor Yellow
    try {
        $searchParams = @{
            Path = $global:sourcePath
            Recurse = $true
            File = $true
        }

        if ($searchPattern) { $searchParams.Filter = $searchPattern }
        if ($minSize) { $searchParams.MinimumSize = [long]$minSize }
        if ($maxSize) { $searchParams.MaximumSize = [long]$maxSize }
        if ($afterDate) { $searchParams.CreationTimeStart = [datetime]::ParseExact($afterDate, "yyyy-MM-dd", $null) }
        if ($beforeDate) { $searchParams.CreationTimeEnd = [datetime]::ParseExact($beforeDate, "yyyy-MM-dd", $null) }

        $results = Get-ChildItem @searchParams

        if ($contentSearch) {
            $results = $results | Where-Object { Get-Content $_.FullName -Raw | Select-String -Pattern $contentSearch -Quiet }
        }

        $results | Format-Table Name, LastWriteTime, Length -AutoSize
        return $results
    }
    catch {
        Write-Host "Error during advanced file search: $_" -ForegroundColor Red
        return $null
    }
}

function Compare-Folders {
    if ([string]::IsNullOrEmpty($global:sourcePath) -or [string]::IsNullOrEmpty($global:destinationPath)) {
        Write-Host "Please set both source and destination paths first." -ForegroundColor Red
        return
    }

    Write-Host "`nComparing Folders..." -ForegroundColor Yellow
    try {
        $comparison = Compare-Object -ReferenceObject (Get-ChildItem -Path $global:sourcePath -Recurse) -DifferenceObject (Get-ChildItem -Path $global:destinationPath -Recurse) -Property Name, Length, LastWriteTime
        if ($comparison) {
            $comparison | Format-Table Name, Length, LastWriteTime, @{Label="Status"; Expression={if ($_.SideIndicator -eq "<=") {"Only in Source"} else {"Only in Destination"}}} -AutoSize
        } else {
            Write-Host "The folders are identical." -ForegroundColor Green
        }
        return $comparison
    }
    catch {
        Write-Host "Error during folder comparison: $_" -ForegroundColor Red
        return $null
    }
}

function Generate-FileHashes {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    Write-Host "`nGenerating File Hashes..." -ForegroundColor Yellow
    try {
        $files = Get-ChildItem -Path $global:sourcePath -Recurse -File
        $hashes = @()
        foreach ($file in $files) {
            $hash = Get-FileHash -Path $file.FullName -Algorithm SHA256
            $hashes += [PSCustomObject]@{
                FileName = $file.Name
                FilePath = $file.FullName
                FileHash = $hash.Hash
            }
        }
        $hashes | Format-Table -AutoSize
        return $hashes
    }
    catch {
        Write-Host "Error generating file hashes: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-FileTypes {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    Write-Host "`nAnalyzing File Types..." -ForegroundColor Yellow
    try {
        $files = Get-ChildItem -Path $global:sourcePath -Recurse -File
        $fileTypes = $files | Group-Object Extension | Sort-Object Count -Descending | Select-Object Name, Count, @{Name="TotalSize(MB)"; Expression={"{0:N2}" -f (($_.Group | Measure-Object Length -Sum).Sum / 1MB)}}
        $fileTypes | Format-Table -AutoSize
        return $fileTypes
    }
    catch {
        Write-Host "Error analyzing file types: $_" -ForegroundColor Red
        return $null
    }
}

function Find-DuplicateFiles {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    Write-Host "`nFinding Duplicate Files..." -ForegroundColor Yellow
    try {
        $files = Get-ChildItem -Path $global:sourcePath -Recurse -File
        $hashes = @{}
        $duplicates = @()

        foreach ($file in $files) {
            $hash = Get-FileHash -Path $file.FullName -Algorithm SHA256
            if ($hashes.ContainsKey($hash.Hash)) {
                $duplicates += [PSCustomObject]@{
                    OriginalFile = $hashes[$hash.Hash]
                    DuplicateFile = $file.FullName
                    FileHash = $hash.Hash
                }
            } else {
                $hashes[$hash.Hash] = $file.FullName
            }
        }

        if ($duplicates.Count -eq 0) {
            Write-Host "No duplicate files found." -ForegroundColor Green
        } else {
            $duplicates | Format-Table -AutoSize
        }
        return $duplicates
    }
    catch {
        Write-Host "Error finding duplicate files: $_" -ForegroundColor Red
        return $null
    }
}

function Compress-Folder {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    $archivePath = Read-Host "Enter the path for the compressed file (including filename.zip)"
    
    Write-Host "`nCompressing Folder..." -ForegroundColor Yellow
    try {
        Compress-Archive -Path $global:sourcePath -DestinationPath $archivePath -Force
        Write-Host "Folder compressed successfully to: $archivePath" -ForegroundColor Green
    }
    catch {
        Write-Host "Error compressing folder: $_" -ForegroundColor Red
    }
}

function Extract-Archive {
    $archivePath = Read-Host "Enter the path of the archive to extract"
    $extractPath = Read-Host "Enter the extraction destination path"

    Write-Host "`nExtracting Archive..." -ForegroundColor Yellow
    try {
        Expand-Archive -Path $archivePath -DestinationPath $extractPath -Force
        Write-Host "Archive extracted successfully to: $extractPath" -ForegroundColor Green
    }
    catch {
        Write-Host "Error extracting archive: $_" -ForegroundColor Red
    }
}

function Set-FileAttributes {
    if ([string]::IsNullOrEmpty($global:sourcePath)) {
        Write-Host "Please set the source path first." -ForegroundColor Red
        return
    }

    $attributes = Read-Host "Enter attributes to set (e.g., ReadOnly, Hidden, Archive)"
    
    Write-Host "`nSetting File Attributes..." -ForegroundColor Yellow
    try {
        $files = Get-ChildItem -Path $global:sourcePath -Recurse -File
        foreach ($file in $files) {
            $file.Attributes = $attributes
        }
        Write-Host "File attributes set successfully." -ForegroundColor Green
    }
    catch {
        Write-Host "Error setting file attributes: $_" -ForegroundColor Red
    }
}

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>Advanced File and Folder 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>Advanced File and Folder Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>Source Path: $global:sourcePath</p>
    <p>Destination Path: $global:destinationPath</p>

    <h2>Folder Structure Analysis</h2>
    $($AllResults.FolderAnalysis | ConvertTo-Html -Fragment)

    <h2>File Search Results</h2>
    $($AllResults.FileSearch | ConvertTo-Html -Fragment)

    <h2>Folder Comparison</h2>
    $($AllResults.FolderComparison | ConvertTo-Html -Fragment)

    <h2>File Hashes</h2>
    $($AllResults.FileHashes | ConvertTo-Html -Fragment)

    <h2>File Type Analysis</h2>
    $($AllResults.FileTypes | ConvertTo-Html -Fragment)

    <h2>Duplicate Files</h2>
    $($AllResults.DuplicateFiles | 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-17)"

    switch ($choice) {
        "1" { Set-SourcePath }
        "2" { Set-DestinationPath }
        "3" { Copy-FilesAndFolders }
        "4" { Move-FilesAndFolders }
        "5" { Delete-FilesAndFolders }
        "6" { Rename-FilesAndFolders }
        "7" { $allResults.FolderAnalysis = Analyze-FolderStructure }
        "8" { $allResults.FileSearch = Advanced-FileSearch }
        "9" { $allResults.FolderComparison = Compare-Folders }
        "10" { $allResults.FileHashes = Generate-FileHashes }
        "11" { $allResults.FileTypes = Analyze-FileTypes }
        "12" { $allResults.DuplicateFiles = Find-DuplicateFiles }
        "13" { Compress-Folder }
        "14" { Extract-Archive }
        "15" { Set-FileAttributes }
        "16" { Generate-HTMLReport -AllResults $allResults }
        "17" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This Advanced File and Folder Management Toolkit includes:

  1. A comprehensive menu-driven interface.
  2. Advanced functions for file and folder operations:
    • Recursive copy, move, and delete operations with progress bars
    • Pattern-based file and folder renaming
    • Detailed folder structure analysis
    • Advanced file search with multiple criteria
    • Folder comparison
    • File hash generation
    • File type analysis
    • Duplicate file detection
    • Folder compression and archive extraction
    • File attribute setting
  3. Comprehensive HTML report generation.

Key features:

  • Flexible path setting for source and destination
  • Advanced file operations with progress tracking
  • Detailed folder analysis including largest and oldest/newest files
  • Complex file search capabilities (pattern, content, size, date)
  • File type distribution analysis
  • Duplicate file detection using hash comparison
  • Built-in compression and extraction tools
  • File attribute manipulation
  • Comprehensive HTML report for all analyses

This tool is particularly useful for:

  • System administrators managing complex file systems
  • IT professionals performing advanced file and folder operations
  • Data analysts needing to understand file distributions and duplicates
  • Anyone requiring detailed file system analysis and management capabilities

To use this script effectively:

  1. Run PowerShell with appropriate permissions to access and modify the file system
  2. Set the source and destination paths before performing operations
  3. Use caution with delete and rename operations, as they can be irreversible
  4. Review the generated HTML report for a comprehensive overview of all analyses

This advanced script provides a powerful set of tools for file and folder management and analysis, suitable for both routine tasks and complex file system operations. It offers detailed insights into file structures, helps identify issues like duplicates, and provides utilities for efficient file management.

Script Template for PowerShell

<#
.SYNOPSIS
    Brief description of what the script does.

.DESCRIPTION
    Detailed description of the script's purpose and functionality.

.PARAMETER ParamName1
    Description of the first parameter.

.PARAMETER ParamName2
    Description of the second parameter.

.EXAMPLE
    Example-1: .\ScriptName.ps1 -ParamName1 Value1 -ParamName2 Value2
    Description of what this example does.

.EXAMPLE
    Example-2: .\ScriptName.ps1 -ParamName1 Value3
    Description of what this example does.

.NOTES
    File Name      : ScriptName.ps1
    Author         : Your Name
    Prerequisite   : PowerShell V3 or later
    Copyright      : (c) 2023 Your Company. All rights reserved.

.LINK
    Script posted over:
    http://www.your-website.com

#>

#Requires -Version 3.0
#Requires -Modules ActiveDirectory, Exchange
#Requires -RunAsAdministrator

[CmdletBinding()]
param (
    [Parameter(Mandatory=$true, 
               ValueFromPipeline=$true,
               ValueFromPipelineByPropertyName=$true, 
               ValueFromRemainingArguments=$false, 
               Position=0,
               HelpMessage="Enter the first parameter value.")]
    [ValidateNotNullOrEmpty()]
    [Alias("PN1")]
    [string]$ParamName1,

    [Parameter(Mandatory=$false)]
    [int]$ParamName2 = 0
)

Begin {
    # Initialize variables, import modules, define functions
    Set-StrictMode -Version Latest
    $ErrorActionPreference = "Stop"

    # Log file setup
    $LogFile = "C:\Logs\ScriptName_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
    
    function Write-Log {
        param([string]$Message)
        $LogMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): $Message"
        Add-Content -Path $LogFile -Value $LogMessage
        Write-Verbose $LogMessage
    }

    Write-Log "Script started"
}

Process {
    try {
        # Main script logic goes here
        Write-Log "Processing started"

        # Your code here

        Write-Log "Processing completed"
    }
    catch {
        Write-Log "An error occurred: $_"
        throw $_
    }
}

End {
    # Cleanup operations
    Write-Log "Script completed"
}

This template includes:

  1. A comprehensive comment-based help section at the beginning, which provides information about the script’s purpose, parameters, examples, and more.
  2. #Requires statements to specify prerequisites like PowerShell version, required modules, or administrator rights.
  3. [CmdletBinding()] attribute to make the script behave like a cmdlet.
  4. Parameter block with examples of mandatory and optional parameters, including parameter attributes.
  5. Begin, Process, and End blocks to structure the script’s execution.
  6. Error handling with try-catch blocks.
  7. Logging functionality to keep track of the script’s execution.
  8. Use of Set-StrictMode and $ErrorActionPreference for better error detection and handling.

You can customize this template based on your specific needs, adding or removing sections as necessary for your script.

Email Validation Toolkit

# Email Validation Toolkit

# Function to validate email using a simple regex pattern
function Test-EmailSimple {
    param (
        [Parameter(Mandatory=$true)]
        [string]$Email
    )
    
    $regex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    return $Email -match $regex
}

# Function to validate email using a more comprehensive regex pattern
function Test-EmailComprehensive {
    param (
        [Parameter(Mandatory=$true)]
        [string]$Email
    )
    
    $regex = "^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"
    return $Email -match $regex
}

# Function to validate email with domain check
function Test-EmailWithDomain {
    param (
        [Parameter(Mandatory=$true)]
        [string]$Email
    )
    
    $regex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    if ($Email -match $regex) {
        $domain = ($Email -split "@")[1]
        if (Resolve-DnsName -Name $domain -ErrorAction SilentlyContinue) {
            return $true
        }
    }
    return $false
}

# Function to validate multiple emails
function Test-MultipleEmails {
    param (
        [Parameter(Mandatory=$true)]
        [string[]]$Emails,
        [Parameter(Mandatory=$false)]
        [ValidateSet("Simple", "Comprehensive", "WithDomain")]
        [string]$Method = "Simple"
    )
    
    $results = @()
    foreach ($email in $Emails) {
        switch ($Method) {
            "Simple" { $isValid = Test-EmailSimple -Email $email }
            "Comprehensive" { $isValid = Test-EmailComprehensive -Email $email }
            "WithDomain" { $isValid = Test-EmailWithDomain -Email $email }
        }
        $results += [PSCustomObject]@{
            Email = $email
            IsValid = $isValid
        }
    }
    return $results
}

# Function to extract emails from text
function Get-EmailsFromText {
    param (
        [Parameter(Mandatory=$true)]
        [string]$Text
    )
    
    $regex = "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"
    return $Text | Select-String -Pattern $regex -AllMatches | ForEach-Object { $_.Matches.Value }
}

# Example usage
$testEmails = @(
    "user@example.com",
    "invalid.email@",
    "another.user@example.co.uk",
    "not_an_email"
)

Write-Host "Simple Validation:"
Test-MultipleEmails -Emails $testEmails -Method Simple | Format-Table

Write-Host "`nComprehensive Validation:"
Test-MultipleEmails -Emails $testEmails -Method Comprehensive | Format-Table

Write-Host "`nValidation with Domain Check:"
Test-MultipleEmails -Emails $testEmails -Method WithDomain | Format-Table

$sampleText = "Contact us at support@example.com or sales@company.co.uk for more information."
Write-Host "`nExtracting emails from text:"
Get-EmailsFromText -Text $sampleText

This toolkit includes the following functions:

  1. Test-EmailSimple: Uses a simple regex pattern to validate email addresses.
  2. Test-EmailComprehensive: Uses a more comprehensive regex pattern for stricter validation.
  3. Test-EmailWithDomain: Validates the email format and checks if the domain exists.
  4. Test-MultipleEmails: Validates multiple email addresses using one of the above methods.
  5. Get-EmailsFromText: Extracts email addresses from a given text.

To use this toolkit, you can copy and paste the entire script into a PowerShell file (e.g., EmailValidationToolkit.ps1) and then dot-source it in your PowerShell session:

. .\EmailValidationToolkit.ps1

RDS License Audit Toolkit

<#
.SYNOPSIS
RDS License Audit Toolkit

.DESCRIPTION
This script performs a comprehensive audit of Remote Desktop Services (RDS) licensing,
including license server configuration, available licenses, and usage statistics.

.NOTES
File Name      : RDSLicenseAuditToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights, and RDS management tools
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\RDSLicenseAuditToolkit.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\RDS_License_Audit_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:licenseServer = $env:COMPUTERNAME  # Default to local machine

function Show-Menu {
    Clear-Host
    Write-Host "=== RDS License Audit Toolkit ===" -ForegroundColor Cyan
    Write-Host "Current License Server: $global:licenseServer"
    Write-Host "1. Set License Server"
    Write-Host "2. Check License Server Configuration"
    Write-Host "3. List Available Licenses"
    Write-Host "4. Analyze License Usage"
    Write-Host "5. Check RDS Server Configuration"
    Write-Host "6. Verify CAL Compliance"
    Write-Host "7. Review License Policies"
    Write-Host "8. Check License Server Health"
    Write-Host "9. Generate Comprehensive HTML Report"
    Write-Host "10. Exit"
}

function Set-LicenseServer {
    $server = Read-Host "Enter the RDS License Server name (or press Enter for localhost)"
    if ([string]::IsNullOrWhiteSpace($server)) {
        $global:licenseServer = $env:COMPUTERNAME
    } else {
        $global:licenseServer = $server
    }
    Write-Host "License server set to: $global:licenseServer" -ForegroundColor Green
}

function Check-LicenseServerConfiguration {
    Write-Host "`nChecking License Server Configuration..." -ForegroundColor Yellow
    try {
        $config = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $serverInfo = Get-RDLicenseConfiguration
            $serverStatus = Get-RDLicenseServerStatus
            return @{
                ServerInfo = $serverInfo
                ServerStatus = $serverStatus
            }
        }
        
        $result = [PSCustomObject]@{
            Mode = $config.ServerInfo.Mode
            LicensingType = $config.ServerInfo.LicensingType
            IsActivated = $config.ServerStatus.IsActivated
            LastIssuedLicenseDate = $config.ServerStatus.LastIssuedLicenseDate
            GracePeriodDays = $config.ServerStatus.GracePeriodDays
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error checking license server configuration: $_" -ForegroundColor Red
        return $null
    }
}

function List-AvailableLicenses {
    Write-Host "`nListing Available Licenses..." -ForegroundColor Yellow
    try {
        $licenses = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            Get-RDLicense
        }
        
        $licenses | Format-Table -AutoSize
        return $licenses
    }
    catch {
        Write-Host "Error listing available licenses: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-LicenseUsage {
    Write-Host "`nAnalyzing License Usage..." -ForegroundColor Yellow
    try {
        $usage = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            Get-RDLicenseUsage
        }
        
        $usage | Format-Table -AutoSize
        return $usage
    }
    catch {
        Write-Host "Error analyzing license usage: $_" -ForegroundColor Red
        return $null
    }
}

function Check-RDSServerConfiguration {
    Write-Host "`nChecking RDS Server Configuration..." -ForegroundColor Yellow
    try {
        $config = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $deployment = Get-RDDeploymentGatewayConfiguration
            $collection = Get-RDSessionCollection
            return @{
                Deployment = $deployment
                Collection = $collection
            }
        }
        
        $result = [PSCustomObject]@{
            GatewayMode = $config.Deployment.GatewayMode
            CollectionName = $config.Collection.CollectionName
            CollectionDescription = $config.Collection.CollectionDescription
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error checking RDS server configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Verify-CALCompliance {
    Write-Host "`nVerifying CAL Compliance..." -ForegroundColor Yellow
    try {
        $compliance = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $licenses = Get-RDLicense
            $usage = Get-RDLicenseUsage
            
            $totalLicenses = ($licenses | Measure-Object -Property TotalLicenses -Sum).Sum
            $usedLicenses = ($usage | Measure-Object -Property IssuedLicenses -Sum).Sum
            
            return @{
                TotalLicenses = $totalLicenses
                UsedLicenses = $usedLicenses
                IsCompliant = $totalLicenses -ge $usedLicenses
            }
        }
        
        $result = [PSCustomObject]@{
            TotalLicenses = $compliance.TotalLicenses
            UsedLicenses = $compliance.UsedLicenses
            IsCompliant = $compliance.IsCompliant
            ComplianceStatus = if ($compliance.IsCompliant) { "Compliant" } else { "Non-Compliant" }
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error verifying CAL compliance: $_" -ForegroundColor Red
        return $null
    }
}

function Review-LicensePolicies {
    Write-Host "`nReviewing License Policies..." -ForegroundColor Yellow
    try {
        $policies = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            Get-RDLicenseConfiguration
        }
        
        $result = [PSCustomObject]@{
            Mode = $policies.Mode
            LicensingType = $policies.LicensingType
            PolicyExpirationDays = $policies.PolicyExpirationDays
            PolicyOverrideAllowed = $policies.PolicyOverrideAllowed
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error reviewing license policies: $_" -ForegroundColor Red
        return $null
    }
}

function Check-LicenseServerHealth {
    Write-Host "`nChecking License Server Health..." -ForegroundColor Yellow
    try {
        $health = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $status = Get-RDLicenseServerStatus
            $service = Get-Service -Name TermServLicensing
            
            return @{
                Status = $status
                ServiceStatus = $service.Status
            }
        }
        
        $result = [PSCustomObject]@{
            IsActivated = $health.Status.IsActivated
            LastIssuedLicenseDate = $health.Status.LastIssuedLicenseDate
            GracePeriodDays = $health.Status.GracePeriodDays
            ServiceStatus = $health.ServiceStatus
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error checking license server health: $_" -ForegroundColor Red
        return $null
    }
}

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>RDS License Audit 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; }
        .warning { color: orange; }
        .critical { color: red; }
        .success { color: green; }
    </style>
</head>
<body>
    <h1>RDS License Audit Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>License Server: $global:licenseServer</p>

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

    <h2>Available Licenses</h2>
    $($AllResults.AvailableLicenses | ConvertTo-Html -Fragment)

    <h2>License Usage</h2>
    $($AllResults.LicenseUsage | ConvertTo-Html -Fragment)

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

    <h2>CAL Compliance</h2>
    $($AllResults.CALCompliance | ConvertTo-Html -Fragment)

    <h2>License Policies</h2>
    $($AllResults.LicensePolicies | ConvertTo-Html -Fragment)

    <h2>License Server Health</h2>
    $($AllResults.ServerHealth | 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" { Set-LicenseServer }
        "2" { $allResults.ServerConfig = Check-LicenseServerConfiguration }
        "3" { $allResults.AvailableLicenses = List-AvailableLicenses }
        "4" { $allResults.LicenseUsage = Analyze-LicenseUsage }
        "5" { $allResults.RDSConfig = Check-RDSServerConfiguration }
        "6" { $allResults.CALCompliance = Verify-CALCompliance }
        "7" { $allResults.LicensePolicies = Review-LicensePolicies }
        "8" { $allResults.ServerHealth = Check-LicenseServerHealth }
        "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 RDS License Audit Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of RDS licensing:
    • License Server Configuration Check
    • Available Licenses Listing
    • License Usage Analysis
    • RDS Server Configuration Check
    • CAL Compliance Verification
    • License Policies Review
    • License Server Health Check
  3. Option to set a target license server (local or remote)
  4. HTML report generation for easy sharing and viewing of results

Key features:

  • Comprehensive RDS license server configuration analysis
  • Detailed listing of available licenses and their types
  • Analysis of current license usage
  • Verification of Client Access License (CAL) compliance
  • Review of RDS deployment and collection configurations
  • Examination of license policies and server health

This tool is particularly useful for:

  • RDS administrators managing license servers
  • IT professionals auditing RDS environments
  • System administrators troubleshooting RDS licensing issues
  • Anyone needing to quickly gather comprehensive information about RDS licensing configuration and usage

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the Remote Desktop Services PowerShell module installed
  3. Have the necessary permissions to query RDS license information (local admin rights on the license server or appropriate delegated permissions)
  4. Review the generated HTML report for a comprehensive overview of the RDS licensing status and configuration

This script provides a thorough analysis of RDS licensing, helping to identify potential issues, compliance concerns, or areas that need attention. It’s designed to give administrators a quick but comprehensive view of their RDS licensing health and configuration.