Skip to content

IIS Utility Functions - Usage Examples

Category: IIS Management Examples Tags: IIS, PowerShell, Usage Examples, Monitoring, Management, Best Practices

Important: Replace Placeholders First

Before using ANY examples below, find your actual site names:

# GET YOUR REAL SITE NAMES FIRST:
Get-IISSite | select Name, ID, State

# Example output:
# Name                ID State
# ----                -- -----
# Default Web Site    1  Started
# MyCompanyAPI        2  Started  
# TestPortal          3  Stopped

Throughout this guide: - [YOUR_SITE_NAME] = Replace with actual site name from above - [YOUR_APP_POOL] = Replace with actual app pool name
- Examples show "Default Web Site" as a real working example

Quick Reference:

# Find app pool names:
Get-IISAppPool | select Name

# Find app pool for specific site:
(Get-IISSite "[YOUR_SITE_NAME]").Applications[0].ApplicationPoolName


Quick Start - Copy & Paste Ready

These commands work immediately with ANY IIS server:

# 1. See all your sites
Get-IISSiteInfo

# 2. Check status of first site (usually "Default Web Site")
$firstSite = (Get-IISSite)[0].Name
Get-SiteStatus $firstSite

# 3. Get performance data for first site
Get-SitePerformance $firstSite -Samples 3

# 4. Quick health check for all sites
Get-IISSite | ForEach-Object { 
    Write-Host "$($_.Name): $($_.State)" -ForegroundColor $(if($_.State -eq "Started"){"Green"}else{"Red"})
}

# 5. Monitor first site for 2 minutes
# (Press Ctrl+C to stop early)
Watch-IISSite $firstSite

After running the Quick Start, replace [YOUR_SITE_NAME] in examples below with your actual site names.


Table of Contents

  1. Discovery & Info Functions
  2. Website Monitoring Functions
  3. Restart & Recovery Functions
  4. Performance Monitoring
  5. Log Monitoring Functions
  6. Health Check Functions
  7. Alerting & Notification Functions
  8. Automated Recovery Functions
  9. Bulk Management Functions
  10. Real-World Scenarios

Discovery & Info Functions

Get-IISSiteInfo Function Examples

Basic Usage:

# REPLACE "MyWebsite" WITH YOUR ACTUAL SITE NAME
# To find your site names: Get-IISSite | select Name

# Get info for specific site
Get-IISSiteInfo "[YOUR_SITE_NAME]"

# REAL EXAMPLE:
Get-IISSiteInfo "Default Web Site"

# Output:
# SiteName         SiteID SiteState PhysicalPath              PathExists AppPoolName       AppPoolState DotNetVersion Bindings               SSL IsResponding TestUrl
# --------         ------ --------- ------------              ---------- -----------       ------------ ------------- --------               --- ------------ -------
# Default Web Site 1      Started   C:\inetpub\wwwroot        True       DefaultAppPool    Started      v4.0          http:*:80:,https:*:443: True True        http://localhost

Advanced Usage:

# Get info for all sites
Get-IISSiteInfo

# Get info for sites matching pattern
Get-IISSiteInfo "*test*"     # All sites with "test" in name
Get-IISSiteInfo "*prod*"     # All production sites
Get-IISSiteInfo "API*"       # All sites starting with "API"

# Example scenarios:
Get-IISSiteInfo "*staging*"  # Check all staging environments
Get-IISSiteInfo "*wordpress*" # Find all WordPress sites

Real-World Example:

# Daily morning check - get overview of all sites
Write-Host "=== Daily Site Overview ===" -ForegroundColor Cyan
Get-IISSiteInfo | Where-Object {$_.SiteState -ne "Started" -or !$_.IsResponding} | 
    Format-Table SiteName, SiteState, IsResponding -AutoSize

# Find sites with path issues
Get-IISSiteInfo | Where-Object {!$_.PathExists} | 
    Select-Object SiteName, PhysicalPath | Format-Table -AutoSize

Get-SiteStatus Function Examples

Basic Usage:

# REPLACE WITH YOUR ACTUAL SITE NAME
Get-SiteStatus "[YOUR_SITE_NAME]"

# REAL EXAMPLE:
Get-SiteStatus "Default Web Site"

# Output:
# === Site Status: Default Web Site ===
# Site State: Started
# App Pool: DefaultAppPool - Started  
# Physical Path: C:\inetpub\wwwroot
# Path Exists: True
# Worker Process: PID 1234 - Memory: 45.2MB
# HTTP Test: 200 - OK

Advanced Usage:

# Check multiple sites in sequence
$criticalSites = @("MainWebsite", "APIService", "PaymentGateway")
foreach($site in $criticalSites) {
    Get-SiteStatus $site
    Write-Host ""
}

# Use in conditional logic
$status = Get-SiteStatus "MyWebsite" 2>&1
if($LASTEXITCODE -eq 0) {
    Write-Host "Site is healthy" -ForegroundColor Green
} else {
    Write-Host "Site has issues - investigating..." -ForegroundColor Red
    # Trigger recovery actions
}

Real-World Example:

# Morning health check script
function Morning-HealthCheck {
    $sites = @("CustomerPortal", "AdminDashboard", "APIGateway", "PaymentService")

    Write-Host "Morning Health Check - $(Get-Date -Format 'yyyy-MM-dd HH:mm')" -ForegroundColor Green
    Write-Host "=" * 60

    foreach($site in $sites) {
        try {
            Get-SiteStatus $site
            Write-Host "✓ $site - OK" -ForegroundColor Green
        } catch {
            Write-Host "✗ $site - ISSUES DETECTED" -ForegroundColor Red
            # Could trigger alert here
        }
        Write-Host ""
    }
}

Morning-HealthCheck


Website Monitoring Functions

Watch-IISSite Function Examples

Basic Usage:

# REPLACE WITH YOUR SITE NAME - FIND WITH: Get-IISSite | select Name
Watch-IISSite "[YOUR_SITE_NAME]"

# REAL EXAMPLE:
Watch-IISSite "Default Web Site"

# Output (continuous):
# 2024-07-11 09:15:30 | Check #1 | ✓ OK | Site:True Pool:True HTTP:True | Response:245ms | Failures:0 | Uptime:00:01:30
# 2024-07-11 09:16:00 | Check #2 | ✓ OK | Site:True Pool:True HTTP:True | Response:189ms | Failures:0 | Uptime:00:02:00

Advanced Usage:

# Aggressive monitoring with auto-restart
Watch-IISSite "[YOUR_CRITICAL_SITE]" -IntervalSeconds 15 -AlertThreshold 2 -AutoRestart

# REAL EXAMPLES:
Watch-IISSite "Default Web Site" -IntervalSeconds 15 -AlertThreshold 2 -AutoRestart
Watch-IISSite "MyCompanyAPI" -IntervalSeconds 30 -AlertThreshold 3

# Conservative monitoring for stable site
Watch-IISSite "[YOUR_STABLE_SITE]" -IntervalSeconds 300 -AlertThreshold 5

Real-World Examples:

Deployment Monitoring:

# Monitor during deployment
Write-Host "Starting deployment monitoring..." -ForegroundColor Yellow
Write-Host "Deploy your application now, monitoring will detect when it's ready"

# Monitor every 10 seconds during deployment
Watch-IISSite "ProductionAPI" -IntervalSeconds 10 -AlertThreshold 2

# Use case: Monitor while deployment team deploys new version
# Will automatically detect when site comes back online

Production Monitoring:

# Production site with auto-recovery
Write-Host "Starting production monitoring with auto-recovery"
Watch-IISSite "EcommerceStore" -IntervalSeconds 30 -AlertThreshold 3 -AutoRestart

# Critical service monitoring  
Watch-IISSite "PaymentProcessor" -IntervalSeconds 15 -AlertThreshold 1 -AutoRestart

Maintenance Window Monitoring:

# Monitor during maintenance
Write-Host "Monitoring during maintenance window..."
Watch-IISSite "MaintenanceSite" -IntervalSeconds 60 -AlertThreshold 10
# Higher threshold during maintenance when temporary failures are expected

Get-SitePerformance Function Examples

Basic Usage:

# Collect 5 samples (default) with 2-second intervals
Get-SitePerformance "MyWebsite"

# Output:
# Time     CurrentConnections RequestsPerSec QueueLength CPUPercent MemoryMB
# ----     ------------------ -------------- ----------- ---------- --------
# 14:30:15 25                 12.5           0           15.2       145.6
# 14:30:17 23                 11.8           0           14.8       146.1
# 14:30:19 27                 13.2           1           16.1       145.9
# 
# Averages:
#   Connections: 25.0
#   Requests/Sec: 12.5  
#   Memory (MB): 145.9

Advanced Usage:

# Extended sampling for detailed analysis
Get-SitePerformance "HighTrafficSite" -Samples 20

# Quick performance check
Get-SitePerformance "APIService" -Samples 3

# Performance comparison
Write-Host "Before optimization:" -ForegroundColor Yellow
Get-SitePerformance "OptimizationTarget" -Samples 10

# Make changes here...

Write-Host "After optimization:" -ForegroundColor Green  
Get-SitePerformance "OptimizationTarget" -Samples 10

Real-World Examples:

Load Testing Analysis:

# Monitor during load test
Write-Host "Starting load test monitoring..." -ForegroundColor Cyan
Write-Host "Start your load test now..."

# Collect samples during load test
$beforeLoad = Get-SitePerformance "LoadTestSite" -Samples 5
Write-Host "Baseline established. Start load test now and press Enter when complete."
Read-Host

$duringLoad = Get-SitePerformance "LoadTestSite" -Samples 15
Write-Host "Load test analysis complete."

# Compare results
Write-Host "`nPerformance Comparison:" -ForegroundColor Yellow
Write-Host "Before Load - Avg Memory: $($beforeLoad.MemoryMB | Measure-Object -Average).Average MB"
Write-Host "During Load - Avg Memory: $($duringLoad.MemoryMB | Measure-Object -Average).Average MB"

Performance Baseline:

# Establish performance baseline
function Create-PerformanceBaseline {
    param([string]$SiteName)

    Write-Host "Creating performance baseline for: $SiteName" -ForegroundColor Green

    # Collect samples at different times
    $morning = Get-SitePerformance $SiteName -Samples 10
    Write-Host "Morning samples collected, waiting 4 hours for afternoon samples..."
    Start-Sleep (4 * 60 * 60)  # 4 hours

    $afternoon = Get-SitePerformance $SiteName -Samples 10

    # Save baseline
    $baseline = @{
        Site = $SiteName
        Date = Get-Date
        Morning = $morning
        Afternoon = $afternoon
    }

    $baseline | ConvertTo-Json | Out-File "baseline_$($SiteName)_$(Get-Date -f 'yyyyMMdd').json"
    Write-Host "Baseline saved to baseline_$($SiteName)_$(Get-Date -f 'yyyyMMdd').json"
}

