#Requires -RunAsAdministrator <# .SYNOPSIS Creates a Certificate Authority (CA) for signing WinRM HTTPS certificates .DESCRIPTION This script creates a self-signed Root CA certificate that can be used to sign individual certificates for each shopfloor PC. Once the CA certificate is trusted on management computers, all certificates signed by this CA will be automatically trusted. This is the proper enterprise approach for WinRM HTTPS deployment. .PARAMETER CACommonName Common Name for the Certificate Authority (default: "Shopfloor WinRM CA") .PARAMETER OutputPath Directory to save the CA certificate (default: current directory) .PARAMETER ValidityYears How many years the CA certificate should be valid (default: 10) .PARAMETER ExportPassword Password for exporting the CA certificate with private key .EXAMPLE # Create CA with default settings .\Create-CertificateAuthority.ps1 .EXAMPLE # Create CA with custom name and validity $caPass = ConvertTo-SecureString "MyCAPassword123!" -AsPlainText -Force .\Create-CertificateAuthority.ps1 -CACommonName "GE Shopfloor CA" -ValidityYears 15 -ExportPassword $caPass .NOTES Author: System Administrator Date: 2025-10-17 IMPORTANT SECURITY NOTES: 1. Store the CA private key (.pfx) securely - it can sign certificates for any PC 2. Only authorized personnel should have access to the CA private key 3. Install the CA certificate (.cer) on all management computers 4. The CA private key should NOT be deployed to shopfloor PCs #> param( [Parameter(Mandatory=$false)] [string]$CACommonName = "Shopfloor WinRM CA", [Parameter(Mandatory=$false)] [string]$OutputPath = ".", [Parameter(Mandatory=$false)] [int]$ValidityYears = 10, [Parameter(Mandatory=$false)] [SecureString]$ExportPassword ) Write-Host "" Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan Write-Host "║ Certificate Authority Creation for WinRM HTTPS ║" -ForegroundColor Cyan Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan Write-Host "" # Prompt for password if not provided if (-not $ExportPassword) { Write-Host "Enter a strong password to protect the CA private key:" -ForegroundColor Yellow Write-Host "(This password will be needed to sign certificates)" -ForegroundColor Gray $ExportPassword = Read-Host "CA Password" -AsSecureString $ExportPassword2 = Read-Host "Confirm Password" -AsSecureString # Convert to plain text to compare $pass1 = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ExportPassword)) $pass2 = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($ExportPassword2)) if ($pass1 -ne $pass2) { Write-Host "" Write-Host "✗ Passwords do not match!" -ForegroundColor Red exit 1 } } # Create output directory if needed if (-not (Test-Path $OutputPath)) { New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null } Write-Host "Creating Certificate Authority..." -ForegroundColor Yellow Write-Host " Common Name: $CACommonName" -ForegroundColor Gray Write-Host " Valid for: $ValidityYears years" -ForegroundColor Gray Write-Host "" try { # Create the CA certificate $notAfter = (Get-Date).AddYears($ValidityYears) $caParams = @{ Subject = "CN=$CACommonName" KeyExportPolicy = 'Exportable' KeyUsage = 'CertSign', 'CRLSign', 'DigitalSignature' KeyUsageProperty = 'All' KeyLength = 4096 KeyAlgorithm = 'RSA' HashAlgorithm = 'SHA256' CertStoreLocation = 'Cert:\LocalMachine\My' NotAfter = $notAfter Type = 'Custom' TextExtension = @( '2.5.29.19={text}CA=1&pathlength=0' # Basic Constraints: CA=TRUE '2.5.29.37={text}1.3.6.1.5.5.7.3.1' # Enhanced Key Usage: Server Authentication ) } Write-Host "Generating 4096-bit RSA key pair..." -ForegroundColor Gray $caCert = New-SelfSignedCertificate @caParams Write-Host "✓ Certificate Authority created successfully" -ForegroundColor Green Write-Host "" Write-Host "Certificate Details:" -ForegroundColor Cyan Write-Host " Subject: $($caCert.Subject)" -ForegroundColor White Write-Host " Thumbprint: $($caCert.Thumbprint)" -ForegroundColor White Write-Host " Issuer: $($caCert.Issuer)" -ForegroundColor White Write-Host " Valid From: $($caCert.NotBefore)" -ForegroundColor White Write-Host " Valid Until: $($caCert.NotAfter)" -ForegroundColor White Write-Host " Key Size: 4096-bit RSA" -ForegroundColor White Write-Host "" } catch { Write-Host "✗ Failed to create CA certificate: $($_.Exception.Message)" -ForegroundColor Red exit 1 } # Export CA certificate with private key (PFX) $timestamp = Get-Date -Format "yyyyMMdd" $caFileNameBase = $CACommonName -replace '[^a-zA-Z0-9]', '-' $pfxPath = Join-Path $OutputPath "$caFileNameBase-$timestamp.pfx" Write-Host "Exporting CA certificate with private key..." -ForegroundColor Yellow Write-Host " File: $pfxPath" -ForegroundColor Gray try { Export-PfxCertificate -Cert $caCert -FilePath $pfxPath -Password $ExportPassword | Out-Null Write-Host "✓ CA certificate exported (with private key)" -ForegroundColor Green Write-Host "" Write-Host "⚠ SECURITY WARNING: Protect this file!" -ForegroundColor Yellow Write-Host " This file contains the CA private key and can sign certificates" -ForegroundColor Gray Write-Host " Store it in a secure location (password manager, vault, etc.)" -ForegroundColor Gray Write-Host "" } catch { Write-Host "✗ Failed to export PFX: $($_.Exception.Message)" -ForegroundColor Red exit 1 } # Export CA certificate without private key (CER) for distribution $cerPath = Join-Path $OutputPath "$caFileNameBase-$timestamp.cer" Write-Host "Exporting CA public certificate..." -ForegroundColor Yellow Write-Host " File: $cerPath" -ForegroundColor Gray try { Export-Certificate -Cert $caCert -FilePath $cerPath | Out-Null Write-Host "✓ CA public certificate exported" -ForegroundColor Green Write-Host "" Write-Host " Install this certificate on all management computers" -ForegroundColor Gray Write-Host " to trust certificates signed by this CA" -ForegroundColor Gray Write-Host "" } catch { Write-Host "✗ Failed to export CER: $($_.Exception.Message)" -ForegroundColor Red exit 1 } # Create summary document $summaryPath = Join-Path $OutputPath "CA-CERTIFICATE-INFO.txt" $summaryContent = @" ================================================================================ CERTIFICATE AUTHORITY INFORMATION ================================================================================ Created: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss") CA Details: ----------- Common Name: $CACommonName Thumbprint: $($caCert.Thumbprint) Key Size: 4096-bit RSA Hash Algorithm: SHA256 Valid From: $($caCert.NotBefore) Valid Until: $($caCert.NotAfter) Valid For: $ValidityYears years Files Created: -------------- 1. $pfxPath - CA certificate WITH private key - Protected with password - KEEP SECURE - Can sign certificates for any PC - Needed to sign individual PC certificates 2. $cerPath - CA certificate WITHOUT private key (public only) - Safe to distribute - Install on all management computers - Once installed, all signed certificates will be trusted Certificate Store Location: --------------------------- The CA certificate has been installed in: Cert:\LocalMachine\My\$($caCert.Thumbprint) ================================================================================ NEXT STEPS ================================================================================ 1. SECURE THE CA PRIVATE KEY - Move $pfxPath to secure location - Store password in password manager - Only authorized personnel should have access 2. INSTALL CA ON MANAGEMENT COMPUTERS - Copy $cerPath to management computers - Import to Trusted Root Certification Authorities: Import-Certificate -FilePath "$cerPath" `` -CertStoreLocation Cert:\LocalMachine\Root 3. GENERATE PC CERTIFICATES - Use Sign-PCCertificate.ps1 to create certificates for each PC - Each PC gets its own certificate with proper hostname - All certificates signed by this CA will be trusted 4. DEPLOY TO SHOPFLOOR PCS - Deploy individual PC certificates (NOT the CA certificate) - Each PC only gets its own certificate - CA private key NEVER leaves this secure system ================================================================================ SECURITY BEST PRACTICES ================================================================================ DO: ✓ Store CA private key in secure vault ✓ Limit access to CA private key ✓ Install CA public certificate on management computers ✓ Sign individual certificates for each PC ✓ Monitor certificate usage and expiration DON'T: ✗ Share CA password via email/chat ✗ Copy CA private key to multiple systems ✗ Deploy CA private key to shopfloor PCs ✗ Use same certificate for multiple PCs ✗ Store CA private key in shared network location ================================================================================ CERTIFICATE SIGNING ================================================================================ To create certificates for shopfloor PCs: # Single PC .\Sign-PCCertificate.ps1 -Hostname G9KN7PZ3ESF `` -CAThumbprint $($caCert.Thumbprint) `` -Domain logon.ds.ge.com # Multiple PCs from file .\Sign-BulkPCCertificates.ps1 -HostnameFile shopfloor-hostnames.txt `` -CAThumbprint $($caCert.Thumbprint) `` -Domain logon.ds.ge.com ================================================================================ TROUBLESHOOTING ================================================================================ If certificates aren't trusted: 1. Verify CA certificate is installed in Trusted Root on management PC: Get-ChildItem Cert:\LocalMachine\Root | Where-Object {`$_.Subject -like "*$CACommonName*"} 2. Verify PC certificate is signed by CA: Get-ChildItem Cert:\LocalMachine\My | Where-Object {`$_.Issuer -like "*$CACommonName*"} 3. Verify certificate chain: Test-Certificate -Cert (Get-Item Cert:\LocalMachine\My\THUMBPRINT) ================================================================================ "@ $summaryContent | Out-File -FilePath $summaryPath -Encoding UTF8 Write-Host "✓ Summary document created: $summaryPath" -ForegroundColor Green Write-Host "" # Final summary Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Green Write-Host "║ CERTIFICATE AUTHORITY CREATED ║" -ForegroundColor Green Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Green Write-Host "" Write-Host "Files Created:" -ForegroundColor Cyan Write-Host " 1. $pfxPath" -ForegroundColor White Write-Host " (CA with private key - KEEP SECURE!)" -ForegroundColor Gray Write-Host "" Write-Host " 2. $cerPath" -ForegroundColor White Write-Host " (CA public certificate - Install on management computers)" -ForegroundColor Gray Write-Host "" Write-Host " 3. $summaryPath" -ForegroundColor White Write-Host " (Detailed information and instructions)" -ForegroundColor Gray Write-Host "" Write-Host "CA Thumbprint: $($caCert.Thumbprint)" -ForegroundColor Yellow Write-Host "" Write-Host "Next Steps:" -ForegroundColor Cyan Write-Host " 1. Secure the CA private key (PFX file)" -ForegroundColor White Write-Host " 2. Install CA certificate on management computers" -ForegroundColor White Write-Host " 3. Use Sign-PCCertificate.ps1 to create PC certificates" -ForegroundColor White Write-Host ""