Files
powershell-scripts/winrm-https/winrm-ca-scripts/Deploy-PCCertificate.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

324 lines
10 KiB
PowerShell

#Requires -RunAsAdministrator
<#
.SYNOPSIS
Deploys PC-specific certificate from network share and configures WinRM HTTPS
.DESCRIPTION
This script:
1. Finds the certificate for this PC on the network share
2. Imports it to the local certificate store
3. Configures WinRM HTTPS listener with the certificate
4. Creates firewall rule
5. Logs everything
.PARAMETER NetworkSharePath
Path to network share containing PC certificates
Default: S:\dt\adata\script\deploy\pc-certificates
.PARAMETER CertificatePassword
Password for the certificate (if not provided, will prompt)
.PARAMETER Domain
Domain suffix for FQDN (default: logon.ds.ge.com)
.PARAMETER LogFile
Path to log file (optional)
.PARAMETER AllowedSubnets
Comma-separated list of allowed remote subnets in CIDR notation
Default: "10.48.130.0/23" (management subnet)
Use "Any" to allow all subnets
.EXAMPLE
.\Deploy-PCCertificate.ps1
.EXAMPLE
$certPass = ConvertTo-SecureString "PCCert2025!" -AsPlainText -Force
.\Deploy-PCCertificate.ps1 -CertificatePassword $certPass
.EXAMPLE
.\Deploy-PCCertificate.ps1 -AllowedSubnets "10.48.130.0/23,10.134.48.0/24"
.NOTES
Author: System Administrator
Date: 2025-10-17
Run this script ON THE TARGET PC as Administrator
#>
param(
[string]$NetworkSharePath = "S:\dt\adata\script\deploy\pc-certificates",
[SecureString]$CertificatePassword,
[string]$Domain = "logon.ds.ge.com",
[string]$LogFile,
[string]$AllowedSubnets = "10.48.130.0/23"
)
function Write-Log {
param([string]$Message, [string]$Color = "White")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] $Message"
Write-Host $Message -ForegroundColor $Color
if ($LogFile) {
Add-Content -Path $LogFile -Value $logMessage -ErrorAction SilentlyContinue
}
}
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " PC Certificate Deployment" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
# Get hostname
$hostname = $env:COMPUTERNAME
$fqdn = "$hostname.$Domain".ToLower()
Write-Log "Computer: $hostname"
Write-Log "FQDN: $fqdn"
Write-Log ""
# Check network share access
Write-Log "Checking network share access..." -Color Yellow
if (-not (Test-Path $NetworkSharePath)) {
Write-Log "[ERROR] Cannot access network share: $NetworkSharePath" -Color Red
Write-Log "Make sure the network share is accessible" -Color Yellow
exit 1
}
Write-Log "[OK] Network share accessible" -Color Green
Write-Log ""
# Find certificate for this PC
Write-Log "Looking for certificate for $hostname..." -Color Yellow
$certFiles = Get-ChildItem -Path "$NetworkSharePath\batch-*\$hostname-*.pfx" -ErrorAction SilentlyContinue
if (-not $certFiles) {
# Try alternative search
$certFiles = Get-ChildItem -Path $NetworkSharePath -Recurse -Filter "$hostname-*.pfx" -ErrorAction SilentlyContinue
}
if (-not $certFiles -or $certFiles.Count -eq 0) {
Write-Log "[ERROR] Certificate not found for $hostname" -Color Red
Write-Log "Searched in: $NetworkSharePath" -Color Yellow
Write-Log "Expected filename pattern: $hostname-*.pfx" -Color Yellow
exit 1
}
if ($certFiles.Count -gt 1) {
Write-Log "Multiple certificates found:" -Color Yellow
$certFiles | ForEach-Object { Write-Log " - $($_.FullName)" }
Write-Log "Using newest: $($certFiles[0].Name)" -Color Yellow
$certFile = $certFiles | Sort-Object LastWriteTime -Descending | Select-Object -First 1
} else {
$certFile = $certFiles[0]
}
Write-Log "[OK] Found certificate: $($certFile.Name)" -Color Green
Write-Log " Path: $($certFile.FullName)" -Color Gray
Write-Log ""
# Get password if not provided
if (-not $CertificatePassword) {
Write-Log "Enter certificate password:" -Color Yellow
$CertificatePassword = Read-Host "Password" -AsSecureString
Write-Log ""
}
# Import certificate
Write-Log "Importing certificate to Local Machine store..." -Color Yellow
try {
$cert = Import-PfxCertificate `
-FilePath $certFile.FullName `
-CertStoreLocation Cert:\LocalMachine\My `
-Password $CertificatePassword `
-Exportable
Write-Log "[OK] Certificate imported successfully" -Color Green
Write-Log " Subject: $($cert.Subject)" -Color Gray
Write-Log " Thumbprint: $($cert.Thumbprint)" -Color Gray
Write-Log " Issuer: $($cert.Issuer)" -Color Gray
Write-Log " Valid Until: $($cert.NotAfter)" -Color Gray
Write-Log ""
} catch {
Write-Log "[ERROR] Failed to import certificate: $($_.Exception.Message)" -Color Red
exit 1
}
# Set Network Profile to Private
Write-Log "Checking network profile..." -Color Yellow
try {
$profiles = Get-NetConnectionProfile
$publicProfiles = $profiles | Where-Object { $_.NetworkCategory -eq 'Public' }
if ($publicProfiles) {
Write-Log " Found Public network profile(s), changing to Private..." -Color Gray
foreach ($profile in $publicProfiles) {
Set-NetConnectionProfile -InterfaceIndex $profile.InterfaceIndex -NetworkCategory Private -ErrorAction SilentlyContinue
}
Write-Log "[OK] Network profile set to Private" -Color Green
} else {
Write-Log "[OK] Network profile is already Private/Domain" -Color Green
}
Write-Log ""
} catch {
Write-Log "[WARN] Could not change network profile: $($_.Exception.Message)" -Color Yellow
Write-Log ""
}
# Configure WinRM Service
Write-Log "Configuring WinRM service..." -Color Yellow
try {
# Enable PowerShell Remoting
Enable-PSRemoting -Force -SkipNetworkProfileCheck | Out-Null
# Start WinRM service
Start-Service WinRM -ErrorAction SilentlyContinue
Set-Service WinRM -StartupType Automatic
# Enable certificate authentication
Set-Item WSMan:\localhost\Service\Auth\Certificate -Value $true
Write-Log "[OK] WinRM service configured" -Color Green
Write-Log ""
} catch {
Write-Log "[ERROR] Failed to configure WinRM: $($_.Exception.Message)" -Color Red
}
# Remove existing HTTPS listeners
Write-Log "Checking for existing HTTPS listeners..." -Color Yellow
try {
$existingListeners = winrm enumerate winrm/config/listener | Select-String "Transport = HTTPS"
if ($existingListeners) {
Write-Log "Removing existing HTTPS listener..." -Color Yellow
winrm delete winrm/config/Listener?Address=*+Transport=HTTPS 2>&1 | Out-Null
Write-Log "[OK] Existing HTTPS listener removed" -Color Green
} else {
Write-Log "[OK] No existing HTTPS listener found" -Color Green
}
Write-Log ""
} catch {
Write-Log "[WARN] Could not check/remove existing listeners" -Color Yellow
}
# Create HTTPS listener
Write-Log "Creating WinRM HTTPS listener..." -Color Yellow
Write-Log " Hostname: $fqdn" -Color Gray
Write-Log " Port: 5986" -Color Gray
Write-Log " Certificate: $($cert.Thumbprint)" -Color Gray
try {
$winrmArgs = "create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname=`"$fqdn`";CertificateThumbprint=`"$($cert.Thumbprint)`";Port=`"5986`"}"
$result = cmd.exe /c "winrm $winrmArgs" 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Log "[ERROR] Failed to create HTTPS listener" -Color Red
Write-Log "Error: $result" -Color Red
exit 1
}
Write-Log "[OK] HTTPS listener created successfully" -Color Green
Write-Log ""
} catch {
Write-Log "[ERROR] Failed to create HTTPS listener: $($_.Exception.Message)" -Color Red
exit 1
}
# Configure firewall
Write-Log "Configuring Windows Firewall..." -Color Yellow
try {
$ruleName = "WinRM HTTPS-In"
# Remove existing rule if present
$existingRule = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
if ($existingRule) {
Remove-NetFirewallRule -DisplayName $ruleName
}
# Determine remote address
if ($AllowedSubnets -eq "Any") {
$remoteAddr = "Any"
Write-Log " Remote Access: Any (all subnets)" -Color Gray
} else {
# Split comma-separated subnets
$remoteAddr = $AllowedSubnets -split "," | ForEach-Object { $_.Trim() }
Write-Log " Remote Access: $AllowedSubnets" -Color Gray
}
# Create new rule
New-NetFirewallRule -DisplayName $ruleName `
-Name $ruleName `
-Profile Any `
-LocalPort 5986 `
-Protocol TCP `
-Direction Inbound `
-Action Allow `
-RemoteAddress $remoteAddr `
-Enabled True | Out-Null
Write-Log "[OK] Firewall rule created" -Color Green
Write-Log ""
} catch {
Write-Log "[WARN] Could not configure firewall: $($_.Exception.Message)" -Color Yellow
}
# Verify configuration
Write-Log "Verifying configuration..." -Color Yellow
Write-Log ""
# Check service
$winrmService = Get-Service WinRM
Write-Log "WinRM Service: $($winrmService.Status) [$($winrmService.StartType)]" -Color $(if($winrmService.Status -eq 'Running'){'Green'}else{'Red'})
# Check listener
Write-Log ""
Write-Log "WinRM Listeners:" -Color Cyan
winrm enumerate winrm/config/listener | Out-String | ForEach-Object { Write-Log $_ -Color Gray }
# Check port
Write-Log ""
Write-Log "Port 5986 Status:" -Color Cyan
$portCheck = netstat -an | Select-String ":5986"
if ($portCheck) {
Write-Log "[OK] Port 5986 is listening" -Color Green
$portCheck | ForEach-Object { Write-Log " $_" -Color Gray }
} else {
Write-Log "[WARNING] Port 5986 is not listening" -Color Yellow
}
# Summary
Write-Log ""
Write-Log "========================================" -ForegroundColor Green
Write-Log " DEPLOYMENT COMPLETE" -ForegroundColor Green
Write-Log "========================================" -ForegroundColor Green
Write-Log ""
Write-Log "Certificate: $($cert.Subject)" -Color White
Write-Log "Thumbprint: $($cert.Thumbprint)" -Color White
Write-Log "Hostname: $fqdn" -Color White
Write-Log ""
Write-Log "Test connection from management computer:" -Color Yellow
Write-Log " Test-WSMan -ComputerName $fqdn -UseSSL -Port 5986" -Color White
Write-Log ""
Write-Log " `$cred = Get-Credential" -Color White
Write-Log " Enter-PSSession -ComputerName $fqdn -Credential `$cred -UseSSL -Port 5986" -Color White
Write-Log ""
if ($LogFile) {
Write-Log "Log saved to: $LogFile" -Color Cyan
}