Create-PerformanceBaseline "ProductionSite"


Restart & Recovery Functions

Restart-IISSiteComplete Function Examples

Basic Usage:

# REPLACE WITH YOUR SITE NAME
Restart-IISSiteComplete "[YOUR_SITE_NAME]"

# REAL EXAMPLE:
Restart-IISSiteComplete "Default Web Site"

# Output:
# Restart site 'Default Web Site' and app pool? (y/N): y
# Starting restart sequence for: Default Web Site
#   Stopping site...
#   Site stopped
#   Restarting application pool: DefaultAppPool...
#   App pool restarted
#   Waiting 3 seconds...
#   Starting site...
#   Site started
# ✓ Restart completed successfully
# ✓ HTTP test successful: 200

Advanced Usage:

# Force restart without confirmation (USE YOUR REAL SITE NAME)
Restart-IISSiteComplete "[YOUR_SITE_NAME]" -Force

# REAL EXAMPLES:
Restart-IISSiteComplete "Default Web Site" -Force
Restart-IISSiteComplete "MyCompanyAPI" -RestartAppPool $false -Force  # Site only, not app pool

# Restart site only (don't restart app pool)
Restart-IISSiteComplete "[YOUR_SITE_NAME]" -RestartAppPool $false -Force

# Custom wait time
Restart-IISSiteComplete "[YOUR_SLOW_SITE]" -WaitSeconds 10 -Force

Real-World Examples:

Deployment Restart:

# Post-deployment restart sequence
Write-Host "Post-deployment restart sequence starting..." -ForegroundColor Cyan

$sites = @("WebAPI", "CustomerPortal", "AdminDashboard")
foreach($site in $sites) {
    Write-Host "Restarting $site..." -ForegroundColor Yellow
    try {
        Restart-IISSiteComplete $site -Force -WaitSeconds 5
        Write-Host "✓ $site restarted successfully" -ForegroundColor Green
    } catch {
        Write-Host "✗ Failed to restart $site`: $($_.Exception.Message)" -ForegroundColor Red
    }
}

Write-Host "Deployment restart sequence completed" -ForegroundColor Cyan

Emergency Restart:

# Emergency restart for unresponsive site
Write-Host "EMERGENCY RESTART INITIATED" -ForegroundColor Red -BackgroundColor White

# Try graceful restart first
try {
    Restart-IISSiteComplete "UnresponsiveSite" -Force -WaitSeconds 1
    Write-Host "Graceful restart successful" -ForegroundColor Green
} catch {
    Write-Host "Graceful restart failed, trying aggressive recovery..." -ForegroundColor Yellow

    # Force stop everything
    Stop-IISSite "UnresponsiveSite" -ErrorAction SilentlyContinue
    Stop-WebAppPool "UnresponsiveAppPool" -ErrorAction SilentlyContinue

    # Kill worker processes if needed
    Get-Process w3wp -ErrorAction SilentlyContinue | Where-Object {$_.MainWindowTitle -like "*UnresponsiveAppPool*"} | Stop-Process -Force

    Start-Sleep 5

    # Restart
    Start-WebAppPool "UnresponsiveAppPool"
    Start-IISSite "UnresponsiveSite"

    Write-Host "Aggressive restart completed" -ForegroundColor Yellow
}

Scheduled Maintenance:

# Scheduled maintenance restart
function Invoke-MaintenanceRestart {
    $maintenanceWindow = @{
        Start = "02:00"
        End = "04:00"
    }

    $currentTime = Get-Date -Format "HH:mm"
    if($currentTime -ge $maintenanceWindow.Start -and $currentTime -le $maintenanceWindow.End) {
        Write-Host "Maintenance window active - performing restarts" -ForegroundColor Green

        $productionSites = Get-IISSite | Where-Object {$_.Name -like "*prod*"}
        foreach($site in $productionSites) {
            Write-Host "Maintenance restart: $($site.Name)"
            Restart-IISSiteComplete $site.Name -Force -WaitSeconds 10
        }
    } else {
        Write-Host "Outside maintenance window ($($maintenanceWindow.Start)-$($maintenanceWindow.End)) - restart cancelled" -ForegroundColor Yellow
    }
}

Invoke-MaintenanceRestart

Restart-AppPoolOnly Function Examples

Basic Usage:

# Restart app pool by site name
Restart-AppPoolOnly -SiteName "MyWebsite"

# Restart app pool directly
Restart-AppPoolOnly -AppPoolName "MyAppPool"

# Output:
# Restarting application pool: MyAppPool
#   Current state: Started
#   New state: Started
# ✓ Worker process started: PID 5678

Advanced Usage:

# Restart multiple app pools
$appPools = @("APIPool", "WebPool", "ServicePool")
foreach($pool in $appPools) {
    Write-Host "Restarting $pool..." -ForegroundColor Yellow
    Restart-AppPoolOnly -AppPoolName $pool
}

# Restart app pool for site without affecting site state
$sites = Get-IISSite | Where-Object {$_.Name -like "*microservice*"}
foreach($site in $sites) {
    Write-Host "Recycling app pool for: $($site.Name)"
    Restart-AppPoolOnly -SiteName $site.Name
}

Real-World Examples:

Memory Pressure Relief:

# Monitor and restart high-memory app pools
$memoryThreshold = 1000  # MB

$highMemoryPools = Get-Process w3wp -ErrorAction SilentlyContinue | Where-Object {
    ($_.WorkingSet / 1MB) -gt $memoryThreshold
} | ForEach-Object {
    # Extract app pool name from command line
    $cmdLine = (Get-WmiObject -Query "SELECT CommandLine FROM Win32_Process WHERE ProcessId=$($_.Id)").CommandLine
    if($cmdLine -match '-ap "([^"]+)"') {
        $matches[1]
    }
} | Select-Object -Unique

foreach($poolName in $highMemoryPools) {
    Write-Host "High memory usage detected in: $poolName - Restarting..." -ForegroundColor Yellow
    Restart-AppPoolOnly -AppPoolName $poolName
}

Development Environment Reset:

# Reset all development app pools
Write-Host "Resetting development environment..." -ForegroundColor Cyan

Get-IISAppPool | Where-Object {$_.Name -like "*dev*" -or $_.Name -like "*test*"} | ForEach-Object {
    Write-Host "Recycling: $($_.Name)" -ForegroundColor Yellow
    Restart-AppPoolOnly -AppPoolName $_.Name
}

Write-Host "Development environment reset complete" -ForegroundColor Green

Invoke-SiteRecovery Function Examples

Basic Usage:

# Smart recovery with progressive escalation
Invoke-SiteRecovery "ProblematicSite"

# Output:
# Starting recovery process for: ProblematicSite
#   Attempting: Reset App Pool Failures...
#   Attempting: Start App Pool...
#   Attempting: Start Site...
# ✓ Recovery successful with: Start Site
#   Final status - Site: Started, Pool: Started

Advanced Usage:

# Recovery with custom test URL
Invoke-SiteRecovery "CustomAPI" -TestUrl "http://localhost/api/health"

# Use in automated monitoring
$recoverySuccess = Invoke-SiteRecovery "CriticalService"
if(!$recoverySuccess) {
    Write-Host "Automatic recovery failed - escalating to operations team" -ForegroundColor Red
    # Send alert to operations team
}

Real-World Examples:

Automated Recovery Script:

# Automated recovery for multiple sites
function Invoke-MassRecovery {
    param([string[]]$SiteNames)

    $results = @()

    foreach($siteName in $SiteNames) {
        Write-Host "Attempting recovery for: $siteName" -ForegroundColor Cyan

        $startTime = Get-Date
        $success = Invoke-SiteRecovery $siteName
        $duration = (Get-Date) - $startTime

        $results += [PSCustomObject]@{
            Site = $siteName
            Success = $success
            Duration = $duration.TotalSeconds
            Timestamp = $startTime
        }

        if($success) {
            Write-Host "✓ $siteName recovered in $([math]::Round($duration.TotalSeconds,1))s" -ForegroundColor Green
        } else {
            Write-Host "✗ $siteName recovery failed after $([math]::Round($duration.TotalSeconds,1))s" -ForegroundColor Red
        }
    }

    return $results
}

# Use during mass outage
$problematicSites = @("Site1", "Site2", "Site3")
$recoveryResults = Invoke-MassRecovery $problematicSites

# Generate report
$recoveryResults | Format-Table -AutoSize

Health Check with Recovery:

# Check health and recover if needed
function Monitor-AndRecover {
    param([string]$SiteName)

    Write-Host "Monitoring: $SiteName" -ForegroundColor White

    # Test site health
    try {
        $response = Invoke-WebRequest "http://localhost" -UseBasicParsing -TimeoutSec 5
        if($response.StatusCode -eq 200) {
            Write-Host "✓ $SiteName is healthy" -ForegroundColor Green
            return $true
        }
    } catch {
        Write-Host "⚠ $SiteName is unresponsive - starting recovery..." -ForegroundColor Yellow

        $recovered = Invoke-SiteRecovery $SiteName
        if($recovered) {
            Write-Host "✓ $SiteName recovered successfully" -ForegroundColor Green
            return $true
        } else {
            Write-Host "✗ $SiteName recovery failed - manual intervention required" -ForegroundColor Red
            return $false
        }
    }
}

# Monitor critical sites
$criticalSites = @("PaymentGateway", "UserAuth", "MainAPI")
foreach($site in $criticalSites) {
    Monitor-AndRecover $site
}


Performance Monitoring

Show-SitePerformanceDashboard Function Examples

Basic Usage:

# Real-time dashboard with default 5-second refresh
Show-SitePerformanceDashboard "MyWebsite"

# Output (refreshes every 5 seconds):
# ╔══════════════════════════════════════════════════════════════╗
# ║                   IIS PERFORMANCE DASHBOARD                  ║
# ╠══════════════════════════════════════════════════════════════╣
# ║ Site: MyWebsite                                              ║
# ║ Time: 2024-07-11 14:35:22                                   ║
# ╚══════════════════════════════════════════════════════════════╝
# 
# STATUS:
#   Site State: Started
#   Pool State: Started
# 
# PERFORMANCE:
#   Current Connections: 45
#   Requests/Second: 23.5
#   Request Queue: 0
# 
# WORKER PROCESS:
#   Process ID: 1234
#   Memory Usage: 234.5 MB
#   Uptime: 2d 5h 32m
#   CPU Usage: 12.3%
# 
# HTTP TEST:
#   Status: 200 - OK
#   Response Time: 156ms

Advanced Usage:

# Faster refresh for real-time monitoring
Show-SitePerformanceDashboard "HighTrafficSite" -RefreshSeconds 2

# Slower refresh for stable monitoring
Show-SitePerformanceDashboard "DocumentationSite" -RefreshSeconds 30

# Monitor during specific events
Show-SitePerformanceDashboard "LoadTestTarget" -RefreshSeconds 1

Real-World Examples:

Load Testing Dashboard:

# Set up dashboard for load testing
Write-Host "Load Test Dashboard Setup" -ForegroundColor Cyan
Write-Host "1. Start the dashboard"
Write-Host "2. Begin your load test"
Write-Host "3. Watch performance metrics in real-time"
Write-Host "4. Press Ctrl+C to stop monitoring"
Write-Host ""

# Start monitoring with aggressive refresh
Show-SitePerformanceDashboard "LoadTestSite" -RefreshSeconds 1

Production Monitoring:

# Production monitoring setup
function Start-ProductionMonitoring {
    param([string]$SiteName)

    Write-Host "Starting production monitoring for: $SiteName" -ForegroundColor Green
    Write-Host "Dashboard will refresh every 10 seconds"
    Write-Host "Watch for:"
    Write-Host "  - Memory usage > 500MB (Yellow) or > 1GB (Red)"
    Write-Host "  - CPU usage > 50% (Yellow) or > 80% (Red)"
    Write-Host "  - Response time > 1s (Yellow) or > 5s (Red)"
    Write-Host "  - Request queue > 0 (indicates bottleneck)"
    Write-Host ""
    Write-Host "Press Ctrl+C to stop monitoring"
    Write-Host ""

    Show-SitePerformanceDashboard $SiteName -RefreshSeconds 10
}

Start-ProductionMonitoring "EcommerceSite"

Troubleshooting Dashboard:

# Use during active troubleshooting
Write-Host "TROUBLESHOOTING MODE ACTIVATED" -ForegroundColor Red -BackgroundColor White
Write-Host "Monitoring: $siteName"
Write-Host "Reproduce the issue now..."
Write-Host "Watching for performance anomalies..."

# Aggressive monitoring during troubleshooting
Show-SitePerformanceDashboard "TroubleshootingSite" -RefreshSeconds 3


Log Monitoring Functions

Watch-IISLogs Function Examples

Basic Usage:

# Show recent log entries
Watch-IISLogs "MyWebsite"

# Output:
# Monitoring logs for: MyWebsite (Site ID: 1)
# Log path: C:\inetpub\logs\LogFiles\W3SVC1
# Errors only: False
# Follow mode: False
# 
# Showing recent entries from: u_ex240711.log
# 2024-07-11 14:30:15 192.168.1.100 GET /home.aspx - 80 - 192.168.1.100 200 0 0 125
# 2024-07-11 14:30:16 192.168.1.101 GET /api/users - 80 - 192.168.1.101 200 0 0 89

Advanced Usage:

# Monitor only errors in real-time
Watch-IISLogs "MyWebsite" -ErrorsOnly -Follow

# Quick error review (recent errors only)
Watch-IISLogs "MyWebsite" -ErrorsOnly

# Follow logs in real-time (all requests)
Watch-IISLogs "MyWebsite" -Follow

Real-World Examples:

Deployment Monitoring:

# Monitor logs during deployment
Write-Host "Deployment Log Monitoring" -ForegroundColor Cyan
Write-Host "Monitoring for errors during deployment..."
Write-Host "Deploy your application now, watching for issues..."
Write-Host ""

# Watch for errors during deployment
Watch-IISLogs "DeploymentSite" -ErrorsOnly -Follow

# Use case: Run this in one PowerShell window while deploying in another
# Will show any 4xx/5xx errors that occur during deployment

Troubleshooting Session:

# Live troubleshooting
Write-Host "TROUBLESHOOTING SESSION STARTED" -ForegroundColor Yellow
Write-Host "Following logs in real-time..."
Write-Host "Reproduce the issue now to see what happens in the logs"
Write-Host ""

# Follow all requests during troubleshooting
Watch-IISLogs "ProblematicSite" -Follow

# In separate window, you can also monitor errors only:
# Watch-IISLogs "ProblematicSite" -ErrorsOnly -Follow

Security Monitoring:

# Monitor for security issues
Write-Host "Security Log Monitoring" -ForegroundColor Red
Write-Host "Watching for potential security issues..."
Write-Host "Looking for: 401 (auth failures), 403 (forbidden), 404 (scanning), etc."
Write-Host ""

# Monitor errors that might indicate security issues
Watch-IISLogs "PublicWebsite" -ErrorsOnly -Follow

# Look for patterns like:
# - Multiple 401s from same IP (brute force)
# - 404s for common attack vectors (/admin, /wp-admin, etc.)
# - 403s indicating access attempts to restricted areas

Performance Analysis:

# Monitor response patterns
function Analyze-ResponseTimes {
    param([string]$SiteName)

    Write-Host "Response Time Analysis for: $SiteName" -ForegroundColor Green
    Write-Host "Following logs for 5 minutes to analyze response patterns..."

    $startTime = Get-Date
    $timeout = $startTime.AddMinutes(5)

    # Start log monitoring in background job
    $job = Start-Job -ScriptBlock {
        param($site)
        # Monitor logs and collect timing data
        Watch-IISLogs $site -Follow
    } -ArgumentList $SiteName

    # Wait for timeout or manual stop
    Write-Host "Monitoring... Press Ctrl+C to stop early or wait 5 minutes"

    try {
        while((Get-Date) -lt $timeout) {
            Start-Sleep 10
            Write-Host "Monitoring... $([math]::Round(($timeout - (Get-Date)).TotalMinutes,1)) minutes remaining"
        }
    } catch {
        Write-Host "Monitoring stopped by user"
    } finally {
        Stop-Job $job
        Remove-Job $job
    }

    Write-Host "Analysis complete. Review the log output above for patterns."
}

Analyze-ResponseTimes "AnalysisSite"


Health Check Functions

Test-IISSiteHealth Function Examples

Basic Usage:

# Basic health check
Test-IISSiteHealth "MyWebsite"

# Output:
# Running health check for: MyWebsite
# 
# === HEALTH CHECK RESULTS ===
# Site: MyWebsite
# Overall Health: Healthy
# 
# CHECKS:
#   Site Exists: ✓ Pass - Site found with ID 1
#   Site State: ✓ Pass - Site is started
#   App Pool State: ✓ Pass - MyAppPool is started
#   Physical Path: ✓ Pass - Path exists: C:\inetpub\wwwroot\mysite
#   Web.config: ✓ Pass - Configuration file is valid XML
#   Site Bindings: ✓ Pass - 2 binding(s) configured
#   HTTP Connectivity: ✓ Pass - HTTP 200 - OK
#   SSL Certificate: ✓ Pass - Certificate valid for 87 days
#   Worker Process Memory: ✓ Pass - 145MB memory usage

Advanced Usage:

# Comprehensive health check with performance metrics
Test-IISSiteHealth "MyWebsite" -IncludePerformance

# Store health check results for analysis
$healthResult = Test-IISSiteHealth "MyWebsite" -IncludePerformance
if($healthResult.OverallHealth -ne "Healthy") {
    Write-Host "Site requires attention!" -ForegroundColor Red
    # Take action based on results
}

Real-World Examples:

Daily Health Check Script:

# Daily health check for all production sites
function Invoke-DailyHealthCheck {
    $reportDate = Get-Date -Format "yyyy-MM-dd"
    $reportFile = "HealthReport_$reportDate.txt"

    Write-Host "Daily Health Check - $reportDate" -ForegroundColor Green
    "Daily Health Check - $reportDate" | Out-File $reportFile
    "=" * 50 | Out-File $reportFile -Append

    $productionSites = Get-IISSite | Where-Object {$_.Name -like "*prod*" -or $_.Name -like "*live*"}

    $healthySites = 0
    $warningSites = 0
    $criticalSites = 0

    foreach($site in $productionSites) {
        Write-Host "Checking: $($site.Name)" -ForegroundColor Yellow

        $health = Test-IISSiteHealth $site.Name -IncludePerformance

        switch($health.OverallHealth) {
            "Healthy" { 
                $healthySites++
                Write-Host "✓ $($site.Name) - Healthy" -ForegroundColor Green
            }
            "Warning" { 
                $warningSites++
                Write-Host "⚠ $($site.Name) - Warning" -ForegroundColor Yellow
            }
            "Critical" { 
                $criticalSites++
                Write-Host "✗ $($site.Name) - Critical" -ForegroundColor Red
            }
        }

        # Add to report
        "`n=== $($site.Name) ===" | Out-File $reportFile -Append
        "Overall Health: $($health.OverallHealth)" | Out-File $reportFile -Append

        if($health.Errors.Count -gt 0) {
            "ERRORS:" | Out-File $reportFile -Append
            $health.Errors | ForEach-Object { "  $_" | Out-File $reportFile -Append }
        }

        if($health.Warnings.Count -gt 0) {
            "WARNINGS:" | Out-File $reportFile -Append
            $health.Warnings | ForEach-Object { "  $_" | Out-File $reportFile -Append }
        }
    }

    # Summary
    Write-Host "`nSUMMARY:" -ForegroundColor Cyan
    Write-Host "  Healthy: $healthySites" -ForegroundColor Green
    Write-Host "  Warning: $warningSites" -ForegroundColor Yellow
    Write-Host "  Critical: $criticalSites" -ForegroundColor Red

    "`nSUMMARY:" | Out-File $reportFile -Append
    "  Healthy: $healthySites" | Out-File $reportFile -Append
    "  Warning: $warningSites" | Out-File $reportFile -Append
    "  Critical: $criticalSites" | Out-File $reportFile -Append

    Write-Host "`nReport saved to: $reportFile" -ForegroundColor White

    # Email report if there are issues
    if($warningSites -gt 0 -or $criticalSites -gt 0) {
        Write-Host "Issues detected - consider sending alert" -ForegroundColor Yellow
        # Send-IISAlert -SiteName "Multiple Sites" -AlertType "Warning" -Message "Daily health check found $warningSites warnings and $criticalSites critical issues"
    }
}

Invoke-DailyHealthCheck

Pre-Deployment Health Check:

