Public/Get-SslCertificate.ps1
<#
.SYNOPSIS Retrieves SSL certificate information from a specified URI and port. .DESCRIPTION The Get-SslCertificate function establishes a TCP connection to the specified URI and port, retrieves the SSL certificate, and provides detailed information about the certificate, including its subject, issuer, validity period, serial number, thumbprint, and extensions. Optionally, the full certificate object can be included in the output. .PARAMETER Uri The URI of the server from which to retrieve the SSL certificate. .PARAMETER Port The port number to connect to (default is 443). .PARAMETER IncludeCertificate A switch parameter that, when specified, includes the full SSL certificate object in the output. .PARAMETER IPAddress An optional parameter to specify the IP address of the server. This parameter is validated to ensure it is a valid IP address. .EXAMPLE Get-SslCertificate -Uri "www.example.com" -IncludeCertificate .EXAMPLE Get-SslCertificate -Uri "www.example.com" -Port 8443 #> Function Get-SslCertificate { [CmdletBinding(DefaultParameterSetName = 'ByUri')] param( [Parameter(Mandatory, ParameterSetName = 'ByUri', Position = 0)] [String]$Uri, [Parameter(Mandatory, ParameterSetName = 'ByIP', Position = 0)] [ValidateScript({[ipaddress]($_ -replace '^https://')})] [String]$IPAddress, [Int]$Port = 443, [Switch]$IncludeCertificate ) # Decide between Uri and IpAdress and remove scheme $Endpoint = switch ($PSCmdlet.ParameterSetName) { 'ByUri' { $Uri -replace '^https://' } 'ByIP' { $IPAddress.IPAddressToString -replace '^https://' } } Write-Verbose "Create TcpClient and SslStream and connect to $($Endpoint):$Port" $TcpClient = New-Object -TypeName System.Net.Sockets.TcpClient -ArgumentList $Endpoint, $Port $SslStream = New-Object -TypeName System.Net.Security.SslStream -ArgumentList $TcpClient.GetStream(), $false, { $true } Write-Verbose "Authenticate as client" Try { $SslStream.AuthenticateAsClient($Endpoint) Write-Verbose "Authenticated successfully" } Catch { Write-Verbose "Could not authenticate to $($Endpoint):$Port" Return } $Certificate = $SslStream.RemoteCertificate $Extensions = Foreach($Extension in $Certificate.Extensions) { $AsnEncodedData = [System.Security.Cryptography.AsnEncodedData]::new($Extension.Oid, $Extension.RawData) $ExtensionsObject = [pscustomobject]@{ ExtensionType = $Extension.Oid.FriendlyName OidValue = $Extension.Oid.Value RawDataLength = $AsnEncodedData.RawData.Length ExtensionValue = $AsnEncodedData.Format($true) } $DefaultDisplaySet = 'ExtensionType', 'ExtensionValue' $DefaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$defaultDisplaySet) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $ExtensionsObject| Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers $ExtensionsObject.PSObject.TypeNames.Insert(0, 'Extension.Information') Write-Output $ExtensionsObject } $CertObject = [pscustomobject]@{ Subject = $Certificate.Subject IssuedOn = $Certificate.NotBefore ExpiresOn = $Certificate.NotAfter Issuer = $Certificate.Issuer SerialNumber = $Certificate.SerialNumber Thumbprint = $Certificate.Thumbprint Extensions = $Extensions Request = @{ TcpHost = $Endpoint } } If($IncludeCertificate.IsPresent) { $CertObject | Add-Member -MemberType NoteProperty -Name 'Certificate' -Value $Certificate } $DefaultDisplaySet = 'Subject', 'IssuedOn', 'ExpiresOn', 'Issuer', 'SerialNumber', 'Thumbprint' $DefaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$defaultDisplaySet) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) $CertObject| Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers $CertObject.PSObject.TypeNames.Insert(0, 'Certificate.Information') Write-Output $CertObject } |