<# .SYNOPSIS Enable HTTPS for ROA2WEB on IIS .DESCRIPTION This script configures HTTPS for ROA2WEB by: - Creating a self-signed SSL certificate (or using existing certificate) - Configuring HTTPS binding on IIS site - Enabling HTTP to HTTPS redirect .PARAMETER IISSiteName IIS Site name (default: Default Web Site) .PARAMETER CertificateDnsName DNS name for certificate (default: server IP or hostname) .PARAMETER UseExistingCert Use existing certificate by thumbprint .PARAMETER CertThumbprint Thumbprint of existing certificate to use .PARAMETER Port HTTPS port (default: 443) .EXAMPLE .\Enable-HTTPS.ps1 Create self-signed certificate and enable HTTPS .EXAMPLE .\Enable-HTTPS.ps1 -IISSiteName "ROA2WEB" -CertificateDnsName "roa2web.company.com" Create certificate with custom DNS name .EXAMPLE .\Enable-HTTPS.ps1 -UseExistingCert -CertThumbprint "ABC123..." Use existing certificate .NOTES Author: ROA2WEB Team Requires: PowerShell 5.1+, Administrator privileges #> [CmdletBinding()] param( [string]$IISSiteName = "Default Web Site", [string]$CertificateDnsName = "", [switch]$UseExistingCert, [string]$CertThumbprint = "", [int]$Port = 443, [string]$IPAddress = "*" ) $ErrorActionPreference = "Stop" # ============================================================================= # HELPER FUNCTIONS # ============================================================================= function Write-Step { param([string]$Message) Write-Host "`n[*] $Message" -ForegroundColor Cyan } function Write-Success { param([string]$Message) Write-Host " [OK] $Message" -ForegroundColor Green } function Write-Error { param([string]$Message) Write-Host " [ERROR] $Message" -ForegroundColor Red } function Write-Warning { param([string]$Message) Write-Host " [WARN] $Message" -ForegroundColor Yellow } function Test-Administrator { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = [Security.Principal.WindowsPrincipal]$identity return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } # ============================================================================= # MAIN SCRIPT # ============================================================================= Write-Host @" ==================================================================== ROA2WEB - Enable HTTPS on IIS ==================================================================== "@ -ForegroundColor Cyan # Check administrator privileges if (-not (Test-Administrator)) { Write-Error "This script must be run as Administrator" Write-Host " Right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow exit 1 } Write-Success "Running as Administrator" # Import required modules Write-Step "Loading IIS module..." Import-Module WebAdministration -ErrorAction Stop Write-Success "IIS module loaded" # Verify IIS site exists Write-Step "Verifying IIS site '$IISSiteName'..." $site = Get-Website -Name $IISSiteName -ErrorAction SilentlyContinue if (-not $site) { Write-Error "IIS site '$IISSiteName' not found" Write-Host "`nAvailable sites:" -ForegroundColor Yellow Get-Website | Format-Table Name, State, PhysicalPath exit 1 } Write-Success "IIS site found: $IISSiteName (State: $($site.State))" # Get or create certificate if ($UseExistingCert) { Write-Step "Using existing certificate..." if ([string]::IsNullOrEmpty($CertThumbprint)) { Write-Host "`nAvailable certificates in LocalMachine\My:" -ForegroundColor Yellow Get-ChildItem -Path "cert:\LocalMachine\My" | Select-Object Thumbprint, Subject, FriendlyName, NotAfter | Format-Table -AutoSize $CertThumbprint = Read-Host "Enter certificate thumbprint" } $cert = Get-ChildItem -Path "cert:\LocalMachine\My\$CertThumbprint" -ErrorAction SilentlyContinue if (-not $cert) { Write-Error "Certificate with thumbprint '$CertThumbprint' not found" exit 1 } Write-Success "Certificate found: $($cert.Subject)" } else { Write-Step "Creating self-signed SSL certificate..." # Auto-detect DNS name if not provided if ([string]::IsNullOrEmpty($CertificateDnsName)) { $serverName = $env:COMPUTERNAME $ipAddress = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -notlike "127.*" -and $_.IPAddress -notlike "169.*"} | Select-Object -First 1).IPAddress Write-Host " Detected hostname: $serverName" -ForegroundColor Yellow Write-Host " Detected IP: $ipAddress" -ForegroundColor Yellow $response = Read-Host "Use hostname for certificate? (Y/n)" if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") { $CertificateDnsName = $serverName } else { $CertificateDnsName = $ipAddress } } # Check if certificate already exists $existingCert = Get-ChildItem -Path "cert:\LocalMachine\My" | Where-Object {$_.DnsNameList -contains $CertificateDnsName} | Select-Object -First 1 if ($existingCert) { Write-Warning "Certificate for '$CertificateDnsName' already exists" $response = Read-Host "Use existing certificate? (Y/n)" if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") { $cert = $existingCert Write-Success "Using existing certificate" } else { Write-Warning "Removing existing certificate..." Remove-Item -Path "cert:\LocalMachine\My\$($existingCert.Thumbprint)" -Force } } if (-not $cert) { # Create new certificate $cert = New-SelfSignedCertificate ` -DnsName $CertificateDnsName ` -CertStoreLocation "cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(5) ` -FriendlyName "ROA2WEB SSL Certificate" ` -KeyUsage DigitalSignature, KeyEncipherment ` -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1") Write-Success "Certificate created successfully" Write-Host " DNS Name: $CertificateDnsName" -ForegroundColor Yellow Write-Host " Thumbprint: $($cert.Thumbprint)" -ForegroundColor Yellow Write-Host " Valid Until: $($cert.NotAfter)" -ForegroundColor Yellow } } # Configure HTTPS binding Write-Step "Configuring HTTPS binding..." # Check if HTTPS binding already exists $existingBinding = Get-WebBinding -Name $IISSiteName -Protocol "https" -Port $Port -ErrorAction SilentlyContinue if ($existingBinding) { Write-Warning "HTTPS binding already exists on port $Port" $response = Read-Host "Remove and recreate binding? (Y/n)" if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") { Remove-WebBinding -Name $IISSiteName -Protocol "https" -Port $Port -ErrorAction SilentlyContinue Write-Success "Existing binding removed" } else { Write-Warning "Skipping binding creation" $existingBinding = $null } } if (-not $existingBinding) { # Create HTTPS binding try { New-WebBinding -Name $IISSiteName -Protocol "https" -Port $Port -IPAddress $IPAddress Write-Success "HTTPS binding created on port $Port" } catch { Write-Error "Failed to create HTTPS binding: $_" exit 1 } } # Attach certificate to binding Write-Step "Attaching certificate to HTTPS binding..." try { # Method 1: Using IIS PowerShell Provider (IIS 8+) Push-Location Set-Location IIS:\SslBindings # Remove existing binding if present $sslBinding = "${IPAddress}!${Port}" if ($IPAddress -eq "*") { $sslBinding = "0.0.0.0!${Port}" } if (Test-Path $sslBinding) { Remove-Item $sslBinding -Force -ErrorAction SilentlyContinue } # Create new SSL binding $cert | New-Item $sslBinding Pop-Location Write-Success "Certificate attached to HTTPS binding" } catch { Write-Warning "Method 1 failed, trying alternative method..." try { # Method 2: Using netsh (more compatible) $certHash = $cert.Thumbprint $appId = "{4dc3e181-e14b-4a21-b022-59fc669b0914}" # Remove existing binding netsh http delete sslcert ipport=0.0.0.0:$Port 2>&1 | Out-Null # Add new binding $result = netsh http add sslcert ipport=0.0.0.0:$Port certhash=$certHash appid=$appId if ($LASTEXITCODE -eq 0) { Write-Success "Certificate attached using netsh" } else { Write-Error "Failed to attach certificate: $result" exit 1 } } catch { Write-Error "Failed to attach certificate: $_" exit 1 } } # Update web.config for HTTP to HTTPS redirect Write-Step "Checking web.config for HTTPS redirect..." $webConfigPath = Join-Path $site.PhysicalPath "web.config" if (Test-Path $webConfigPath) { $webConfig = Get-Content $webConfigPath -Raw if ($webConfig -match "Force HTTPS") { Write-Success "HTTPS redirect rule already exists in web.config" } else { Write-Warning "HTTPS redirect rule not found in web.config" Write-Host "`nTo enable automatic HTTP to HTTPS redirect, add this rule to web.config:" -ForegroundColor Yellow Write-Host @" "@ -ForegroundColor Gray $response = Read-Host "`nAdd this rule automatically? (Y/n)" if ($response -eq "" -or $response -eq "Y" -or $response -eq "y") { # Backup web.config $backupPath = "$webConfigPath.backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')" Copy-Item -Path $webConfigPath -Destination $backupPath Write-Success "web.config backed up to: $backupPath" # Add redirect rule $redirectRule = @" "@ $webConfig = $webConfig -replace '()', "`$1`r`n$redirectRule" Set-Content -Path $webConfigPath -Value $webConfig Write-Success "HTTPS redirect rule added to web.config" } } } else { Write-Warning "web.config not found at: $webConfigPath" Write-Host " Please ensure web.config exists and contains proper rewrite rules" -ForegroundColor Yellow } # Test configuration Write-Step "Testing configuration..." # Restart IIS site to apply changes try { Stop-Website -Name $IISSiteName -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 Start-Website -Name $IISSiteName Write-Success "IIS site restarted" } catch { Write-Warning "Could not restart IIS site: $_" } # Display summary Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan Write-Host " HTTPS CONFIGURATION COMPLETED" -ForegroundColor Green Write-Host ("=" * 70) -ForegroundColor Cyan Write-Host "`nConfiguration Summary:" -ForegroundColor Yellow Write-Host " IIS Site: $IISSiteName" Write-Host " HTTPS Port: $Port" Write-Host " Certificate: $($cert.Subject)" Write-Host " Thumbprint: $($cert.Thumbprint)" Write-Host " Valid Until: $($cert.NotAfter)" Write-Host "`nAccess Points:" -ForegroundColor Yellow Write-Host " HTTPS URL: https://$CertificateDnsName" if ($site.Bindings.Collection | Where-Object {$_.protocol -eq "http"}) { Write-Host " HTTP URL: http://$CertificateDnsName (will redirect to HTTPS)" } Write-Host "`nNext Steps:" -ForegroundColor Yellow if ($cert.Subject -match "CN=[\d\.]+") { Write-Host " 1. [RECOMMENDED] Replace self-signed certificate with CA-issued certificate" Write-Host " - Browsers will show security warnings for self-signed certificates" Write-Host " - Use Let's Encrypt, DigiCert, or another CA for production" } Write-Host " 2. Test HTTPS access: https://$CertificateDnsName" Write-Host " 3. Verify HTTP to HTTPS redirect is working" Write-Host " 4. Check browser console for mixed content warnings" Write-Host "`nTroubleshooting:" -ForegroundColor Yellow Write-Host " View IIS bindings: Get-WebBinding -Name '$IISSiteName'" Write-Host " View certificates: Get-ChildItem cert:\LocalMachine\My" Write-Host " Test HTTPS locally: Invoke-WebRequest https://localhost:$Port -SkipCertificateCheck" Write-Host " IIS Manager: inetmgr" Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan Write-Host ""