# Pre-deployment validation
function Test-PreDeployment {
    param([string[]]$SiteNames)

    Write-Host "PRE-DEPLOYMENT HEALTH CHECK" -ForegroundColor Cyan
    Write-Host "Validating environment before deployment..." -ForegroundColor White

    $allHealthy = $true

    foreach($siteName in $SiteNames) {
        Write-Host "`nChecking: $siteName" -ForegroundColor Yellow

        $health = Test-IISSiteHealth $siteName -IncludePerformance

        if($health.OverallHealth -eq "Critical") {
            Write-Host "DEPLOYMENT BLOCKED: $siteName has critical issues" -ForegroundColor Red -BackgroundColor White
            Write-Host "Issues:" -ForegroundColor Red
            $health.Errors | ForEach-Object { Write-Host "  $_" -ForegroundColor Red }
            $allHealthy = $false
        } elseif($health.OverallHealth -eq "Warning") {
            Write-Host "WARNING: $siteName has warnings (deployment can proceed)" -ForegroundColor Yellow
            $health.Warnings | ForEach-Object { Write-Host "  $_" -ForegroundColor Yellow }
        } else {
            Write-Host "✓ $siteName ready for deployment" -ForegroundColor Green
        }
    }

    if($allHealthy) {
        Write-Host "`n✓ ALL SYSTEMS GO - DEPLOYMENT APPROVED" -ForegroundColor Green -BackgroundColor Black
        return $true
    } else {
        Write-Host "`n✗ DEPLOYMENT BLOCKED - RESOLVE CRITICAL ISSUES FIRST" -ForegroundColor Red -BackgroundColor White
        return $false
    }
}

# Use before deployment
$deploymentSites = @("WebAPI", "UserPortal", "AdminPanel")
$canDeploy = Test-PreDeployment $deploymentSites

if($canDeploy) {
    Write-Host "Proceeding with deployment..." -ForegroundColor Green
    # Deployment script here
} else {
    Write-Host "Deployment cancelled due to health check failures" -ForegroundColor Red
    exit 1
}

Continuous Health Monitoring:

# Continuous health monitoring
function Start-ContinuousHealthMonitoring {
    param(
        [string[]]$SiteNames,
        [int]$IntervalMinutes = 15
    )

    Write-Host "Starting continuous health monitoring" -ForegroundColor Green
    Write-Host "Sites: $($SiteNames -join ', ')" -ForegroundColor White
    Write-Host "Interval: $IntervalMinutes minutes" -ForegroundColor White
    Write-Host "Press Ctrl+C to stop" -ForegroundColor Yellow

    try {
        while($true) {
            $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            Write-Host "`n[$timestamp] Health Check Cycle" -ForegroundColor Cyan

            foreach($siteName in $SiteNames) {
                $health = Test-IISSiteHealth $siteName

                $color = switch($health.OverallHealth) {
                    "Healthy" { "Green" }
                    "Warning" { "Yellow" } 
                    "Critical" { "Red" }
                }

                Write-Host "  $siteName`: $($health.OverallHealth)" -ForegroundColor $color

                # Alert on state changes or critical issues
                if($health.OverallHealth -eq "Critical") {
                    Write-Host "    CRITICAL ALERT: $siteName requires immediate attention" -ForegroundColor Red
                    # Send-IISAlert -SiteName $siteName -AlertType "Error" -Message "Critical health check failure"
                }
            }

            Write-Host "Next check in $IntervalMinutes minutes..." -ForegroundColor Gray
            Start-Sleep ($IntervalMinutes * 60)
        }
    } catch [System.Management.Automation.PipelineStoppedException] {
        Write-Host "`nContinuous monitoring stopped" -ForegroundColor Yellow
    }
}

# Monitor critical sites every 10 minutes
$criticalSites = @("PaymentGateway", "UserAuth", "MainAPI")
Start-ContinuousHealthMonitoring -SiteNames $criticalSites -IntervalMinutes 10


Alerting & Notification Functions

Send-IISAlert Function Examples

Basic Usage:

# Simple error alert
Send-IISAlert -SiteName "MyWebsite" -AlertType "Error" -Message "Site is down and not responding to HTTP requests"

# Warning alert
Send-IISAlert -SiteName "MyWebsite" -AlertType "Warning" -Message "High memory usage detected: 1.2GB"

# Info alert
Send-IISAlert -SiteName "MyWebsite" -AlertType "Info" -Message "Site successfully restarted after deployment"

Advanced Usage:

# Custom SMTP settings
Send-IISAlert -SiteName "CriticalSite" -AlertType "Error" -Message "Database connection failed" -SmtpServer "mail.company.com" -To @("admin@company.com", "oncall@company.com") -From "iis-alerts@company.com"

# Alert with detailed information
$alertMessage = @"
Site: MyWebsite
Issue: Application pool stopped unexpectedly
Time: $(Get-Date)
Worker Process: Not running
Last Error: $(Get-EventLog -LogName Application -Newest 1 | Where-Object {$_.Source -like "*IIS*"} | Select-Object -ExpandProperty Message)

Recovery Action Taken: Automatic restart attempted
Status: $(try { (Get-IISSite "MyWebsite").State } catch { "Unknown" })
"@

Send-IISAlert -SiteName "MyWebsite" -AlertType "Error" -Message $alertMessage

Real-World Examples:

Automated Alert System:

# Comprehensive alerting system
function Send-SmartAlert {
    param(
        [string]$SiteName,
        [string]$IssueType,
        [object]$HealthData = $null
    )

    $alertLevel = switch($IssueType) {
        "SiteDown" { "Error" }
        "HighMemory" { "Warning" }
        "SlowResponse" { "Warning" }
        "AppPoolStopped" { "Error" }
        "SSLExpiring" { "Warning" }
        "RecoverySuccess" { "Info" }
        default { "Warning" }
    }

    # Build detailed message based on issue type
    $message = switch($IssueType) {
        "SiteDown" {
            @"
CRITICAL: Site $SiteName is completely down
- Site State: $((Get-IISSite $SiteName -ea 0).State)
- App Pool State: $((Get-IISAppPool ((Get-IISSite $SiteName).Applications[0].ApplicationPoolName) -ea 0).State)
- HTTP Response: Failed
- Time: $(Get-Date)

Automatic recovery will be attempted.
If this alert persists, manual intervention is required.
"@
        }

        "HighMemory" {
            $memUsage = if($HealthData) { $HealthData.MemoryMB } else { "Unknown" }
            @"
WARNING: High memory usage detected for $SiteName
- Current Memory Usage: ${memUsage}MB
- Threshold: 1000MB
- Time: $(Get-Date)

Consider investigating for memory leaks or increasing app pool recycling frequency.
"@
        }

        "RecoverySuccess" {
            @"
RECOVERY SUCCESS: $SiteName has been successfully restored
- Recovery Time: $(Get-Date)
- Site State: Started
- App Pool State: Started
- HTTP Response: OK

The site is now operational. Monitor for stability.
"@
        }

        default { "Issue detected with $SiteName`: $IssueType" }
    }

    Send-IISAlert -SiteName $SiteName -AlertType $alertLevel -Message $message
}

# Usage examples:
# Send-SmartAlert -SiteName "CriticalSite" -IssueType "SiteDown"
# Send-SmartAlert -SiteName "MemorySite" -IssueType "HighMemory" -HealthData @{MemoryMB=1200}
# Send-SmartAlert -SiteName "RecoveredSite" -IssueType "RecoverySuccess"

Alert Escalation System:

# Multi-level alert system
function Send-EscalatedAlert {
    param(
        [string]$SiteName,
        [string]$Issue,
        [int]$EscalationLevel = 1
    )

    $escalationConfig = @{
        1 = @{ Recipients = @("l1-support@company.com"); Subject = "L1 Alert" }
        2 = @{ Recipients = @("l1-support@company.com", "l2-support@company.com"); Subject = "L2 Escalation" }
        3 = @{ Recipients = @("l1-support@company.com", "l2-support@company.com", "manager@company.com"); Subject = "L3 Critical Escalation" }
    }

    $config = $escalationConfig[$EscalationLevel]
    $alertType = if($EscalationLevel -ge 3) { "Error" } else { "Warning" }

    $message = @"
ESCALATION LEVEL $EscalationLevel

Site: $SiteName
Issue: $Issue
Time: $(Get-Date)
Server: $env:COMPUTERNAME

$(if($EscalationLevel -ge 3) { "IMMEDIATE ACTION REQUIRED - CRITICAL SYSTEM DOWN" } else { "Monitoring and resolution required" })

Please investigate and resolve immediately.
"@

    Send-IISAlert -SiteName $SiteName -AlertType $alertType -Message $message -To $config.Recipients

    Write-Host "Level $EscalationLevel alert sent for $SiteName" -ForegroundColor $(if($EscalationLevel -ge 3){"Red"}else{"Yellow"})
}

# Usage in monitoring:
# Send-EscalatedAlert -SiteName "CriticalSite" -Issue "Site unresponsive for 5 minutes" -EscalationLevel 1
# Start-Sleep 300  # Wait 5 minutes
# Send-EscalatedAlert -SiteName "CriticalSite" -Issue "Site still unresponsive after 10 minutes" -EscalationLevel 2
# Start-Sleep 600  # Wait 10 more minutes  
# Send-EscalatedAlert -SiteName "CriticalSite" -Issue "Site down for 20 minutes - CRITICAL" -EscalationLevel 3


Automated Recovery Functions

Start-IISAutoRecovery Function Examples

Basic Usage:

# Basic auto-recovery for critical sites
Start-IISAutoRecovery -SiteNames @("MainWebsite", "APIService")

# Output:
# Starting auto-recovery service for sites: MainWebsite, APIService
# Check interval: 60 seconds
# Max restart attempts: 3
# Press Ctrl+C to stop
# 
# 2024-07-11 14:45:00 | MainWebsite passed health check
# 2024-07-11 14:45:00 | APIService passed health check
# (continues every 60 seconds...)

Advanced Usage:

# Aggressive monitoring for critical systems
Start-IISAutoRecovery -SiteNames @("PaymentGateway", "UserAuth") -CheckInterval 30 -MaxRestartAttempts 5

# Conservative monitoring for stable sites
Start-IISAutoRecovery -SiteNames @("Documentation", "Reports") -CheckInterval 300 -MaxRestartAttempts 2

# High-frequency monitoring during deployment
Start-IISAutoRecovery -SiteNames @("NewDeployment") -CheckInterval 15 -MaxRestartAttempts 1

Real-World Examples:

Production Auto-Recovery Setup:

