Discover powerful PowerShell programs and scripts to automate tasks, manage systems, and enhance productivity. Learn to create, customize, and implement efficient PowerShell solutions for Windows administration, network management, and more. Explore expert tips, best practices, and real-world examples to master PowerShell programming and streamline your IT operations.

PowerShell Log File Text Finder Toolkit

# PowerShell Log File Text Finder Toolkit

# Function to search for text in log files
function Search-LogFile {
    param (
        [string]$LogFilePath,
        [string]$SearchText,
        [string]$OutputFilePath
    )
    
    if (-Not (Test-Path $LogFilePath)) {
        Write-Host "The specified log file does not exist."
        return
    }
    
    # Search the log file for the specified text
    Write-Host "Searching for '$SearchText' in $LogFilePath..."
    $results = Select-String -Path $LogFilePath -Pattern $SearchText
    
    if ($results.Count -eq 0) {
        Write-Host "No matches found."
    } else {
        # Display results
        $results | Format-Table LineNumber, Line -AutoSize
        Write-Host "Found $($results.Count) matches."
        
        # Optionally save results to output file
        if ($OutputFilePath) {
            $results | Out-File -FilePath $OutputFilePath -Append
            Write-Host "Results saved to $OutputFilePath."
        }
    }
}

# Function to display the menu and handle user choices
function Show-Menu {
    Clear-Host
    Write-Host "Log File Text Finder Toolkit"
    Write-Host "1: Search in Log File"
    Write-Host "Q: Quit"
    $choice = Read-Host "Enter your choice"
    
    switch ($choice) {
        "1" {
            $logFilePath = Read-Host "Enter log file path"
            $searchText = Read-Host "Enter text to search"
            $outputFilePath = Read-Host "Enter output file path (or press Enter to skip saving)"
            
            if ([string]::IsNullOrEmpty($outputFilePath)) {
                $outputFilePath = $null
            }
            
            Search-LogFile -LogFilePath $logFilePath -SearchText $searchText -OutputFilePath $outputFilePath
        }
        "Q" { exit }
        default { Write-Host "Invalid choice, please try again." }
    }
}

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

Explanation:

  1. Function: Search-LogFile
    • Parameters:
      • $LogFilePath: The path to the log file where the search will be performed.
      • $SearchText: The text pattern to search for in the log file.
      • $OutputFilePath: Optional path to save the search results.
    • Logic:
      • Checks if the log file exists.
      • Uses Select-String to search for the specified text pattern.
      • Displays the matching lines and line numbers.
      • Optionally saves the results to an output file if specified.
  2. Function: Show-Menu
    • Displays a menu to the user for searching within log files or quitting the script.
    • Handles user input to perform the search or exit the script.
  3. Main Loop
    • Continuously displays the menu and processes user input.

Usage:

  1. Save the Script: Copy the script into a .ps1 file, e.g., LogFileTextFinder.ps1.
  2. Run the Script: Open PowerShell and execute the script by navigating to its directory and running:.\LogFileTextFinder.ps1
  3. Follow Prompts: Use the menu to enter the log file path, search text, and optionally specify an output file path.

This single-file PowerShell toolkit is a simple yet powerful tool for searching text within log files, displaying results, and optionally saving them. It can be easily extended or modified to fit additional requirements or handle more complex scenarios.

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
}

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.

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

PowerShell Toolkit for Regex IP Networking

# PowerShell Toolkit for Regex IP Networking

# Function to validate an IPv4 address
function Test-IPv4Address {
    param (
        [Parameter(Mandatory=$true)]
        [string]$IPAddress
    )
    
    $regex = '^\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$'
    return $IPAddress -match $regex
}

# Function to validate an IPv6 address
function Test-IPv6Address {
    param (
        [Parameter(Mandatory=$true)]
        [string]$IPAddress
    )
    
    $regex = '^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$'
    return $IPAddress -match $regex
}

# Function to extract all IPv4 addresses from a string
function Get-IPv4Addresses {
    param (
        [Parameter(Mandatory=$true)]
        [string]$InputString
    )
    
    $regex = '\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b'
    return $InputString | Select-String -Pattern $regex -AllMatches | ForEach-Object { $_.Matches.Value }
}

# Function to extract all IPv6 addresses from a string
function Get-IPv6Addresses {
    param (
        [Parameter(Mandatory=$true)]
        [string]$InputString
    )
    
    $regex = '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'
    return $InputString | Select-String -Pattern $regex -AllMatches | ForEach-Object { $_.Matches.Value }
}

# Function to validate a subnet mask
function Test-SubnetMask {
    param (
        [Parameter(Mandatory=$true)]
        [string]$SubnetMask
    )
    
    $regex = '^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$'
    return $SubnetMask -match $regex
}

# Function to validate CIDR notation
function Test-CIDRNotation {
    param (
        [Parameter(Mandatory=$true)]
        [string]$CIDR
    )
    
    $regex = '^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))$'
    return $CIDR -match $regex
}

# Function to extract network address from CIDR notation
function Get-NetworkAddress {
    param (
        [Parameter(Mandatory=$true)]
        [string]$CIDR
    )
    
    if (Test-CIDRNotation $CIDR) {
        $parts = $CIDR -split '/'
        $ip = $parts[0]
        $mask = [int]$parts[1]
        
        $ipBytes = [System.Net.IPAddress]::Parse($ip).GetAddressBytes()
        $maskBytes = [byte[]](,0xFF * 4)
        for ($i = 0; $i -lt 4; $i++) {
            if ($mask -lt 8) {
                $maskBytes[$i] = [byte]((0xFF -shl (8 - $mask)) -band 0xFF)
                $mask = 0
            } else {
                $mask -= 8
            }
        }
        
        $networkBytes = for ($i = 0; $i -lt 4; $i++) {
            $ipBytes[$i] -band $maskBytes[$i]
        }
        
        return [System.Net.IPAddress]($networkBytes)
    } else {
        Write-Error "Invalid CIDR notation"
        return $null
    }
}

# Example usage:
# Test-IPv4Address "192.168.1.1"
# Test-IPv6Address "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
# Get-IPv4Addresses "The IP addresses are 192.168.1.1 and 10.0.0.1"
# Get-IPv6Addresses "IPv6 addresses: 2001:0db8:85a3::8a2e:0370:7334 and fe80::1"
# Test-SubnetMask "255.255.255.0"
# Test-CIDRNotation "192.168.1.0/24"
# Get-NetworkAddress "192.168.1.100/24"

This toolkit provides the following functions:

  1. Test-IPv4Address: Validates an IPv4 address.
  2. Test-IPv6Address: Validates an IPv6 address.
  3. Get-IPv4Addresses: Extracts all IPv4 addresses from a given string.
  4. Get-IPv6Addresses: Extracts all IPv6 addresses from a given string.
  5. Test-SubnetMask: Validates a subnet mask.
  6. Test-CIDRNotation: Validates CIDR notation.
  7. Get-NetworkAddress: Extracts the network address from CIDR notation.

You can use these functions in your PowerShell scripts or directly in the PowerShell console. The example usage at the end of the script shows how to call each function.

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.