Test-NetSslProtocol.ps1
<#
.Synopsis Test the SSL and TLS protocols on a remote server. .DESCRIPTION Validate which SSL and TLS protocols are enabled or disabled on remote systems and ports. .PARAMETER ComputerName Specify the DNS name or IP address of the URL you want to query. .PARAMETER Port Specify the port of the destination server. .EXAMPLE Test-NetSslProtocol -ComputerName www.google.com -Port 443 .EXAMPLE Test-NetSslProtocol -IP 8.8.8.8 -Port 853 .NOTES Created by: Jason Wasser Modified: 11/10/2020 Reconciled use of $TCPClient and $TcpSocket Comments added at change locations for integration #> function Test-NetSslProtocol { [CmdletBinding()] Param ( [Parameter(Mandatory, ValueFromPipeline)] [Alias('IP')] [string[]]$ComputerName, [int[]]$Port = 443, [ValidateSet('ssl2', 'ssl3', 'tls', 'tls11', 'tls12', 'tls13')] [string[]]$Protocol = ('ssl2', 'ssl3', 'tls', 'tls11', 'tls12', 'tls13') ) begin { #Commenting this out because it isn't actually used #$TCPClient = New-Object -TypeName System.Net.Sockets.TCPClient } process { foreach ($Computer in $ComputerName) { foreach ($CurrentPort in $Port) { foreach ($CurrentProtocol in $Protocol) { Write-Verbose "Testing $CurrentProtocol on ${Computer}:$Port" try { #Adding typename parameter and fully qualifying TcpClient $TcpSocket = New-Object -TypeName System.Net.Sockets.TcpClient($Computer, $CurrentPort) $tcpstream = $TcpSocket.GetStream() #$sender is flagged by VSCode as an automatic variable and recommends changing it. Changed to caller and functionality seems undeminished $Callback = { param($caller, $cert, $chain, $errors) return $true } $SSLStream = New-Object -TypeName System.Net.Security.SSLStream -ArgumentList @($tcpstream, $True, $Callback) try { $SSLStream.AuthenticateAsClient($Computer, $null, $CurrentProtocol, $false) $ProtocolStatus = 'Enabled' } catch { $ProtocolStatus = 'Disabled' } finally { $SSLStream.Dispose() } } catch { Write-Warning "Unable to connect to ${Computer}:$CurrentPort" break } finally { #Changing following from TCPClient to TcpSocket since that is what is actually used $TcpSocket.Dispose() } if ($ProtocolStatus) { $NetSslProtocolProperties = [ordered]@{ ComputerName = $Computer Port = $CurrentPort Protocol = $CurrentProtocol ProtocolStatus = $ProtocolStatus } $NetSslProtocol = New-Object -TypeName PSCustomObject -Property $NetSslProtocolProperties Write-Output $NetSslProtocol $ProtocolStatus = $null } } } } } end { } } |