# Production environment auto-recovery
function Start-ProductionAutoRecovery {
    # STEP 1: REPLACE THESE WITH YOUR ACTUAL SITE NAMES
    # To find your real site names, run: Get-IISSite | select Name

    $criticalSites = @("[YOUR_PAYMENT_SITE]", "[YOUR_AUTH_SITE]", "[YOUR_MAIN_SITE]")
    $importantSites = @("[YOUR_ADMIN_SITE]", "[YOUR_API_SITE]", "[YOUR_REPORTS_SITE]") 
    $standardSites = @("[YOUR_DOCS_SITE]", "[YOUR_SUPPORT_SITE]")

    # EXAMPLE with real site names:
    # $criticalSites = @("Default Web Site", "MyCompanyAPI", "UserPortal")
    # $importantSites = @("AdminDashboard", "ReportsService") 
    # $standardSites = @("Documentation")

    Write-Host "PRODUCTION AUTO-RECOVERY STARTING" -ForegroundColor Green -BackgroundColor Black
    Write-Host "Critical Sites: $($criticalSites -join ', ')" -ForegroundColor Red
    Write-Host "Important Sites: $($importantSites -join ', ')" -ForegroundColor Yellow
    Write-Host "Standard Sites: $($standardSites -join ', ')" -ForegroundColor White

    # Start separate monitoring for each group
    Write-Host "`nStarting monitoring services..." -ForegroundColor Cyan

    # Critical - aggressive monitoring
    Start-Job -Name "CriticalMonitoring" -ScriptBlock {
        param($sites)
        Import-Module WebAdministration,IISAdministration
        # Import your custom functions here
        Start-IISAutoRecovery -SiteNames $sites -CheckInterval 30 -MaxRestartAttempts 5
    } -ArgumentList $criticalSites

    # Important - moderate monitoring  
    Start-Job -Name "ImportantMonitoring" -ScriptBlock {
        param($sites)
        Import-Module WebAdministration,IISAdministration
        Start-IISAutoRecovery -SiteNames $sites -CheckInterval 60 -MaxRestartAttempts 3
    } -ArgumentList $importantSites

    # Standard - basic monitoring
    Start-Job -Name "StandardMonitoring" -ScriptBlock {
        param($sites)
        Import-Module WebAdministration,IISAdministration
        Start-IISAutoRecovery -SiteNames $sites -CheckInterval 300 -MaxRestartAttempts 2
    } -ArgumentList $standardSites

    Write-Host "All monitoring services started in background jobs" -ForegroundColor Green
    Write-Host "Use 'Get-Job' to check status, 'Stop-Job' to stop monitoring" -ForegroundColor White
}

Start-ProductionAutoRecovery

Deployment Auto-Recovery:

# Auto-recovery during deployment window
function Start-DeploymentMonitoring {
    param([string[]]$SiteNames, [int]$DeploymentWindowMinutes = 60)

    Write-Host "DEPLOYMENT MONITORING ACTIVATED" -ForegroundColor Cyan -BackgroundColor Black
    Write-Host "Sites: $($SiteNames -join ', ')" -ForegroundColor White
    Write-Host "Window: $DeploymentWindowMinutes minutes" -ForegroundColor White
    Write-Host "Aggressive monitoring during deployment..." -ForegroundColor Yellow

    $endTime = (Get-Date).AddMinutes($DeploymentWindowMinutes)

    # Start auto-recovery with deployment-specific settings
    $job = Start-Job -ScriptBlock {
        param($sites, $endTime)
        Import-Module WebAdministration,IISAdministration

        # Aggressive monitoring during deployment
        try {
            Start-IISAutoRecovery -SiteNames $sites -CheckInterval 15 -MaxRestartAttempts 1
        } catch [System.Management.Automation.PipelineStoppedException] {
            Write-Host "Deployment monitoring stopped"
        }
    } -ArgumentList $SiteNames, $endTime

    # Monitor the monitoring job
    try {
        while((Get-Date) -lt $endTime -and $job.State -eq "Running") {
            $remaining = [math]::Round(($endTime - (Get-Date)).TotalMinutes, 1)
            Write-Host "Deployment monitoring active - $remaining minutes remaining" -ForegroundColor Green
            Start-Sleep 60
        }
    } catch {
        Write-Host "Deployment monitoring interrupted" -ForegroundColor Yellow
    } finally {
        Stop-Job $job -ErrorAction SilentlyContinue
        Remove-Job $job -ErrorAction SilentlyContinue
        Write-Host "Deployment monitoring window closed" -ForegroundColor Cyan
    }
}

# Use during deployment
$deploymentSites = @("WebAPI", "UserPortal", "AdminDashboard")
Start-DeploymentMonitoring -SiteNames $deploymentSites -DeploymentWindowMinutes 45

24/7 Monitoring Service:

# Enterprise 24/7 monitoring setup
function Install-IISMonitoringService {
    $serviceScript = @'
# IIS Monitoring Service Script
Import-Module WebAdministration,IISAdministration

# Load custom functions (you'd import your module here)
# Import-Module IISUtilities

$criticalSites = @("MainWebsite", "PaymentAPI", "UserAuth")
$logFile = "C:\Logs\IISMonitoring.log"

function Write-MonitoringLog {
    param([string]$Message, [string]$Level = "INFO")
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$timestamp [$Level] $Message" | Out-File $logFile -Append
}

Write-MonitoringLog "IIS Monitoring Service Starting" "INFO"

try {
    Start-IISAutoRecovery -SiteNames $criticalSites -CheckInterval 60 -MaxRestartAttempts 3
} catch {
    Write-MonitoringLog "Monitoring service error: $($_.Exception.Message)" "ERROR"
} finally {
    Write-MonitoringLog "IIS Monitoring Service Stopped" "INFO"
}
'@

    # Save monitoring script
    $scriptPath = "C:\Scripts\IISMonitoring.ps1"
    $serviceScript | Out-File $scriptPath -Encoding UTF8

    # Create Windows service (requires NSSM or similar)
    Write-Host "Monitoring script created at: $scriptPath" -ForegroundColor Green
    Write-Host "To install as Windows service:" -ForegroundColor Yellow
    Write-Host "1. Install NSSM (Non-Sucking Service Manager)" -ForegroundColor White
    Write-Host "2. Run: nssm install IISMonitoring powershell.exe" -ForegroundColor White
    Write-Host "3. Set arguments: -ExecutionPolicy Bypass -File `"$scriptPath`"" -ForegroundColor White
    Write-Host "4. Configure service recovery options" -ForegroundColor White
}

Install-IISMonitoringService


Bulk Management Functions

Invoke-BulkSiteOperation Function Examples

Basic Usage:

# Check status of all sites
Invoke-BulkSiteOperation -SitePattern "*" -Operation "Status"

# Output:
# Found 5 sites matching pattern: *
#   - MainWebsite
#   - TestSite  
#   - DevPortal
#   - APIService
#   - Documentation
# 
# Proceed with Status operation on these sites? (y/N): y
# 
# Executing Status operation...
# 
# RESULTS:
# Site         Operation Status Message
# ----         --------- ------ -------
# MainWebsite  Status    Info   Site: Started, Pool: Started
# TestSite     Status    Info   Site: Stopped, Pool: Stopped
# DevPortal    Status    Info   Site: Started, Pool: Started

Advanced Usage:

# Restart all test sites in parallel
Invoke-BulkSiteOperation -SitePattern "*test*" -Operation "Restart" -Parallel

# Health check all production sites  
Invoke-BulkSiteOperation -SitePattern "*prod*" -Operation "HealthCheck"

# Start all stopped sites
Invoke-BulkSiteOperation -SitePattern "*" -Operation "Start"

# Stop development sites for maintenance
Invoke-BulkSiteOperation -SitePattern "*dev*" -Operation "Stop"

Real-World Examples:

Environment Management:

# Development environment reset
function Reset-DevelopmentEnvironment {
    Write-Host "DEVELOPMENT ENVIRONMENT RESET" -ForegroundColor Cyan
    Write-Host "This will restart all development and test sites" -ForegroundColor Yellow

    # Stop all dev/test sites
    Write-Host "`n1. Stopping all development sites..." -ForegroundColor Yellow
    Invoke-BulkSiteOperation -SitePattern "*dev*" -Operation "Stop"

    Write-Host "`n2. Stopping all test sites..." -ForegroundColor Yellow  
    Invoke-BulkSiteOperation -SitePattern "*test*" -Operation "Stop"

    # Clear temp files, logs, etc. here
    Write-Host "`n3. Clearing temporary files..." -ForegroundColor Yellow
    # Add cleanup logic

    # Restart everything
    Write-Host "`n4. Starting all development sites..." -ForegroundColor Green
    Invoke-BulkSiteOperation -SitePattern "*dev*" -Operation "Start"

    Write-Host "`n5. Starting all test sites..." -ForegroundColor Green
    Invoke-BulkSiteOperation -SitePattern "*test*" -Operation "Start"

    Write-Host "`nDevelopment environment reset complete!" -ForegroundColor Green
}

Reset-DevelopmentEnvironment

Maintenance Window Operations:

# Scheduled maintenance operations
function Invoke-MaintenanceWindow {
    param([string]$Environment = "prod")

    $maintenanceStart = Get-Date
    Write-Host "MAINTENANCE WINDOW STARTED" -ForegroundColor Red -BackgroundColor White
    Write-Host "Environment: $Environment" -ForegroundColor White
    Write-Host "Start Time: $maintenanceStart" -ForegroundColor White

    try {
        # 1. Health check before maintenance
        Write-Host "`n=== PRE-MAINTENANCE HEALTH CHECK ===" -ForegroundColor Cyan
        $preResults = Invoke-BulkSiteOperation -SitePattern "*$Environment*" -Operation "HealthCheck"

        # 2. Stop sites gracefully
        Write-Host "`n=== STOPPING SITES ===" -ForegroundColor Yellow
        Invoke-BulkSiteOperation -SitePattern "*$Environment*" -Operation "Stop"

        # 3. Perform maintenance tasks
        Write-Host "`n=== MAINTENANCE TASKS ===" -ForegroundColor Yellow
        Write-Host "Performing maintenance tasks..." -ForegroundColor White

        # Example maintenance tasks:
        # - Clear temporary files
        # - Update configurations
        # - Apply patches
        # - Database maintenance
        # - Log cleanup

        Start-Sleep 30  # Simulate maintenance work

        # 4. Restart sites
        Write-Host "`n=== RESTARTING SITES ===" -ForegroundColor Green
        $restartResults = Invoke-BulkSiteOperation -SitePattern "*$Environment*" -Operation "Restart" -Parallel

        # 5. Post-maintenance health check
        Write-Host "`n=== POST-MAINTENANCE HEALTH CHECK ===" -ForegroundColor Cyan
        Start-Sleep 30  # Allow time for sites to fully start
        $postResults = Invoke-BulkSiteOperation -SitePattern "*$Environment*" -Operation "HealthCheck"

        $maintenanceEnd = Get-Date
        $duration = $maintenanceEnd - $maintenanceStart

        Write-Host "`nMAINTENANCE WINDOW COMPLETED" -ForegroundColor Green -BackgroundColor Black
        Write-Host "Duration: $($duration.TotalMinutes.ToString('F1')) minutes" -ForegroundColor White

    } catch {
        Write-Host "`nMAINTENANCE WINDOW ERROR: $($_.Exception.Message)" -ForegroundColor Red
        Write-Host "Attempting emergency recovery..." -ForegroundColor Yellow

        # Emergency recovery
        Invoke-BulkSiteOperation -SitePattern "*$Environment*" -Operation "Start"
    }
}

