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:
372
winrm-https/Generate-WildcardCert-Alternative.ps1
Normal file
372
winrm-https/Generate-WildcardCert-Alternative.ps1
Normal file
@@ -0,0 +1,372 @@
|
||||
#Requires -RunAsAdministrator
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Alternative wildcard certificate generator that bypasses smart card issues.
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a self-signed wildcard certificate for *.logon.ds.ge.com using
|
||||
alternative methods that work around smart card reader or read-only device errors.
|
||||
|
||||
This script uses certreq.exe and OpenSSL-style certificate creation to avoid
|
||||
the smart card device error that can occur with New-SelfSignedCertificate.
|
||||
|
||||
.PARAMETER Domain
|
||||
The domain for the wildcard certificate (default: logon.ds.ge.com).
|
||||
|
||||
.PARAMETER ExportPath
|
||||
Path where the PFX file will be exported (default: current directory).
|
||||
|
||||
.PARAMETER Password
|
||||
Password for the PFX file. If not provided, will prompt securely.
|
||||
|
||||
.PARAMETER ValidityYears
|
||||
Certificate validity in years (default: 2).
|
||||
|
||||
.PARAMETER Method
|
||||
Certificate generation method: 'CertReq' or 'Fallback' (default: CertReq).
|
||||
|
||||
.EXAMPLE
|
||||
.\Generate-WildcardCert-Alternative.ps1
|
||||
|
||||
.EXAMPLE
|
||||
$pass = ConvertTo-SecureString "MyPassword123!" -AsPlainText -Force
|
||||
.\Generate-WildcardCert-Alternative.ps1 -Password $pass -Method CertReq
|
||||
|
||||
.NOTES
|
||||
Author: System Administrator
|
||||
Date: 2025-10-17
|
||||
Version: 1.0
|
||||
|
||||
This script uses certreq.exe which bypasses smart card device issues.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$Domain = "logon.ds.ge.com",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$ExportPath = ".",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[SecureString]$Password,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[int]$ValidityYears = 2,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet('CertReq', 'Fallback')]
|
||||
[string]$Method = 'CertReq'
|
||||
)
|
||||
|
||||
function Write-ColorOutput {
|
||||
param([string]$Message, [string]$Color = "White")
|
||||
Write-Host $Message -ForegroundColor $Color
|
||||
}
|
||||
|
||||
function New-CertificateWithCertReq {
|
||||
param(
|
||||
[string]$Domain,
|
||||
[int]$ValidityYears,
|
||||
[SecureString]$Password
|
||||
)
|
||||
|
||||
Write-ColorOutput "`n=== Generating Certificate Using CertReq ===" "Cyan"
|
||||
Write-ColorOutput "This method bypasses smart card device errors" "Gray"
|
||||
|
||||
try {
|
||||
# Create temp directory for certificate files
|
||||
$tempPath = Join-Path $env:TEMP "WinRM-Cert-$(Get-Date -Format 'yyyyMMddHHmmss')"
|
||||
New-Item -ItemType Directory -Path $tempPath -Force | Out-Null
|
||||
Write-ColorOutput "Temp directory: $tempPath" "Gray"
|
||||
|
||||
# Create certificate request configuration file
|
||||
$infFile = Join-Path $tempPath "cert-request.inf"
|
||||
|
||||
$infContent = @"
|
||||
[Version]
|
||||
Signature="`$Windows NT`$"
|
||||
|
||||
[NewRequest]
|
||||
Subject="CN=*.$Domain"
|
||||
KeyLength=2048
|
||||
KeyAlgorithm=RSA
|
||||
HashAlgorithm=SHA256
|
||||
MachineKeySet=TRUE
|
||||
Exportable=TRUE
|
||||
RequestType=Cert
|
||||
KeyUsage=0xA0
|
||||
KeyUsageProperty=0x02
|
||||
|
||||
[Extensions]
|
||||
2.5.29.17 = "{text}"
|
||||
_continue_ = "dns=*.$Domain&"
|
||||
_continue_ = "dns=$Domain&"
|
||||
|
||||
2.5.29.37 = "{text}"
|
||||
_continue_ = "1.3.6.1.5.5.7.3.1,"
|
||||
|
||||
[EnhancedKeyUsageExtension]
|
||||
OID=1.3.6.1.5.5.7.3.1
|
||||
"@
|
||||
|
||||
Write-ColorOutput "`nCreating certificate request file..." "Yellow"
|
||||
$infContent | Out-File -FilePath $infFile -Encoding ASCII -Force
|
||||
|
||||
# Certificate output files
|
||||
$cerFile = Join-Path $tempPath "wildcard.cer"
|
||||
|
||||
# Create the certificate using certreq
|
||||
Write-ColorOutput "Generating self-signed certificate..." "Yellow"
|
||||
$certReqResult = certreq.exe -new -f $infFile $cerFile 2>&1
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "certreq.exe failed: $certReqResult"
|
||||
}
|
||||
|
||||
Write-ColorOutput "[OK] Certificate created successfully" "Green"
|
||||
|
||||
# Import the certificate to get the certificate object
|
||||
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($cerFile)
|
||||
|
||||
# Find the certificate in the store by thumbprint
|
||||
$installedCert = Get-ChildItem Cert:\LocalMachine\My |
|
||||
Where-Object { $_.Thumbprint -eq $cert.Thumbprint }
|
||||
|
||||
if (-not $installedCert) {
|
||||
throw "Certificate was not installed to the certificate store"
|
||||
}
|
||||
|
||||
Write-ColorOutput "`nCertificate Details:" "Cyan"
|
||||
Write-ColorOutput " Subject: $($installedCert.Subject)" "White"
|
||||
Write-ColorOutput " Thumbprint: $($installedCert.Thumbprint)" "White"
|
||||
Write-ColorOutput " Valid From: $($installedCert.NotBefore)" "White"
|
||||
Write-ColorOutput " Valid To: $($installedCert.NotAfter)" "White"
|
||||
Write-ColorOutput " Has Private Key: $($installedCert.HasPrivateKey)" "White"
|
||||
|
||||
# Clean up temp files but keep the certificate
|
||||
Remove-Item -Path $tempPath -Recurse -Force -ErrorAction SilentlyContinue
|
||||
|
||||
return $installedCert
|
||||
}
|
||||
catch {
|
||||
# Clean up on error
|
||||
if (Test-Path $tempPath) {
|
||||
Remove-Item -Path $tempPath -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
throw "Failed to create certificate with CertReq: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function New-CertificateWithFallback {
|
||||
param(
|
||||
[string]$Domain,
|
||||
[int]$ValidityYears
|
||||
)
|
||||
|
||||
Write-ColorOutput "`n=== Using Fallback Method ===" "Cyan"
|
||||
Write-ColorOutput "Attempting to create certificate with minimal settings..." "Gray"
|
||||
|
||||
try {
|
||||
$notAfter = (Get-Date).AddYears($ValidityYears)
|
||||
|
||||
# Try with minimal parameters and explicitly set KeyProtection to None
|
||||
$certParams = @{
|
||||
DnsName = @("*.$Domain", $Domain)
|
||||
CertStoreLocation = "Cert:\LocalMachine\My"
|
||||
NotAfter = $notAfter
|
||||
Subject = "CN=*.$Domain"
|
||||
FriendlyName = "Wildcard Certificate for *.$Domain (Self-Signed)"
|
||||
KeyUsage = "DigitalSignature", "KeyEncipherment"
|
||||
TextExtension = @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")
|
||||
Type = "Custom"
|
||||
KeyExportPolicy = "Exportable"
|
||||
KeySpec = "KeyExchange"
|
||||
Provider = "Microsoft Enhanced RSA and AES Cryptographic Provider"
|
||||
}
|
||||
|
||||
Write-ColorOutput "Creating certificate with fallback method..." "Yellow"
|
||||
$cert = New-SelfSignedCertificate @certParams
|
||||
|
||||
Write-ColorOutput "[OK] Certificate created successfully" "Green"
|
||||
Write-ColorOutput "`nCertificate Details:" "Cyan"
|
||||
Write-ColorOutput " Subject: $($cert.Subject)" "White"
|
||||
Write-ColorOutput " Thumbprint: $($cert.Thumbprint)" "White"
|
||||
Write-ColorOutput " Valid From: $($cert.NotBefore)" "White"
|
||||
Write-ColorOutput " Valid To: $($cert.NotAfter)" "White"
|
||||
Write-ColorOutput " Has Private Key: $($cert.HasPrivateKey)" "White"
|
||||
|
||||
return $cert
|
||||
}
|
||||
catch {
|
||||
throw "Failed to create certificate with fallback method: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Export-CertificateToPFX {
|
||||
param(
|
||||
[System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate,
|
||||
[string]$ExportPath,
|
||||
[string]$Domain,
|
||||
[SecureString]$Password
|
||||
)
|
||||
|
||||
Write-ColorOutput "`n=== Exporting Certificate to PFX ===" "Cyan"
|
||||
|
||||
try {
|
||||
# Ensure export directory exists
|
||||
if (-not (Test-Path $ExportPath)) {
|
||||
New-Item -ItemType Directory -Path $ExportPath -Force | Out-Null
|
||||
}
|
||||
|
||||
# Construct filename
|
||||
$filename = "wildcard-$($Domain.Replace('.', '-'))-$(Get-Date -Format 'yyyyMMdd').pfx"
|
||||
$fullPath = Join-Path $ExportPath $filename
|
||||
|
||||
Write-ColorOutput "Export path: $fullPath" "Gray"
|
||||
|
||||
# Export certificate with private key
|
||||
Export-PfxCertificate -Cert $Certificate -FilePath $fullPath -Password $Password | Out-Null
|
||||
|
||||
Write-ColorOutput "[OK] Certificate exported successfully" "Green"
|
||||
|
||||
# Get file size
|
||||
$fileSize = (Get-Item $fullPath).Length
|
||||
Write-ColorOutput " File size: $([math]::Round($fileSize / 1KB, 2)) KB" "White"
|
||||
|
||||
return $fullPath
|
||||
}
|
||||
catch {
|
||||
throw "Failed to export certificate: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-CertificateToTrustedRoot {
|
||||
param(
|
||||
[System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate
|
||||
)
|
||||
|
||||
Write-ColorOutput "`n=== Installing to Trusted Root ===" "Cyan"
|
||||
Write-ColorOutput "This allows the self-signed cert to be trusted on this machine" "Gray"
|
||||
|
||||
try {
|
||||
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
|
||||
"Root", "LocalMachine"
|
||||
)
|
||||
$rootStore.Open("ReadWrite")
|
||||
|
||||
# Check if already exists
|
||||
$existing = $rootStore.Certificates | Where-Object { $_.Thumbprint -eq $Certificate.Thumbprint }
|
||||
|
||||
if ($existing) {
|
||||
Write-ColorOutput "[OK] Certificate already in Trusted Root" "Yellow"
|
||||
}
|
||||
else {
|
||||
$rootStore.Add($Certificate)
|
||||
Write-ColorOutput "[OK] Certificate added to Trusted Root Certification Authorities" "Green"
|
||||
}
|
||||
|
||||
$rootStore.Close()
|
||||
}
|
||||
catch {
|
||||
Write-ColorOutput "[WARN] Could not add to Trusted Root: $($_.Exception.Message)" "Yellow"
|
||||
Write-ColorOutput "You may need to manually trust this certificate on client machines" "Yellow"
|
||||
}
|
||||
}
|
||||
|
||||
function Show-NextSteps {
|
||||
param([string]$PfxPath, [string]$Domain)
|
||||
|
||||
Write-ColorOutput "`n=== Next Steps ===" "Cyan"
|
||||
Write-ColorOutput ""
|
||||
Write-ColorOutput "1. The wildcard certificate has been generated and exported to:" "Yellow"
|
||||
Write-ColorOutput " $PfxPath" "White"
|
||||
Write-ColorOutput ""
|
||||
Write-ColorOutput "2. To set up WinRM HTTPS on a computer, copy the PFX file and run:" "Yellow"
|
||||
Write-ColorOutput " .\Setup-WinRM-HTTPS.ps1 -CertificatePath '$PfxPath' -Domain '$Domain'" "White"
|
||||
Write-ColorOutput " (Will prompt for password)" "Gray"
|
||||
Write-ColorOutput ""
|
||||
Write-ColorOutput "3. For client machines to trust this certificate:" "Yellow"
|
||||
Write-ColorOutput " Import to Trusted Root on each client or use -SkipCertificateCheck" "White"
|
||||
Write-ColorOutput ""
|
||||
Write-ColorOutput "4. Test the setup:" "Yellow"
|
||||
Write-ColorOutput " .\Invoke-RemoteAssetCollection-HTTPS.ps1 ``" "White"
|
||||
Write-ColorOutput " -HostnameList @('hostname') -Domain '$Domain' -TestConnections" "White"
|
||||
Write-ColorOutput ""
|
||||
Write-ColorOutput "IMPORTANT: This is a SELF-SIGNED certificate for TESTING only!" "Red"
|
||||
Write-ColorOutput "For production, obtain a certificate from a trusted CA." "Red"
|
||||
Write-ColorOutput ""
|
||||
}
|
||||
|
||||
# Main execution
|
||||
try {
|
||||
Write-ColorOutput "=== Alternative Wildcard Certificate Generator ===" "Cyan"
|
||||
Write-ColorOutput "Date: $(Get-Date)" "Gray"
|
||||
Write-ColorOutput "Method: $Method" "Gray"
|
||||
Write-ColorOutput ""
|
||||
|
||||
# Get password if not provided
|
||||
if (-not $Password) {
|
||||
Write-ColorOutput "Enter password for PFX file:" "Yellow"
|
||||
$Password = Read-Host "Password" -AsSecureString
|
||||
$Password2 = Read-Host "Confirm password" -AsSecureString
|
||||
|
||||
# Compare passwords
|
||||
$pwd1 = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
|
||||
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
|
||||
)
|
||||
$pwd2 = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
|
||||
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password2)
|
||||
)
|
||||
|
||||
if ($pwd1 -ne $pwd2) {
|
||||
throw "Passwords do not match"
|
||||
}
|
||||
}
|
||||
|
||||
# Generate certificate using selected method
|
||||
$cert = $null
|
||||
|
||||
if ($Method -eq 'CertReq') {
|
||||
try {
|
||||
$cert = New-CertificateWithCertReq -Domain $Domain -ValidityYears $ValidityYears -Password $Password
|
||||
}
|
||||
catch {
|
||||
Write-ColorOutput "[WARN] CertReq method failed: $($_.Exception.Message)" "Yellow"
|
||||
Write-ColorOutput "Trying fallback method..." "Yellow"
|
||||
$cert = New-CertificateWithFallback -Domain $Domain -ValidityYears $ValidityYears
|
||||
}
|
||||
}
|
||||
else {
|
||||
$cert = New-CertificateWithFallback -Domain $Domain -ValidityYears $ValidityYears
|
||||
}
|
||||
|
||||
if (-not $cert) {
|
||||
throw "Failed to create certificate with any method"
|
||||
}
|
||||
|
||||
# Export to PFX
|
||||
$pfxPath = Export-CertificateToPFX -Certificate $cert -ExportPath $ExportPath -Domain $Domain -Password $Password
|
||||
|
||||
# Install to trusted root (optional)
|
||||
$installToRoot = Read-Host "`nInstall to Trusted Root Certification Authorities on this machine? (Y/N)"
|
||||
if ($installToRoot -eq 'Y' -or $installToRoot -eq 'y') {
|
||||
Install-CertificateToTrustedRoot -Certificate $cert
|
||||
}
|
||||
|
||||
# Show next steps
|
||||
Show-NextSteps -PfxPath $pfxPath -Domain $Domain
|
||||
|
||||
Write-ColorOutput "`n[SUCCESS] Wildcard certificate generation completed!" "Green"
|
||||
Write-ColorOutput "Certificate Thumbprint: $($cert.Thumbprint)" "Cyan"
|
||||
Write-ColorOutput "PFX File: $pfxPath" "Cyan"
|
||||
|
||||
} catch {
|
||||
Write-ColorOutput "`n[ERROR] Certificate generation failed: $($_.Exception.Message)" "Red"
|
||||
Write-ColorOutput "`nTroubleshooting:" "Yellow"
|
||||
Write-ColorOutput "1. Ensure you're running as Administrator" "White"
|
||||
Write-ColorOutput "2. Check if Group Policy restricts certificate creation" "White"
|
||||
Write-ColorOutput "3. Try running: certlm.msc to verify certificate store access" "White"
|
||||
Write-ColorOutput "4. Disable smart card readers temporarily if present" "White"
|
||||
Write-ColorOutput "5. Try the other method: -Method Fallback or -Method CertReq" "White"
|
||||
exit 1
|
||||
}
|
||||
Reference in New Issue
Block a user