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:
425
winrm-https/TROUBLESHOOTING_CERTIFICATE_GENERATION.md
Normal file
425
winrm-https/TROUBLESHOOTING_CERTIFICATE_GENERATION.md
Normal file
@@ -0,0 +1,425 @@
|
||||
# Troubleshooting Certificate Generation Issues
|
||||
|
||||
## Common Error: "Smart card select a smart card device the security device is read-only"
|
||||
|
||||
This error occurs when using `New-SelfSignedCertificate` on systems with:
|
||||
- Smart card policies enforced by Group Policy
|
||||
- Smart card readers attached
|
||||
- Restricted certificate store permissions
|
||||
- TPM (Trusted Platform Module) restrictions
|
||||
|
||||
### Quick Fixes
|
||||
|
||||
#### Fix 1: Use Alternative Certificate Generation Script
|
||||
|
||||
```powershell
|
||||
# Use the alternative script that bypasses smart card issues
|
||||
.\Generate-WildcardCert-Alternative.ps1
|
||||
```
|
||||
|
||||
This script uses `certreq.exe` instead of `New-SelfSignedCertificate` to avoid smart card device errors.
|
||||
|
||||
---
|
||||
|
||||
#### Fix 2: Temporarily Disable Smart Card Service
|
||||
|
||||
```powershell
|
||||
# Stop smart card service temporarily
|
||||
Stop-Service -Name "SCardSvr" -Force
|
||||
|
||||
# Run certificate generation
|
||||
.\Generate-WildcardCert.ps1
|
||||
|
||||
# Restart service
|
||||
Start-Service -Name "SCardSvr"
|
||||
```
|
||||
|
||||
**Note:** Requires Administrator privileges. May affect other applications using smart cards.
|
||||
|
||||
---
|
||||
|
||||
#### Fix 3: Use Different Crypto Provider
|
||||
|
||||
```powershell
|
||||
# Generate certificate with specific provider
|
||||
$cert = New-SelfSignedCertificate `
|
||||
-DnsName "*.logon.ds.ge.com", "logon.ds.ge.com" `
|
||||
-CertStoreLocation "Cert:\LocalMachine\My" `
|
||||
-Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" `
|
||||
-KeyExportPolicy Exportable `
|
||||
-KeySpec KeyExchange `
|
||||
-NotAfter (Get-Date).AddYears(2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Fix 4: Generate Certificate via CertReq
|
||||
|
||||
**Step 1: Create request file**
|
||||
|
||||
Create `cert-request.inf`:
|
||||
```ini
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
|
||||
[NewRequest]
|
||||
Subject="CN=*.logon.ds.ge.com"
|
||||
KeyLength=2048
|
||||
KeyAlgorithm=RSA
|
||||
HashAlgorithm=SHA256
|
||||
MachineKeySet=TRUE
|
||||
Exportable=TRUE
|
||||
RequestType=Cert
|
||||
KeyUsage=0xA0
|
||||
KeyUsageProperty=0x02
|
||||
|
||||
[Extensions]
|
||||
2.5.29.17 = "{text}"
|
||||
_continue_ = "dns=*.logon.ds.ge.com&"
|
||||
_continue_ = "dns=logon.ds.ge.com&"
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
**Step 2: Generate certificate**
|
||||
|
||||
```powershell
|
||||
# Create certificate using certreq
|
||||
certreq.exe -new -f cert-request.inf wildcard.cer
|
||||
|
||||
# Find the certificate
|
||||
$cert = Get-ChildItem Cert:\LocalMachine\My |
|
||||
Where-Object { $_.Subject -like "*logon.ds.ge.com*" } |
|
||||
Sort-Object NotBefore -Descending |
|
||||
Select-Object -First 1
|
||||
|
||||
# Export to PFX
|
||||
$password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force
|
||||
Export-PfxCertificate -Cert $cert `
|
||||
-FilePath "wildcard-logon-ds-ge-com.pfx" `
|
||||
-Password $password
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Fix 5: Generate on Different Computer
|
||||
|
||||
If the above methods don't work, generate the certificate on a computer without smart card restrictions:
|
||||
|
||||
1. **Generate on unrestricted computer:**
|
||||
```powershell
|
||||
.\Generate-WildcardCert.ps1
|
||||
```
|
||||
|
||||
2. **Copy PFX file to restricted computer:**
|
||||
```powershell
|
||||
Copy-Item "wildcard-*.pfx" -Destination "\\RestrictedComputer\C$\Temp\"
|
||||
```
|
||||
|
||||
3. **Use on restricted computer:**
|
||||
```powershell
|
||||
.\Setup-WinRM-HTTPS.ps1 -CertificatePath "C:\Temp\wildcard-*.pfx" `
|
||||
-Domain "logon.ds.ge.com"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Other Common Certificate Errors
|
||||
|
||||
### Error: "Access Denied" When Creating Certificate
|
||||
|
||||
**Cause:** Insufficient permissions on certificate store
|
||||
|
||||
**Solution:**
|
||||
```powershell
|
||||
# Run PowerShell as Administrator
|
||||
# Right-click PowerShell → Run as Administrator
|
||||
|
||||
# Verify admin rights
|
||||
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
if (-not $isAdmin) {
|
||||
Write-Error "This script requires Administrator privileges"
|
||||
exit 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "The parameter is incorrect" When Exporting
|
||||
|
||||
**Cause:** Password not in correct format
|
||||
|
||||
**Solution:**
|
||||
```powershell
|
||||
# Ensure password is SecureString
|
||||
$password = Read-Host "Enter password" -AsSecureString
|
||||
|
||||
# NOT this (unless using -AsPlainText -Force)
|
||||
# $password = "MyPassword" # Wrong type
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Error: "Cannot export non-exportable private key"
|
||||
|
||||
**Cause:** Certificate created without exportable flag
|
||||
|
||||
**Solution:**
|
||||
```powershell
|
||||
# When creating, ensure KeyExportPolicy is Exportable
|
||||
$cert = New-SelfSignedCertificate `
|
||||
-DnsName "*.logon.ds.ge.com" `
|
||||
-KeyExportPolicy Exportable ` # Important!
|
||||
-CertStoreLocation "Cert:\LocalMachine\My"
|
||||
```
|
||||
|
||||
If already created, you must recreate the certificate.
|
||||
|
||||
---
|
||||
|
||||
### Error: "The trust chain could not be established"
|
||||
|
||||
**Cause:** Self-signed certificate not in Trusted Root store
|
||||
|
||||
**Solution:**
|
||||
```powershell
|
||||
# Import to Trusted Root
|
||||
$cert = Get-ChildItem Cert:\LocalMachine\My |
|
||||
Where-Object { $_.Subject -like "*logon.ds.ge.com*" }
|
||||
|
||||
$rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store(
|
||||
"Root", "LocalMachine"
|
||||
)
|
||||
$rootStore.Open("ReadWrite")
|
||||
$rootStore.Add($cert)
|
||||
$rootStore.Close()
|
||||
|
||||
Write-Host "Certificate added to Trusted Root"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Group Policy Restrictions
|
||||
|
||||
### Check if Group Policy Restricts Certificates
|
||||
|
||||
```powershell
|
||||
# Check certificate template policies
|
||||
gpresult /H gpreport.html
|
||||
# Open gpreport.html and search for "Certificate"
|
||||
|
||||
# Check smart card policies
|
||||
Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\SmartCardCredentialProvider"
|
||||
```
|
||||
|
||||
### Workarounds for Group Policy
|
||||
|
||||
1. **Request exception from IT security team**
|
||||
- Explain need for WinRM HTTPS testing
|
||||
- Request temporary policy exemption
|
||||
|
||||
2. **Use test environment without policies**
|
||||
- VM or workstation not in domain
|
||||
- Generate certificates there
|
||||
|
||||
3. **Get certificate from Certificate Authority**
|
||||
- Request wildcard cert from internal CA
|
||||
- Avoids self-signed certificate issues
|
||||
|
||||
---
|
||||
|
||||
## Alternative: Use Existing Certificate
|
||||
|
||||
If you cannot generate certificates, use an existing one:
|
||||
|
||||
### Option 1: Use Existing Machine Certificate
|
||||
|
||||
```powershell
|
||||
# Find existing exportable certificates
|
||||
Get-ChildItem Cert:\LocalMachine\My |
|
||||
Where-Object {
|
||||
$_.HasPrivateKey -and
|
||||
$_.Extensions | Where-Object { $_.Oid.FriendlyName -eq "Key Usage" }
|
||||
} |
|
||||
Select-Object Subject, Thumbprint, NotAfter
|
||||
|
||||
# Use existing certificate by thumbprint
|
||||
.\Setup-WinRM-HTTPS.ps1 -CertificateThumbprint "ABC123..." `
|
||||
-Domain "logon.ds.ge.com"
|
||||
```
|
||||
|
||||
### Option 2: Import Existing PFX
|
||||
|
||||
```powershell
|
||||
# If you have a PFX file from elsewhere
|
||||
$password = Read-Host "Enter PFX password" -AsSecureString
|
||||
Import-PfxCertificate -FilePath "existing-cert.pfx" `
|
||||
-CertStoreLocation "Cert:\LocalMachine\My" `
|
||||
-Password $password `
|
||||
-Exportable
|
||||
|
||||
# Use it
|
||||
$cert = Get-ChildItem Cert:\LocalMachine\My |
|
||||
Where-Object { $_.Subject -like "*your-domain*" }
|
||||
|
||||
.\Setup-WinRM-HTTPS.ps1 -CertificateThumbprint $cert.Thumbprint `
|
||||
-Domain "logon.ds.ge.com"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Using OpenSSL (Advanced)
|
||||
|
||||
If PowerShell methods fail completely, use OpenSSL:
|
||||
|
||||
### Install OpenSSL
|
||||
|
||||
```powershell
|
||||
# Install via Chocolatey
|
||||
choco install openssl -y
|
||||
|
||||
# Or download from: https://slproweb.com/products/Win32OpenSSL.html
|
||||
```
|
||||
|
||||
### Generate Certificate with OpenSSL
|
||||
|
||||
```bash
|
||||
# Generate private key
|
||||
openssl genrsa -out wildcard.key 2048
|
||||
|
||||
# Generate certificate signing request
|
||||
openssl req -new -key wildcard.key -out wildcard.csr -subj "/CN=*.logon.ds.ge.com"
|
||||
|
||||
# Create config file for SAN
|
||||
cat > openssl.cnf << EOF
|
||||
[req]
|
||||
distinguished_name = req_distinguished_name
|
||||
req_extensions = v3_req
|
||||
|
||||
[req_distinguished_name]
|
||||
|
||||
[v3_req]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[alt_names]
|
||||
DNS.1 = *.logon.ds.ge.com
|
||||
DNS.2 = logon.ds.ge.com
|
||||
EOF
|
||||
|
||||
# Generate self-signed certificate
|
||||
openssl x509 -req -days 730 -in wildcard.csr -signkey wildcard.key \
|
||||
-out wildcard.crt -extensions v3_req -extfile openssl.cnf
|
||||
|
||||
# Create PFX
|
||||
openssl pkcs12 -export -out wildcard.pfx \
|
||||
-inkey wildcard.key -in wildcard.crt \
|
||||
-passout pass:YourPassword
|
||||
```
|
||||
|
||||
### Import OpenSSL Certificate
|
||||
|
||||
```powershell
|
||||
# Import the PFX created by OpenSSL
|
||||
$password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force
|
||||
Import-PfxCertificate -FilePath "wildcard.pfx" `
|
||||
-CertStoreLocation "Cert:\LocalMachine\My" `
|
||||
-Password $password `
|
||||
-Exportable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification Steps
|
||||
|
||||
After generating certificate by any method:
|
||||
|
||||
```powershell
|
||||
# 1. Verify certificate exists
|
||||
$cert = Get-ChildItem Cert:\LocalMachine\My |
|
||||
Where-Object { $_.Subject -like "*logon.ds.ge.com*" }
|
||||
|
||||
if ($cert) {
|
||||
Write-Host "Certificate found!" -ForegroundColor Green
|
||||
Write-Host "Subject: $($cert.Subject)"
|
||||
Write-Host "Thumbprint: $($cert.Thumbprint)"
|
||||
Write-Host "Has Private Key: $($cert.HasPrivateKey)"
|
||||
Write-Host "Expires: $($cert.NotAfter)"
|
||||
} else {
|
||||
Write-Host "Certificate not found!" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# 2. Verify exportable
|
||||
if ($cert.PrivateKey.CspKeyContainerInfo.Exportable) {
|
||||
Write-Host "Private key is exportable" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Private key is NOT exportable" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# 3. Test export
|
||||
try {
|
||||
$testPassword = ConvertTo-SecureString "test" -AsPlainText -Force
|
||||
$testPath = "$env:TEMP\test-export.pfx"
|
||||
Export-PfxCertificate -Cert $cert -FilePath $testPath -Password $testPassword
|
||||
Remove-Item $testPath -Force
|
||||
Write-Host "Export test successful" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host "Export test failed: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
If none of these solutions work:
|
||||
|
||||
1. **Check Event Viewer:**
|
||||
```powershell
|
||||
# View certificate-related errors
|
||||
Get-EventLog -LogName Application -Source "Microsoft-Windows-CertificateServicesClient-CertEnroll" -Newest 10
|
||||
```
|
||||
|
||||
2. **Enable certificate logging:**
|
||||
```powershell
|
||||
# Enable detailed certificate logging
|
||||
wevtutil sl Microsoft-Windows-CertificateServicesClient-Lifecycle-System /e:true
|
||||
wevtutil sl Microsoft-Windows-CertificateServicesClient-Lifecycle-User /e:true
|
||||
```
|
||||
|
||||
3. **Check Group Policy settings:**
|
||||
```powershell
|
||||
gpresult /H C:\Temp\gpreport.html
|
||||
# Open and search for certificate or smart card policies
|
||||
```
|
||||
|
||||
4. **Test with makecert (legacy):**
|
||||
```powershell
|
||||
# If available (older Windows SDK)
|
||||
makecert -r -pe -n "CN=*.logon.ds.ge.com" -sky exchange -ss my
|
||||
```
|
||||
|
||||
5. **Contact IT/Security team:**
|
||||
- Request certificate from internal CA
|
||||
- Request policy exemption
|
||||
- Request assistance with certificate generation
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Recommended approach when you see smart card error:**
|
||||
|
||||
1. ✅ Try `Generate-WildcardCert-Alternative.ps1` (uses certreq)
|
||||
2. ✅ Try disabling smart card service temporarily
|
||||
3. ✅ Try different crypto provider
|
||||
4. ✅ Generate on different computer without restrictions
|
||||
5. ✅ Request certificate from your organization's CA
|
||||
|
||||
**For production deployment:**
|
||||
- Always get certificates from trusted Certificate Authority
|
||||
- Self-signed certificates are for testing only
|
||||
- Document any workarounds used
|
||||
Reference in New Issue
Block a user