# Scheduled maintenance for production
Invoke-MaintenanceWindow -Environment "prod"

Disaster Recovery:

# Disaster recovery operations
function Invoke-DisasterRecovery {
    param([string]$Scope = "all")

    Write-Host "DISASTER RECOVERY INITIATED" -ForegroundColor Red -BackgroundColor White
    Write-Host "Scope: $Scope" -ForegroundColor White
    Write-Host "Time: $(Get-Date)" -ForegroundColor White

    $recoveryLog = "DisasterRecovery_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
    "Disaster Recovery Log - $(Get-Date)" | Out-File $recoveryLog

    try {
        # 1. Assess current state
        Write-Host "`n=== ASSESSING CURRENT STATE ===" -ForegroundColor Cyan
        "=== INITIAL STATE ASSESSMENT ===" | Out-File $recoveryLog -Append

        $currentState = Invoke-BulkSiteOperation -SitePattern "*$Scope*" -Operation "Status"
        $currentState | Out-String | Out-File $recoveryLog -Append

        $failedSites = $currentState | Where-Object {$_.Status -eq "Error"}
        Write-Host "Sites requiring recovery: $($failedSites.Count)" -ForegroundColor Red

        # 2. Attempt automatic recovery
        if($failedSites.Count -gt 0) {
            Write-Host "`n=== AUTOMATIC RECOVERY ATTEMPT ===" -ForegroundColor Yellow
            "=== AUTOMATIC RECOVERY ATTEMPT ===" | Out-File $recoveryLog -Append

            foreach($site in $failedSites) {
                Write-Host "Recovering: $($site.Site)" -ForegroundColor Yellow
                try {
                    $success = Invoke-SiteRecovery $site.Site
                    if($success) {
                        Write-Host "✓ $($site.Site) recovered" -ForegroundColor Green
                        "SUCCESS: $($site.Site) recovered" | Out-File $recoveryLog -Append
                    } else {
                        Write-Host "✗ $($site.Site) recovery failed" -ForegroundColor Red
                        "FAILED: $($site.Site) recovery failed" | Out-File $recoveryLog -Append
                    }
                } catch {
                    Write-Host "✗ $($site.Site) recovery error: $($_.Exception.Message)" -ForegroundColor Red
                    "ERROR: $($site.Site) - $($_.Exception.Message)" | Out-File $recoveryLog -Append
                }
            }
        }

        # 3. Final state assessment
        Write-Host "`n=== FINAL STATE ASSESSMENT ===" -ForegroundColor Cyan
        "=== FINAL STATE ASSESSMENT ===" | Out-File $recoveryLog -Append

        $finalState = Invoke-BulkSiteOperation -SitePattern "*$Scope*" -Operation "HealthCheck"
        $finalState | Out-String | Out-File $recoveryLog -Append

        $stillFailed = $finalState | Where-Object {$_.Status -eq "Error"}

        if($stillFailed.Count -eq 0) {
            Write-Host "✓ ALL SITES RECOVERED SUCCESSFULLY" -ForegroundColor Green -BackgroundColor Black
            "DISASTER RECOVERY SUCCESSFUL - ALL SITES OPERATIONAL" | Out-File $recoveryLog -Append
        } else {
            Write-Host "⚠ $($stillFailed.Count) SITES STILL REQUIRE MANUAL INTERVENTION" -ForegroundColor Red -BackgroundColor White
            Write-Host "Failed sites:" -ForegroundColor Red
            $stillFailed | ForEach-Object { Write-Host "  - $($_.Site)" -ForegroundColor Red }

            "MANUAL INTERVENTION REQUIRED FOR:" | Out-File $recoveryLog -Append
            $stillFailed | ForEach-Object { "  - $($_.Site)" | Out-File $recoveryLog -Append }
        }

    } catch {
        Write-Host "DISASTER RECOVERY ERROR: $($_.Exception.Message)" -ForegroundColor Red
        "DISASTER RECOVERY ERROR: $($_.Exception.Message)" | Out-File $recoveryLog -Append
    } finally {
        Write-Host "`nRecovery log saved to: $recoveryLog" -ForegroundColor White
    }
}

# Use during major outage
Invoke-DisasterRecovery -Scope "prod"


Real-World Scenarios

Complete Monitoring Setup

# Complete monitoring solution setup
function Deploy-ComprehensiveMonitoring {
    Write-Host "DEPLOYING COMPREHENSIVE IIS MONITORING" -ForegroundColor Green -BackgroundColor Black

    # 1. Identify site categories
    $sites = Get-IISSite
    $criticalSites = $sites | Where-Object {$_.Name -like "*prod*" -or $_.Name -like "*payment*" -or $_.Name -like "*auth*"}
    $importantSites = $sites | Where-Object {$_.Name -like "*api*" -or $_.Name -like "*service*"}
    $standardSites = $sites | Where-Object {$_.Name -notlike "*prod*" -and $_.Name -notlike "*payment*" -and $_.Name -notlike "*auth*" -and $_.Name -notlike "*api*" -and $_.Name -notlike "*service*"}

    Write-Host "`nSite Categories:" -ForegroundColor Cyan
    Write-Host "Critical ($($criticalSites.Count)): $($criticalSites.Name -join ', ')" -ForegroundColor Red
    Write-Host "Important ($($importantSites.Count)): $($importantSites.Name -join ', ')" -ForegroundColor Yellow  
    Write-Host "Standard ($($standardSites.Count)): $($standardSites.Name -join ', ')" -ForegroundColor White

    # 2. Initial health check
    Write-Host "`n=== INITIAL HEALTH ASSESSMENT ===" -ForegroundColor Cyan
    foreach($site in $sites) {
        $health = Test-IISSiteHealth $site.Name
        $color = switch($health.OverallHealth) { "Healthy"{"Green"} "Warning"{"Yellow"} "Critical"{"Red"} }
        Write-Host "$($site.Name): $($health.OverallHealth)" -ForegroundColor $color
    }

    # 3. Start monitoring services
    Write-Host "`n=== STARTING MONITORING SERVICES ===" -ForegroundColor Green

    if($criticalSites.Count -gt 0) {
        Write-Host "Starting critical site monitoring (30s intervals)..." -ForegroundColor Red
        Start-Job -Name "CriticalMonitoring" -ScriptBlock {
            param($sites)
            Import-Module WebAdministration,IISAdministration
            Start-IISAutoRecovery -SiteNames $sites -CheckInterval 30 -MaxRestartAttempts 5
        } -ArgumentList $criticalSites.Name
    }

    if($importantSites.Count -gt 0) {
        Write-Host "Starting important site monitoring (60s intervals)..." -ForegroundColor Yellow
        Start-Job -Name "ImportantMonitoring" -ScriptBlock {
            param($sites) 
            Import-Module WebAdministration,IISAdministration
            Start-IISAutoRecovery -SiteNames $sites -CheckInterval 60 -MaxRestartAttempts 3
        } -ArgumentList $importantSites.Name
    }

    if($standardSites.Count -gt 0) {
        Write-Host "Starting standard site monitoring (300s intervals)..." -ForegroundColor White
        Start-Job -Name "StandardMonitoring" -ScriptBlock {
            param($sites)
            Import-Module WebAdministration,IISAdministration 
            Start-IISAutoRecovery -SiteNames $sites -CheckInterval 300 -MaxRestartAttempts 2
        } -ArgumentList $standardSites.Name
    }

    # 4. Show monitoring status
    Write-Host "`n=== MONITORING STATUS ===" -ForegroundColor Green
    Get-Job | Where-Object {$_.Name -like "*Monitoring"} | Format-Table Name, State -AutoSize

    Write-Host "`nMonitoring deployed successfully!" -ForegroundColor Green
    Write-Host "Use 'Get-Job' to check status" -ForegroundColor White
    Write-Host "Use 'Stop-Job -Name JobName' to stop specific monitoring" -ForegroundColor White
    Write-Host "Use 'Get-Job | Stop-Job' to stop all monitoring" -ForegroundColor White
}

Deploy-ComprehensiveMonitoring

Deployment Pipeline Integration

# Complete deployment pipeline with monitoring
function Invoke-DeploymentPipeline {
    param(
        [string[]]$SiteNames,
        [string]$DeploymentPackage,
        [int]$MonitoringMinutes = 30
    )

    $deploymentStart = Get-Date
    Write-Host "DEPLOYMENT PIPELINE STARTED" -ForegroundColor Cyan -BackgroundColor Black
    Write-Host "Sites: $($SiteNames -join ', ')" -ForegroundColor White
    Write-Host "Package: $DeploymentPackage" -ForegroundColor White
    Write-Host "Start Time: $deploymentStart" -ForegroundColor White

    try {
        # 1. Pre-deployment health check
        Write-Host "`n=== PRE-DEPLOYMENT HEALTH CHECK ===" -ForegroundColor Cyan
        $preDeployHealth = @{}
        foreach($site in $SiteNames) {
            $health = Test-IISSiteHealth $site -IncludePerformance
            $preDeployHealth[$site] = $health

            if($health.OverallHealth -eq "Critical") {
                throw "Pre-deployment check failed: $site has critical issues"
            } elseif($health.OverallHealth -eq "Warning") {
                Write-Host "WARNING: $site has warnings but deployment can proceed" -ForegroundColor Yellow
            } else {
                Write-Host "✓ $site ready for deployment" -ForegroundColor Green
            }
        }

        # 2. Start deployment monitoring
        Write-Host "`n=== STARTING DEPLOYMENT MONITORING ===" -ForegroundColor Yellow
        $monitoringJob = Start-Job -ScriptBlock {
            param($sites, $minutes)
            Import-Module WebAdministration,IISAdministration
            Start-IISAutoRecovery -SiteNames $sites -CheckInterval 15 -MaxRestartAttempts 2
        } -ArgumentList $SiteNames, $MonitoringMinutes

        # 3. Deploy application
        Write-Host "`n=== DEPLOYING APPLICATION ===" -ForegroundColor Green
        foreach($site in $SiteNames) {
            Write-Host "Deploying to: $site" -ForegroundColor Yellow

            # Stop site
            Stop-IISSite $site
            Write-Host "  Site stopped" -ForegroundColor White

            # Deploy files (simulate deployment)
            Write-Host "  Deploying files..." -ForegroundColor White
            Start-Sleep 5  # Simulate deployment time

            # Start site
            Start-IISSite $site
            Write-Host "  Site started" -ForegroundColor Green

            # Wait for site to be ready
            Start-Sleep 10
        }

        # 4. Post-deployment verification
        Write-Host "`n=== POST-DEPLOYMENT VERIFICATION ===" -ForegroundColor Cyan
        $allHealthy = $true
        foreach($site in $SiteNames) {
            Write-Host "Verifying: $site" -ForegroundColor Yellow

            # Health check
            $postHealth = Test-IISSiteHealth $site -IncludePerformance

            if($postHealth.OverallHealth -ne "Healthy") {
                Write-Host "✗ $site verification failed: $($postHealth.OverallHealth)" -ForegroundColor Red
                $allHealthy = $false
            } else {
                Write-Host "✓ $site verification passed" -ForegroundColor Green
            }
        }

        # 5. Generate deployment report
        $deploymentEnd = Get-Date
        $duration = $deploymentEnd - $deploymentStart

        Write-Host "`n=== DEPLOYMENT SUMMARY ===" -ForegroundColor Cyan
        Write-Host "Status: $(if($allHealthy){'SUCCESS'}else{'FAILED'})" -ForegroundColor $(if($allHealthy){'Green'}else{'Red'})
        Write-Host "Duration: $($duration.TotalMinutes.ToString('F1')) minutes" -ForegroundColor White
        Write-Host "Sites: $($SiteNames -join ', ')" -ForegroundColor White

        if($allHealthy) {
            Write-Host "✓ DEPLOYMENT COMPLETED SUCCESSFULLY" -ForegroundColor Green -BackgroundColor Black
        } else {
            Write-Host "✗ DEPLOYMENT VERIFICATION FAILED" -ForegroundColor Red -BackgroundColor White
            throw "Deployment verification failed"
        }

    } catch {
        Write-Host "`nDEPLOYMENT ERROR: $($_.Exception.Message)" -ForegroundColor Red

        # Rollback attempt
        Write-Host "Attempting automatic rollback..." -ForegroundColor Yellow
        foreach($site in $SiteNames) {
            try {
                Invoke-SiteRecovery $site
                Write-Host "✓ $site recovery attempted" -ForegroundColor Yellow
            } catch {
                Write-Host "✗ $site recovery failed" -ForegroundColor Red
            }
        }

        throw "Deployment failed and rollback attempted"

    } finally {
        # Stop monitoring
        if($monitoringJob) {
            Stop-Job $monitoringJob -ErrorAction SilentlyContinue
            Remove-Job $monitoringJob -ErrorAction SilentlyContinue
        }

        Write-Host "`nDeployment monitoring stopped" -ForegroundColor Gray
    }
}

