Created
May 22, 2026 01:33
-
-
Save lrckt/42f401bc3e070a263e61f349c64cefbc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Test-TlsEndpoint { | |
| param( | |
| [Parameter(Mandatory=$true)] | |
| [string]$ComputerName, | |
| [int]$Port = 443 | |
| ) | |
| Write-Host "`nTesting $ComputerName`:$Port" -ForegroundColor Cyan | |
| Write-Host ("-" * 60) | |
| # Check basic connectivity first | |
| $tcp = Test-NetConnection -ComputerName $ComputerName -Port $Port -WarningAction SilentlyContinue | |
| if (-not $tcp.TcpTestSucceeded) { | |
| Write-Host "TCP connection failed" -ForegroundColor Red | |
| return | |
| } | |
| Write-Host "TCP/$Port reachable" -ForegroundColor Green | |
| # Save original protocol setting | |
| $originalProtocol = [Net.ServicePointManager]::SecurityProtocol | |
| # Protocols to test - using static enum values (CLM-safe) | |
| $protocols = @{ | |
| 'SSL 3.0' = [Net.SecurityProtocolType]::Ssl3 | |
| 'TLS 1.0' = [Net.SecurityProtocolType]::Tls | |
| 'TLS 1.1' = [Net.SecurityProtocolType]::Tls11 | |
| 'TLS 1.2' = [Net.SecurityProtocolType]::Tls12 | |
| } | |
| # TLS 1.3 only exists on newer .NET - check before adding | |
| try { | |
| $tls13 = [Net.SecurityProtocolType]::Tls13 | |
| $protocols['TLS 1.3'] = $tls13 | |
| } catch { | |
| Write-Host "TLS 1.3 enum not available on this .NET version" -ForegroundColor DarkGray | |
| } | |
| $uri = "https://${ComputerName}:${Port}" | |
| $results = @() | |
| foreach ($name in $protocols.Keys) { | |
| try { | |
| [Net.ServicePointManager]::SecurityProtocol = $protocols[$name] | |
| # -UseBasicParsing avoids IE engine dependency; -TimeoutSec keeps it snappy | |
| $null = Invoke-WebRequest -Uri $uri -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop | |
| $supported = $true | |
| $detail = "OK" | |
| } catch { | |
| $msg = $_.Exception.Message | |
| # Distinguish handshake failure from other errors (404, 500, cert errors etc still mean TLS worked) | |
| if ($msg -match "could not establish|handshake|protocol|SSL/TLS|secure channel") { | |
| $supported = $false | |
| $detail = "Handshake failed" | |
| } else { | |
| # Got an HTTP error - that means TLS handshake succeeded | |
| $supported = $true | |
| $detail = "OK (HTTP error: $($_.Exception.Status))" | |
| } | |
| } | |
| $results += [PSCustomObject]@{ | |
| Protocol = $name | |
| Supported = $supported | |
| Detail = $detail | |
| } | |
| } | |
| # Restore original protocol setting | |
| [Net.ServicePointManager]::SecurityProtocol = $originalProtocol | |
| $results | Format-Table -AutoSize | |
| # Certificate inspection - uses cmdlet, CLM-safe | |
| Write-Host "Certificate details:" -ForegroundColor Cyan | |
| try { | |
| # Trust all certs temporarily for inspection (CLM-safe via scriptblock assignment is blocked, | |
| # so we rely on the connection succeeding above and pull cert from ServicePoint) | |
| [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |
| $req = [Net.HttpWebRequest]::Create($uri) | |
| $req.Timeout = 10000 | |
| try { $resp = $req.GetResponse(); $resp.Close() } catch { } | |
| $cert = $req.ServicePoint.Certificate | |
| if ($cert) { | |
| [PSCustomObject]@{ | |
| Subject = $cert.Subject | |
| Issuer = $cert.Issuer | |
| NotBefore = $cert.GetEffectiveDateString() | |
| NotAfter = $cert.GetExpirationDateString() | |
| Thumbprint = $cert.GetCertHashString() | |
| SerialNumber = $cert.GetSerialNumberString() | |
| } | Format-List | |
| } else { | |
| Write-Host "Could not retrieve certificate" -ForegroundColor Yellow | |
| } | |
| } catch { | |
| Write-Host "Cert retrieval failed: $($_.Exception.Message)" -ForegroundColor Yellow | |
| } | |
| [Net.ServicePointManager]::SecurityProtocol = $originalProtocol | |
| } | |
| # Usage: | |
| #Test-TlsEndpoint -ComputerName "target.example.com" | |
| # Test-TlsEndpoint -ComputerName "internal.host" -Port 8443 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment