Get-NetCertificate.ps1

<#
.Synopsis
Get the TLS certificate from a remote server.
.DESCRIPTION
Obtain the TLS certificate from a remote server by name or IP address and TCP port.
.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
Get-NetCertificate -ComputerName www.google.com -Port 443
.EXAMPLE
Get-NetCertificate -IP 8.8.8.8 -Port 853
.NOTES
Adapted by: Jason Wasser
Original code by: Rob VandenBrink
Inspiration
https://isc.sans.edu/forums/diary/Assessing+Remote+Certificates+with+Powershell/20645/
 
Modified: 1/9/2020 02:16:05 PM
# Need to verify if this supports server name indication (SNI) for certificates
Modified: 11/10/2020
Reconciled use of $TCPClient and $TcpSocket
Comments added at change locations for integration
#>

function Get-NetCertificate {
    Param (
        [Alias('IP')]
        [string]$ComputerName,
        [int]$Port=443
    )

    #Commenting this out because it isn't actually used
    #$TCPClient = New-Object -TypeName System.Net.Sockets.TCPClient
    try {
        #Adding typename parameter and fully qualifying TcpClient
        $TcpSocket = New-Object -TypeName System.Net.Sockets.TcpClient($ComputerName, $Port)
        $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($ComputerName)
            $Certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($SSLStream.RemoteCertificate)
        }
        finally {
            $SSLStream.Dispose()
        }
    }
    finally {
        #Changing following from TCPClient to TcpSocket since that is what is actually used
        $TcpSocket.Dispose()
    }
    Write-Output $Certificate
}