# USAGE EXAMPLES:

# Simple deployment
# REPLACE WITH YOUR REAL SITE NAMES:
Invoke-DeploymentPipeline -SiteNames @("[YOUR_SITE1]", "[YOUR_SITE2]") -DeploymentPackage "v2.1.0"

# REAL EXAMPLE:
Invoke-DeploymentPipeline -SiteNames @("Default Web Site", "MyAPI") -DeploymentPackage "v2.1.0"

# Extended monitoring during deployment
Invoke-DeploymentPipeline -SiteNames @("CriticalSite") -DeploymentPackage "v2.1.0" -MonitoringMinutes 60

Emergency Response Playbook

# Complete emergency response workflow
function Invoke-EmergencyResponse {
    param(
        [string]$IncidentType,
        [string[]]$AffectedSites = @(),
        [string]$Severity = "High"
    )

    $incidentStart = Get-Date
    $incidentId = "INC-$(Get-Date -Format 'yyyyMMdd-HHmmss')"

    Write-Host "🚨 EMERGENCY RESPONSE ACTIVATED 🚨" -ForegroundColor Red -BackgroundColor White
    Write-Host "Incident ID: $incidentId" -ForegroundColor White
    Write-Host "Type: $IncidentType" -ForegroundColor White
    Write-Host "Severity: $Severity" -ForegroundColor White
    Write-Host "Start Time: $incidentStart" -ForegroundColor White

    $logFile = "Emergency_$incidentId.log"
    "Emergency Response Log - $incidentId" | Out-File $logFile
    "Incident Type: $IncidentType" | Out-File $logFile -Append
    "Severity: $Severity" | Out-File $logFile -Append
    "Start Time: $incidentStart" | Out-File $logFile -Append

    try {
        # 1. Immediate assessment
        Write-Host "`n=== IMMEDIATE ASSESSMENT ===" -ForegroundColor Red
        "=== IMMEDIATE ASSESSMENT ===" | Out-File $logFile -Append

        if($AffectedSites.Count -eq 0) {
            # Auto-detect affected sites
            Write-Host "Auto-detecting affected sites..." -ForegroundColor Yellow
            $allSites = Get-IISSite
            $AffectedSites = @()

            foreach($site in $allSites) {
                try {
                    $response = Invoke-WebRequest "http://localhost" -UseBasicParsing -TimeoutSec 5
                    if($response.StatusCode -ne 200) {
                        $AffectedSites += $site.Name
                    }
                } catch {
                    $AffectedSites += $site.Name
                }
            }
        }

        Write-Host "Affected sites: $($AffectedSites.Count)" -ForegroundColor Red
        $AffectedSites | ForEach-Object { 
            Write-Host "  - $_" -ForegroundColor Red
            "AFFECTED: $_" | Out-File $logFile -Append
        }

        # 2. Emergency recovery
        Write-Host "`n=== EMERGENCY RECOVERY ===" -ForegroundColor Yellow
        "=== EMERGENCY RECOVERY ===" | Out-File $logFile -Append

        $recoveredSites = @()
        $failedSites = @()

        foreach($site in $AffectedSites) {
            Write-Host "Emergency recovery: $site" -ForegroundColor Yellow
            try {
                $success = Invoke-SiteRecovery $site
                if($success) {
                    $recoveredSites += $site
                    Write-Host "✓ $site recovered" -ForegroundColor Green
                    "RECOVERED: $site" | Out-File $logFile -Append
                } else {
                    $failedSites += $site
                    Write-Host "✗ $site recovery failed" -ForegroundColor Red
                    "FAILED RECOVERY: $site" | Out-File $logFile -Append
                }
            } catch {
                $failedSites += $site
                Write-Host "✗ $site recovery error: $($_.Exception.Message)" -ForegroundColor Red
                "ERROR: $site - $($_.Exception.Message)" | Out-File $logFile -Append
            }
        }

        # 3. Service restoration verification
        Write-Host "`n=== SERVICE RESTORATION VERIFICATION ===" -ForegroundColor Cyan
        "=== SERVICE RESTORATION VERIFICATION ===" | Out-File $logFile -Append

        Start-Sleep 30  # Allow time for services to stabilize

        $finalStatus = @()
        foreach($site in $AffectedSites) {
            $health = Test-IISSiteHealth $site
            $finalStatus += [PSCustomObject]@{
                Site = $site
                Status = $health.OverallHealth
                Recovered = $recoveredSites -contains $site
            }
        }

        # 4. Incident summary
        Write-Host "`n=== INCIDENT SUMMARY ===" -ForegroundColor Cyan
        "=== INCIDENT SUMMARY ===" | Out-File $logFile -Append

        $incidentEnd = Get-Date
        $duration = $incidentEnd - $incidentStart
        $fullyRecovered = ($finalStatus | Where-Object {$_.Status -eq "Healthy"}).Count
        $totalAffected = $AffectedSites.Count

        Write-Host "Incident Duration: $($duration.TotalMinutes.ToString('F1')) minutes" -ForegroundColor White
        Write-Host "Sites Affected: $totalAffected" -ForegroundColor White
        Write-Host "Sites Recovered: $fullyRecovered" -ForegroundColor Green
        Write-Host "Sites Still Down: $($totalAffected - $fullyRecovered)" -ForegroundColor Red

        "Duration: $($duration.TotalMinutes.ToString('F1')) minutes" | Out-File $logFile -Append
        "Sites Affected: $totalAffected" | Out-File $logFile -Append
        "Sites Recovered: $fullyRecovered" | Out-File $logFile -Append
        "Sites Still Down: $($totalAffected - $fullyRecovered)" | Out-File $logFile -Append

        if($fullyRecovered -eq $totalAffected) {
            Write-Host "`n✅ ALL SERVICES RESTORED" -ForegroundColor Green -BackgroundColor Black
            "INCIDENT RESOLVED - ALL SERVICES RESTORED" | Out-File $logFile -Append
        } else {
            Write-Host "`n⚠️ PARTIAL RECOVERY - ESCALATION REQUIRED" -ForegroundColor Red -BackgroundColor White
            "PARTIAL RECOVERY - MANUAL INTERVENTION REQUIRED" | Out-File $logFile -Append

            Write-Host "`nSites requiring manual intervention:" -ForegroundColor Red
            $finalStatus | Where-Object {$_.Status -ne "Healthy"} | ForEach-Object {
                Write-Host "  - $($_.Site): $($_.Status)" -ForegroundColor Red
                "MANUAL REQUIRED: $($_.Site) - $($_.Status)" | Out-File $logFile -Append
            }
        }

    } catch {
        Write-Host "`nEMERGENCY RESPONSE ERROR: $($_.Exception.Message)" -ForegroundColor Red
        "EMERGENCY RESPONSE ERROR: $($_.Exception.Message)" | Out-File $logFile -Append
    } finally {
        Write-Host "`nEmergency response log: $logFile" -ForegroundColor White
        Write-Host "Incident ID: $incidentId" -ForegroundColor White
    }
}

# USAGE EXAMPLES:

# Auto-detect and recover all down sites
Invoke-EmergencyResponse -IncidentType "Mass Site Outage" -Severity "Critical"

# Target specific sites
# REPLACE WITH YOUR REAL SITE NAMES:
Invoke-EmergencyResponse -IncidentType "Payment System Down" -AffectedSites @("[YOUR_PAYMENT_SITE]", "[YOUR_AUTH_SITE]") -Severity "Critical"

# REAL EXAMPLE:
Invoke-EmergencyResponse -IncidentType "Main Sites Down" -AffectedSites @("Default Web Site", "MyAPI") -Severity "High"

Daily Operations Workflow

