Files
powershell-scripts/winrm-https/Create-CertificateAuthority.ps1
cproudlock 62c0c7bb06 Initial commit: Organized PowerShell scripts for ShopDB asset collection
Structure:
- asset-collection/: Local PC data collection scripts
- remote-execution/: WinRM remote execution scripts
- setup-utilities/: Configuration and testing utilities
- registry-backup/: GE registry backup scripts
- winrm-https/: WinRM HTTPS certificate setup
- docs/: Complete documentation

Each folder includes a README with detailed documentation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 10:57:54 -05:00

315 lines
12 KiB
PowerShell

#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 ""