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>
469 lines
16 KiB
PowerShell
469 lines
16 KiB
PowerShell
#Requires -RunAsAdministrator
|
|
|
|
param(
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$ComputerName = $env:COMPUTERNAME,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$LogFile
|
|
)
|
|
|
|
# Setup logging function
|
|
function Write-Log {
|
|
param(
|
|
[string]$Message,
|
|
[string]$Color = "White"
|
|
)
|
|
|
|
# Write to console
|
|
if ($Color -ne "White") {
|
|
Write-Host $Message -ForegroundColor $Color
|
|
} else {
|
|
Write-Host $Message
|
|
}
|
|
|
|
# Write to log file (strip color codes, just text)
|
|
if ($LogFile) {
|
|
Add-Content -Path $LogFile -Value $Message -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
|
|
# Create log file if not specified
|
|
if (-not $LogFile) {
|
|
$logDir = "S:\DT\ADATA\SCRIPT\DEPLOY\LOGS"
|
|
if (Test-Path $logDir) {
|
|
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
|
|
$LogFile = "$logDir\$ComputerName-$timestamp-DEBUG.txt"
|
|
}
|
|
}
|
|
|
|
# Create log directory if needed
|
|
if ($LogFile) {
|
|
$logDir = Split-Path $LogFile -Parent
|
|
if (-not (Test-Path $logDir)) {
|
|
New-Item -Path $logDir -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
# Start log file
|
|
"============================================================================" | Out-File $LogFile
|
|
"WinRM HTTPS Debug Test Log" | Out-File $LogFile -Append
|
|
"============================================================================" | Out-File $LogFile -Append
|
|
"Computer: $ComputerName" | Out-File $LogFile -Append
|
|
"Date/Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" | Out-File $LogFile -Append
|
|
"Log File: $LogFile" | Out-File $LogFile -Append
|
|
"============================================================================" | Out-File $LogFile -Append
|
|
"" | Out-File $LogFile -Append
|
|
}
|
|
|
|
Write-Log ""
|
|
Write-Log "======================================" -Color Cyan
|
|
Write-Log " WinRM HTTPS Debug Test" -Color Cyan
|
|
Write-Log "======================================" -Color Cyan
|
|
Write-Log ""
|
|
Write-Log "Computer: $ComputerName"
|
|
Write-Log "Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
|
if ($LogFile) {
|
|
Write-Log "Log File: $LogFile" -Color Cyan
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 1: WinRM Service
|
|
Write-Log "TEST 1: WinRM Service Status" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$winrmService = Get-Service WinRM
|
|
if ($winrmService.Status -eq 'Running') {
|
|
Write-Log "[OK] WinRM service is RUNNING" -Color Green
|
|
} else {
|
|
Write-Log "[ERROR] WinRM service is $($winrmService.Status)" -Color Red
|
|
}
|
|
Write-Log " Status: $($winrmService.Status)"
|
|
Write-Log " StartType: $($winrmService.StartType)"
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot check WinRM service: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 2: WinRM Listeners
|
|
Write-Log "TEST 2: WinRM Listeners" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$listeners = winrm enumerate winrm/config/listener
|
|
if ($listeners) {
|
|
Write-Log $listeners
|
|
|
|
# Check for HTTPS listener
|
|
if ($listeners -match 'Transport = HTTPS') {
|
|
Write-Log "[OK] HTTPS listener found" -Color Green
|
|
} else {
|
|
Write-Log "[WARNING] No HTTPS listener found" -Color Yellow
|
|
}
|
|
} else {
|
|
Write-Log "[WARNING] No listeners configured" -Color Yellow
|
|
}
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot enumerate listeners: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 3: Port Listening
|
|
Write-Log "TEST 3: Port Listening Status" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
$ports = @(5985, 5986)
|
|
foreach ($port in $ports) {
|
|
$listening = netstat -an | Select-String ":$port"
|
|
if ($listening) {
|
|
Write-Log "[OK] Port $port is LISTENING" -Color Green
|
|
$listening | ForEach-Object { Write-Log " $_" -Color Gray }
|
|
} else {
|
|
Write-Log "[WARNING] Port $port is NOT listening" -Color Yellow
|
|
}
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 4: Firewall Rules
|
|
Write-Log "TEST 4: Firewall Rules" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$winrmRules = Get-NetFirewallRule | Where-Object {
|
|
$_.DisplayName -like "*WinRM*"
|
|
}
|
|
|
|
if ($winrmRules) {
|
|
Write-Log "[OK] Found $($winrmRules.Count) WinRM firewall rule(s)" -Color Green
|
|
foreach ($rule in $winrmRules) {
|
|
$portFilter = $rule | Get-NetFirewallPortFilter
|
|
$addressFilter = $rule | Get-NetFirewallAddressFilter
|
|
|
|
$status = if ($rule.Enabled) { "ENABLED" } else { "DISABLED" }
|
|
$statusColor = if ($rule.Enabled) { "Green" } else { "Red" }
|
|
|
|
Write-Log ""
|
|
Write-Log " Rule: $($rule.DisplayName)" -Color White
|
|
Write-Log " Status: $status" -Color $statusColor
|
|
Write-Log " Direction: $($rule.Direction)"
|
|
Write-Log " Action: $($rule.Action)"
|
|
Write-Log " Profile: $($rule.Profile)"
|
|
Write-Log " Local Port: $($portFilter.LocalPort)"
|
|
Write-Log " Protocol: $($portFilter.Protocol)"
|
|
Write-Log " Remote Address: $($addressFilter.RemoteAddress)"
|
|
Write-Log " Local Address: $($addressFilter.LocalAddress)"
|
|
}
|
|
} else {
|
|
Write-Log "[WARNING] No WinRM firewall rules found" -Color Yellow
|
|
}
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot check firewall: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 5: Certificates
|
|
Write-Log "TEST 5: Certificates" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$certs = Get-ChildItem Cert:\LocalMachine\My | Where-Object {
|
|
$_.Subject -like "*$env:COMPUTERNAME*" -or
|
|
$_.Subject -like "*.logon.ds.ge.com*" -or
|
|
$_.DnsNameList -like "*$env:COMPUTERNAME*"
|
|
}
|
|
|
|
if ($certs) {
|
|
Write-Log "[OK] Found $($certs.Count) certificate(s)" -Color Green
|
|
foreach ($cert in $certs) {
|
|
Write-Log ""
|
|
Write-Log " Subject: $($cert.Subject)" -Color White
|
|
Write-Log " Thumbprint: $($cert.Thumbprint)"
|
|
Write-Log " Issuer: $($cert.Issuer)"
|
|
Write-Log " Valid Until: $($cert.NotAfter)"
|
|
Write-Log " Has Private Key: $($cert.HasPrivateKey)"
|
|
if ($cert.DnsNameList) {
|
|
Write-Log " DNS Names: $($cert.DnsNameList.Unicode -join ', ')"
|
|
}
|
|
}
|
|
} else {
|
|
Write-Log "[WARNING] No matching certificates found" -Color Yellow
|
|
}
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot check certificates: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 6: WinRM Configuration
|
|
Write-Log "TEST 6: WinRM Configuration" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$config = winrm get winrm/config
|
|
Write-Log $config
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot get WinRM config: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 7: Network Information
|
|
Write-Log "TEST 7: Network Information" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$hostname = $env:COMPUTERNAME
|
|
$fqdn = [System.Net.Dns]::GetHostByName($hostname).HostName
|
|
$ips = Get-NetIPAddress -AddressFamily IPv4 | Where-Object {
|
|
$_.IPAddress -notlike "127.*" -and $_.IPAddress -notlike "169.254.*"
|
|
}
|
|
|
|
Write-Log " Hostname: $hostname"
|
|
Write-Log " FQDN: $fqdn"
|
|
Write-Log ""
|
|
Write-Log " IP Addresses:"
|
|
foreach ($ip in $ips) {
|
|
Write-Log " - $($ip.IPAddress) [$($ip.InterfaceAlias)]"
|
|
}
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot get network info: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 8: Network Profile
|
|
Write-Log "TEST 8: Network Profile" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$profiles = Get-NetConnectionProfile
|
|
|
|
if ($profiles) {
|
|
foreach ($profile in $profiles) {
|
|
$category = $profile.NetworkCategory
|
|
$categoryColor = switch ($category) {
|
|
'Private' { 'Green' }
|
|
'DomainAuthenticated' { 'Green' }
|
|
'Public' { 'Yellow' }
|
|
default { 'White' }
|
|
}
|
|
|
|
Write-Log ""
|
|
Write-Log " Interface: $($profile.InterfaceAlias)" -Color White
|
|
Write-Log " Name: $($profile.Name)"
|
|
Write-Log " Category: $category" -Color $categoryColor
|
|
Write-Log " IPv4 Connectivity: $($profile.IPv4Connectivity)"
|
|
Write-Log " IPv6 Connectivity: $($profile.IPv6Connectivity)"
|
|
}
|
|
|
|
# Warning for Public profiles
|
|
$publicProfiles = $profiles | Where-Object { $_.NetworkCategory -eq 'Public' }
|
|
if ($publicProfiles) {
|
|
Write-Log ""
|
|
Write-Log " [WARNING] Public network profile detected!" -Color Yellow
|
|
Write-Log " Public profiles may restrict WinRM connectivity" -Color Yellow
|
|
Write-Log " Run Set-NetworkPrivate.bat to change to Private" -Color Yellow
|
|
}
|
|
} else {
|
|
Write-Log "[WARNING] No network profiles found" -Color Yellow
|
|
}
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot get network profile: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 9: Firewall Profile Status
|
|
Write-Log "TEST 9: Firewall Profile Status" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$firewallProfiles = Get-NetFirewallProfile
|
|
|
|
foreach ($fwProfile in $firewallProfiles) {
|
|
$status = if ($fwProfile.Enabled) { "ENABLED" } else { "DISABLED" }
|
|
$statusColor = if ($fwProfile.Enabled) { "Yellow" } else { "Green" }
|
|
|
|
Write-Log ""
|
|
Write-Log " Profile: $($fwProfile.Name)" -Color White
|
|
Write-Log " Firewall: $status" -Color $statusColor
|
|
Write-Log " Default Inbound Action: $($fwProfile.DefaultInboundAction)"
|
|
Write-Log " Default Outbound Action: $($fwProfile.DefaultOutboundAction)"
|
|
}
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot get firewall profiles: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 10: Group Policy Information
|
|
Write-Log "TEST 10: Group Policy Information" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
# Check if domain joined
|
|
$computerSystem = Get-WmiObject -Class Win32_ComputerSystem
|
|
$isDomainJoined = $computerSystem.PartOfDomain
|
|
|
|
Write-Log ""
|
|
Write-Log " Domain Status:" -Color White
|
|
if ($isDomainJoined) {
|
|
Write-Log " Domain Joined: YES" -Color Green
|
|
Write-Log " Domain: $($computerSystem.Domain)"
|
|
} else {
|
|
Write-Log " Domain Joined: NO (Workgroup)" -Color Yellow
|
|
Write-Log " Workgroup: $($computerSystem.Workgroup)"
|
|
}
|
|
|
|
Write-Log ""
|
|
Write-Log " Applied Group Policies:" -Color White
|
|
|
|
# Get GPResult summary
|
|
$gpResult = gpresult /r 2>&1 | Out-String
|
|
|
|
# Extract Computer Configuration section
|
|
if ($gpResult -match "COMPUTER SETTINGS[\s\S]*?Applied Group Policy Objects[\s\S]*?The following GPOs were not applied") {
|
|
$computerGPOs = $matches[0]
|
|
Write-Log " (Displaying first 20 lines of computer GPOs)" -Color Gray
|
|
$computerGPOs -split "`n" | Select-Object -First 20 | ForEach-Object {
|
|
Write-Log " $_" -Color Gray
|
|
}
|
|
} elseif ($gpResult -match "Applied Group Policy Objects[\s\S]*?-{3,}") {
|
|
$gpos = $matches[0] -split "`n" | Where-Object { $_ -match '\S' } | Select-Object -First 15
|
|
$gpos | ForEach-Object { Write-Log " $_" -Color Gray }
|
|
} else {
|
|
Write-Log " [WARN] Could not extract GPO list" -Color Yellow
|
|
}
|
|
|
|
# Check for firewall GPO settings
|
|
Write-Log ""
|
|
Write-Log " Firewall Group Policy:" -Color White
|
|
$firewallGPO = gpresult /r 2>&1 | Select-String -Pattern "firewall" -Context 0,2
|
|
if ($firewallGPO) {
|
|
$firewallGPO | ForEach-Object { Write-Log " $_" -Color Gray }
|
|
} else {
|
|
Write-Log " No firewall-specific GPOs detected" -Color Gray
|
|
}
|
|
|
|
# Check for WinRM GPO settings
|
|
Write-Log ""
|
|
Write-Log " WinRM Group Policy:" -Color White
|
|
$winrmGPO = gpresult /r 2>&1 | Select-String -Pattern "winrm|remote" -Context 0,2
|
|
if ($winrmGPO) {
|
|
$winrmGPO | Select-Object -First 10 | ForEach-Object { Write-Log " $_" -Color Gray }
|
|
} else {
|
|
Write-Log " No WinRM-specific GPOs detected" -Color Gray
|
|
}
|
|
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot get Group Policy info: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 11: Firewall Rule Policy Source
|
|
Write-Log "TEST 11: Firewall Rule Policy Source" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$winrmRules = Get-NetFirewallRule | Where-Object {
|
|
$_.DisplayName -like "*WinRM*"
|
|
}
|
|
|
|
if ($winrmRules) {
|
|
foreach ($rule in $winrmRules) {
|
|
$policySource = $rule.PolicyStoreSource
|
|
$sourceColor = switch ($policySource) {
|
|
'GroupPolicy' { 'Yellow' }
|
|
'PersistentStore' { 'Green' }
|
|
default { 'White' }
|
|
}
|
|
|
|
Write-Log ""
|
|
Write-Log " Rule: $($rule.DisplayName)" -Color White
|
|
Write-Log " Policy Source: $policySource" -Color $sourceColor
|
|
Write-Log " Enabled: $($rule.Enabled)"
|
|
Write-Log " Profile: $($rule.Profile)"
|
|
|
|
if ($policySource -eq 'GroupPolicy') {
|
|
Write-Log " [INFO] Rule is managed by Group Policy" -Color Yellow
|
|
Write-Log " Local changes will be overwritten by GPO" -Color Yellow
|
|
} elseif ($policySource -eq 'PersistentStore') {
|
|
Write-Log " [INFO] Rule is locally configured" -Color Green
|
|
Write-Log " Can be modified locally" -Color Green
|
|
}
|
|
}
|
|
} else {
|
|
Write-Log " [WARNING] No WinRM firewall rules found" -Color Yellow
|
|
}
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot check firewall policy source: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 12: Network Category and GPO Override
|
|
Write-Log "TEST 12: Network Category Control" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
# Check if network category is controlled by GPO
|
|
Write-Log " Checking if Network Category is GPO-controlled..." -Color White
|
|
Write-Log ""
|
|
|
|
$nlmKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\NetworkListManager"
|
|
if (Test-Path $nlmKey) {
|
|
Write-Log " [INFO] Network List Manager GPO key exists" -Color Yellow
|
|
Write-Log " Network category may be controlled by Group Policy" -Color Yellow
|
|
|
|
$nlmValues = Get-ItemProperty -Path $nlmKey -ErrorAction SilentlyContinue
|
|
if ($nlmValues) {
|
|
$nlmValues.PSObject.Properties | Where-Object {
|
|
$_.Name -notlike "PS*"
|
|
} | ForEach-Object {
|
|
Write-Log " $($_.Name) = $($_.Value)" -Color Gray
|
|
}
|
|
}
|
|
} else {
|
|
Write-Log " [OK] Network category is not GPO-controlled" -Color Green
|
|
Write-Log " Can be changed locally" -Color Green
|
|
}
|
|
|
|
# Check current network profiles again with category source
|
|
Write-Log ""
|
|
Write-Log " Current Network Profiles:" -Color White
|
|
$profiles = Get-NetConnectionProfile
|
|
foreach ($profile in $profiles) {
|
|
$category = $profile.NetworkCategory
|
|
Write-Log ""
|
|
Write-Log " Interface: $($profile.InterfaceAlias)" -Color White
|
|
Write-Log " Category: $category"
|
|
Write-Log " Name: $($profile.Name)"
|
|
|
|
# Determine if can be changed
|
|
if (Test-Path $nlmKey) {
|
|
Write-Log " Can Change: NO (GPO Controlled)" -Color Yellow
|
|
} else {
|
|
Write-Log " Can Change: YES (Local Control)" -Color Green
|
|
}
|
|
}
|
|
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot check network category control: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Test 13: Self-Connectivity Test
|
|
Write-Log "TEST 13: Self-Connectivity Test" -Color Yellow
|
|
Write-Log "------------------------------"
|
|
try {
|
|
$hostname = $env:COMPUTERNAME
|
|
$fqdn = "$hostname.logon.ds.ge.com".ToLower()
|
|
|
|
Write-Log " Testing local connectivity to port 5986..."
|
|
$portTest = Test-NetConnection -ComputerName localhost -Port 5986 -WarningAction SilentlyContinue
|
|
|
|
if ($portTest.TcpTestSucceeded) {
|
|
Write-Log " [OK] Port 5986 is reachable locally" -Color Green
|
|
} else {
|
|
Write-Log " [ERROR] Port 5986 is NOT reachable locally" -Color Red
|
|
Write-Log " This indicates WinRM HTTPS is not properly configured" -Color Yellow
|
|
}
|
|
|
|
Write-Log ""
|
|
Write-Log " Remote computers should connect to:" -Color Cyan
|
|
Write-Log " $fqdn:5986" -Color White
|
|
} catch {
|
|
Write-Log "[ERROR] Cannot test connectivity: $($_.Exception.Message)" -Color Red
|
|
}
|
|
Write-Log ""
|
|
|
|
# Summary
|
|
Write-Log "======================================" -Color Cyan
|
|
Write-Log " Debug Test Complete" -Color Cyan
|
|
Write-Log "======================================" -Color Cyan
|
|
Write-Log ""
|
|
Write-Log "Save this output for troubleshooting!"
|
|
Write-Log ""
|