# Complete daily operations checklist
function Invoke-DailyOperations {
    param([string]$Environment = "production")

    $dailyStart = Get-Date
    $reportDate = Get-Date -Format "yyyy-MM-dd"
    $reportFile = "DailyOps_$reportDate.html"

    Write-Host "📊 DAILY OPERATIONS CHECKLIST - $reportDate" -ForegroundColor Cyan -BackgroundColor Black

    $htmlReport = @"
<!DOCTYPE html>
<html>
<head>
    <title>Daily Operations Report - $reportDate</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .header { background-color: #2c3e50; color: white; padding: 20px; text-align: center; }
        .section { margin: 20px 0; padding: 15px; border-left: 4px solid #3498db; }
        .healthy { color: green; font-weight: bold; }
        .warning { color: orange; font-weight: bold; }
        .critical { color: red; font-weight: bold; }
        table { width: 100%; border-collapse: collapse; margin: 10px 0; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <div class="header">
        <h1>Daily Operations Report</h1>
        <h2>$reportDate - $env:COMPUTERNAME</h2>
    </div>
"@

    try {
        # 1. System Health Check
        Write-Host "`n=== SYSTEM HEALTH CHECK ===" -ForegroundColor Green
        $htmlReport += "<div class='section'><h2>System Health Check</h2>"

        # IIS Services
        $services = Get-Service W3SVC, WAS, IISADMIN
        $htmlReport += "<h3>IIS Services</h3><table><tr><th>Service</th><th>Status</th></tr>"

        foreach($service in $services) {
            $status = $service.Status
            $statusClass = if($status -eq "Running") {"healthy"} else {"critical"}
            Write-Host "$($service.Name): $status" -ForegroundColor $(if($status -eq "Running"){"Green"}else{"Red"})
            $htmlReport += "<tr><td>$($service.Name)</td><td class='$statusClass'>$status</td></tr>"
        }
        $htmlReport += "</table>"

        # 2. Site Health Assessment
        Write-Host "`n=== SITE HEALTH ASSESSMENT ===" -ForegroundColor Green
        $htmlReport += "<h3>Site Health Assessment</h3><table><tr><th>Site</th><th>State</th><th>App Pool</th><th>Health</th><th>Response</th></tr>"

        $sites = Get-IISSite | Where-Object {$_.Name -like "*$Environment*" -or $Environment -eq "all"}
        $healthySites = 0
        $warningSites = 0
        $criticalSites = 0

        foreach($site in $sites) {
            Write-Host "Checking: $($site.Name)" -ForegroundColor Yellow

            $health = Test-IISSiteHealth $site.Name
            $appPool = (Get-IISAppPool $site.Applications[0].ApplicationPoolName).State

            # Test HTTP response
            $httpStatus = "Unknown"
            try {
                $binding = Get-IISSiteBinding $site.Name | Where-Object {$_.Protocol -eq "http"} | Select-Object -First 1
                if($binding) {
                    $testUrl = "http://localhost$($binding.BindingInformation.Split(':')[1])"
                    $response = Invoke-WebRequest $testUrl -UseBasicParsing -TimeoutSec 5
                    $httpStatus = $response.StatusCode
                }
            } catch {
                $httpStatus = "Failed"
            }

            $healthClass = switch($health.OverallHealth) {
                "Healthy" { $healthySites++; "healthy" }
                "Warning" { $warningSites++; "warning" }
                "Critical" { $criticalSites++; "critical" }
            }

            Write-Host "  $($site.Name): $($health.OverallHealth)" -ForegroundColor $(switch($health.OverallHealth) {"Healthy"{"Green"} "Warning"{"Yellow"} "Critical"{"Red"}})

            $htmlReport += "<tr><td>$($site.Name)</td><td>$($site.State)</td><td>$appPool</td><td class='$healthClass'>$($health.OverallHealth)</td><td>$httpStatus</td></tr>"
        }
        $htmlReport += "</table>"

        # 3. Performance Summary
        Write-Host "`n=== PERFORMANCE SUMMARY ===" -ForegroundColor Green
        $htmlReport += "<h3>Performance Summary</h3><table><tr><th>Metric</th><th>Value</th></tr>"

        # Memory usage
        $totalMemory = (Get-Process w3wp -ErrorAction SilentlyContinue | Measure-Object -Property WorkingSet -Sum).Sum / 1GB
        Write-Host "Total IIS Memory Usage: $([math]::Round($totalMemory, 2))GB" -ForegroundColor White
        $htmlReport += "<tr><td>Total IIS Memory Usage</td><td>$([math]::Round($totalMemory, 2))GB</td></tr>"

        # Active connections
        try {
            $connections = (Get-Counter "\Web Service(_Total)\Current Connections" -SampleInterval 1 -MaxSamples 1).CounterSamples[0].CookedValue
            Write-Host "Total Active Connections: $connections" -ForegroundColor White
            $htmlReport += "<tr><td>Total Active Connections</td><td>$connections</td></tr>"
        } catch {
            Write-Host "Total Active Connections: Unable to retrieve" -ForegroundColor Gray
            $htmlReport += "<tr><td>Total Active Connections</td><td>Unable to retrieve</td></tr>"
        }

        # Worker processes
        $workerProcesses = (Get-Process w3wp -ErrorAction SilentlyContinue).Count
        Write-Host "Active Worker Processes: $workerProcesses" -ForegroundColor White
        $htmlReport += "<tr><td>Active Worker Processes</td><td>$workerProcesses</td></tr>"

        $htmlReport += "</table>"

        # 4. Disk Space Check
        Write-Host "`n=== DISK SPACE CHECK ===" -ForegroundColor Green
        $htmlReport += "<h3>Disk Space Check</h3><table><tr><th>Drive</th><th>Total (GB)</th><th>Free (GB)</th><th>Free %</th><th>Status</th></tr>"

        $drives = Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3}
        foreach($drive in $drives) {
            $totalGB = [math]::Round($drive.Size / 1GB, 2)
            $freeGB = [math]::Round($drive.FreeSpace / 1GB, 2)
            $freePercent = [math]::Round(($drive.FreeSpace / $drive.Size) * 100, 1)

            $status = if($freePercent -gt 20) {"OK"} elseif($freePercent -gt 10) {"Warning"} else {"Critical"}
            $statusClass = switch($status) {"OK"{"healthy"} "Warning"{"warning"} "Critical"{"critical"}}

            Write-Host "$($drive.DeviceID) $totalGB GB total, $freeGB GB free ($freePercent%) - $status" -ForegroundColor $(switch($status) {"OK"{"Green"} "Warning"{"Yellow"} "Critical"{"Red"}})

            $htmlReport += "<tr><td>$($drive.DeviceID)</td><td>$totalGB</td><td>$freeGB</td><td>$freePercent%</td><td class='$statusClass'>$status</td></tr>"
        }
        $htmlReport += "</table>"

        # 5. Recent Errors
        Write-Host "`n=== RECENT ERRORS ===" -ForegroundColor Green
        $htmlReport += "<h3>Recent Errors (Last 24 Hours)</h3><table><tr><th>Time</th><th>Source</th><th>Event ID</th><th>Message</th></tr>"

        $yesterday = (Get-Date).AddDays(-1)
        $recentErrors = Get-EventLog -LogName Application -EntryType Error -After $yesterday | 
                       Where-Object {$_.Source -like "*IIS*" -or $_.Source -like "*ASP.NET*"} | 
                       Select-Object -First 10

        if($recentErrors.Count -gt 0) {
            foreach($error in $recentErrors) {
                Write-Host "$($error.TimeGenerated) - $($error.Source) - $($error.EventID)" -ForegroundColor Red
                $htmlReport += "<tr><td>$($error.TimeGenerated)</td><td>$($error.Source)</td><td>$($error.EventID)</td><td>$($error.Message.Substring(0, [math]::Min(100, $error.Message.Length)))...</td></tr>"
            }
        } else {
            Write-Host "No recent IIS errors found" -ForegroundColor Green
            $htmlReport += "<tr><td colspan='4'>No recent IIS errors found</td></tr>"
        }
        $htmlReport += "</table></div>"

        # 6. Summary
        $dailyEnd = Get-Date
        $duration = $dailyEnd - $dailyStart

        Write-Host "`n=== DAILY OPERATIONS SUMMARY ===" -ForegroundColor Cyan
        $htmlReport += "<div class='section'><h2>Summary</h2>"

        Write-Host "Check Duration: $($duration.TotalMinutes.ToString('F1')) minutes" -ForegroundColor White
        Write-Host "Sites Checked: $($sites.Count)" -ForegroundColor White
        Write-Host "Healthy Sites: $healthySites" -ForegroundColor Green
        Write-Host "Warning Sites: $warningSites" -ForegroundColor Yellow
        Write-Host "Critical Sites: $criticalSites" -ForegroundColor Red

        $overallStatus = if($criticalSites -eq 0 -and $warningSites -eq 0) {"All Systems Operational"} 
                        elseif($criticalSites -eq 0) {"Minor Issues Detected"} 
                        else {"Critical Issues Require Attention"}

        $statusClass = if($criticalSites -eq 0 -and $warningSites -eq 0) {"healthy"} 
                      elseif($criticalSites -eq 0) {"warning"} 
                      else {"critical"}

        Write-Host "Overall Status: $overallStatus" -ForegroundColor $(switch($statusClass) {"healthy"{"Green"} "warning"{"Yellow"} "critical"{"Red"}})

        $htmlReport += @"
<p><strong>Check Duration:</strong> $($duration.TotalMinutes.ToString('F1')) minutes</p>
<p><strong>Sites Checked:</strong> $($sites.Count)</p>
<p><strong>Healthy Sites:</strong> <span class="healthy">$healthySites</span></p>
<p><strong>Warning Sites:</strong> <span class="warning">$warningSites</span></p>
<p><strong>Critical Sites:</strong> <span class="critical">$criticalSites</span></p>
<p><strong>Overall Status:</strong> <span class="$statusClass">$overallStatus</span></p>
</div>
</body>
</html>
"@

        # Save HTML report
        $htmlReport | Out-File $reportFile -Encoding UTF8
        Write-Host "`nDaily operations report saved: $reportFile" -ForegroundColor White

        # Open report in browser
        Start-Process $reportFile

    } catch {
        Write-Host "`nDAILY OPERATIONS ERROR: $($_.Exception.Message)" -ForegroundColor Red
    }
}

# USAGE EXAMPLES:

# Daily check for production environment
Invoke-DailyOperations -Environment "production"

# Check all sites
Invoke-DailyOperations -Environment "all"

# Check test environment
Invoke-DailyOperations -Environment "test"

Final Summary

The functions in this guide provide:

Complete site monitoring with real-time dashboards ✅ Smart restart capabilities with progressive recovery
Automated health checks with detailed reporting ✅ Emergency response workflows for major incidents ✅ Performance monitoring and analysis tools ✅ Bulk operations for managing multiple sites ✅ Daily operations automation and reporting

Quick deployment: 1. Copy all functions to your PowerShell profile 2. Run the Quick Start commands to test 3. Replace [YOUR_SITE_NAME] placeholders with real site names 4. Set up monitoring for critical sites

Most useful for daily operations: - Watch-IISSite for real-time monitoring - Test-IISSiteHealth for health checks
- Restart-IISSiteComplete for reliable restarts - Invoke-DailyOperations for daily reporting - Start-IISAutoRecovery for automated recovery

All functions include proper error handling, logging, and can be used in production environments.