Tag Archive for: Web Server

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.

IIS (Internet Information Services) Analyzer Tool

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

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

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

.EXAMPLE
.\IISAnalyzer.ps1
#>

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

# Import required module
Import-Module WebAdministration

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

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

<#
.SYNOPSIS
Analyzes IIS Websites.

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

<#
.SYNOPSIS
Reviews Application Pools.

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

<#
.SYNOPSIS
Analyzes Bindings and SSL Certificates.

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

<#
.SYNOPSIS
Checks Virtual Directories.

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

<#
.SYNOPSIS
Reviews HTTP Response Headers.

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

<#
.SYNOPSIS
Analyzes Authentication Settings.

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

<#
.SYNOPSIS
Checks Logging Configuration.

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

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

.PARAMETER AllResults
Hashtable containing all analysis results.

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

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IIS Analysis Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>IIS Analysis Report</h1>
    <p>Generated on: $(Get-Date)</p>

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

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

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

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

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

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

    <h2>Logging Configuration</h2>
    $($AllResults.LoggingConfiguration | ConvertTo-Html -Fragment)
</body>
</html>
"@

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

# Main program loop
$allResults = @{}

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

    switch ($choice) {
        "1" { $allResults.Websites = Analyze-Websites }
        "2" { $allResults.ApplicationPools = Review-ApplicationPools }
        "3" { $allResults.BindingsAndSSL = Analyze-BindingsAndSSL }
        "4" { $allResults.VirtualDirectories = Check-VirtualDirectories }
        "5" { $allResults.HTTPResponseHeaders = Review-HTTPResponseHeaders }
        "6" { $allResults.AuthenticationSettings = Analyze-AuthenticationSettings }
        "7" { $allResults.LoggingConfiguration = Check-LoggingConfiguration }
        "8" { Generate-HTMLReport -AllResults $allResults }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This IIS Analyzer Tool includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of IIS:
    • Website analysis
    • Application Pool review
    • Bindings and SSL Certificate analysis
    • Virtual Directory check
    • HTTP Response Header review
    • Authentication Settings analysis
    • Logging Configuration check
  3. Comprehensive error handling for each analysis function.
  4. A function to generate an HTML report of all collected data.

Key features:

  • Detailed analysis of IIS Websites and their configurations
  • Review of Application Pools and their settings
  • Analysis of Bindings and SSL Certificates, including expiration dates
  • Examination of Virtual Directories
  • Overview of custom HTTP Response Headers
  • Analysis of Authentication Settings for each website
  • Review of Logging Configurations
  • Comprehensive HTML report generation

This tool is particularly useful for:

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

To use this script effectively:

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

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