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>
315 lines
12 KiB
PowerShell
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 ""
|