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>
This commit is contained in:
323
winrm-https/winrm-ca-scripts/Deploy-PCCertificate.ps1
Normal file
323
winrm-https/winrm-ca-scripts/Deploy-PCCertificate.ps1
Normal file
@@ -0,0 +1,323 @@
|
||||
#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
|
||||
}
|
||||
Reference in New Issue
Block a user