Created
July 12, 2022 10:01
-
-
Save ToroNZ/dbcc18b6ee70b4d20a2d043b9dcd9abb to your computer and use it in GitHub Desktop.
Powershell - Check/Get SSL/TLS Certificate
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
using namespace System.Net.Sockets | |
using namespace System.Net.Security | |
using namespace System.Security.Cryptography.X509Certificates | |
function Test-ServerSSLSupport { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory = $true, ValueFromPipeline = $true)] | |
[ValidateNotNullOrEmpty()] | |
[string]$HostName, | |
[UInt16]$Port = 443 | |
) | |
process { | |
$RetValue = New-Object psobject -Property @{ | |
Host = $HostName | |
Port = $Port | |
SSLv2 = $false | |
SSLv3 = $false | |
TLSv1_0 = $false | |
TLSv1_1 = $false | |
TLSv1_2 = $false | |
KeyExhange = $null | |
HashAlgorithm = $null | |
} | |
"ssl2", "ssl3", "tls", "tls11", "tls12" | %{ | |
$TcpClient = New-Object Net.Sockets.TcpClient | |
$TcpClient.Connect($RetValue.Host, $RetValue.Port) | |
$SslStream = New-Object Net.Security.SslStream $TcpClient.GetStream(), | |
$true, | |
([System.Net.Security.RemoteCertificateValidationCallback]{ $true }) | |
$SslStream.ReadTimeout = 15000 | |
$SslStream.WriteTimeout = 15000 | |
try { | |
$SslStream.AuthenticateAsClient($RetValue.Host,$null,$_,$false) | |
$RetValue.KeyExhange = $SslStream.KeyExchangeAlgorithm | |
$RetValue.HashAlgorithm = $SslStream.HashAlgorithm | |
$status = $true | |
} catch { | |
$status = $false | |
} | |
switch ($_) { | |
"ssl2" {$RetValue.SSLv2 = $status} | |
"ssl3" {$RetValue.SSLv3 = $status} | |
"tls" {$RetValue.TLSv1_0 = $status} | |
"tls11" {$RetValue.TLSv1_1 = $status} | |
"tls12" {$RetValue.TLSv1_2 = $status} | |
} | |
# dispose objects to prevent memory leaks | |
$TcpClient.Dispose() | |
$SslStream.Dispose() | |
} | |
$RetValue | |
} | |
} | |
function Get-ADDomainControllerCertificate | |
{ | |
<# | |
.SYNOPSIS | |
Retrieves the LDAPS certificate properties. | |
.PARAMETER ComputerName | |
Specifies the Active Directory domain controller. | |
.PARAMETER Domain | |
Specifies the Active Directory DNS name. | |
.PARAMETER Port | |
LDAPS port for domain controller: 636 (default) | |
LDAPS port for global catalog: 3269 | |
.DESCRIPTION | |
The cmdlet 'Get-ADDomainControllerCertificate' retrieves the LDAP over TSL/SSL certificate properties. | |
.EXAMPLE | |
Get-ADDomainControllerCertificate -ComputerName DC01 | |
.EXAMPLE | |
Get-ADDomainControllerCertificate -ComputerName DC01,DC02 | Select ComputerName,Port,Subject,Thumbprint | |
.EXAMPLE | |
Get-ADDomainControllerCertificate DC01,DC02 | |
.EXAMPLE | |
Get-ADDomainControllerCertificate DC01 -Port 3269 | |
.EXAMPLE | |
Get-ADDomainControllerCertificate -Domain domain.local | |
.EXAMPLE | |
Get-ADDomainControllerCertificate -Domain domain.local | Select-Object ComputerName,Port,Subject,Thumbprint | |
.EXAMPLE | |
Get-ADDomainControllerCertificate -Domain domain.local -Port 3269 | Select-Object ComputerName,Port,Subject,Thumbprint | |
#> | |
[Cmdletbinding(DefaultParameterSetName='ComputerName')] | |
param( | |
[Parameter(ParameterSetName='ComputerName',Mandatory,Position=0)] | |
[Alias('CN')] | |
[string[]]$ComputerName, | |
[Parameter(ParameterSetName='DomainName',Mandatory,Position=0)] | |
[string]$Domain, | |
[Parameter(Position=1)] | |
[UInt16]$Port = 443, | |
[ValidateSet('Base64', 'X509Certificate')] | |
[string]$As = 'X509Certificate' | |
) | |
function ConvertFrom-X509Certificate { | |
param( | |
[Parameter(ValueFromPipeline)] | |
[X509Certificate2]$Certificate | |
) | |
process { | |
@( | |
'-----BEGIN CERTIFICATE-----' | |
[Convert]::ToBase64String( | |
$Certificate.Export([X509ContentType]::Cert), | |
[Base64FormattingOptions]::InsertLineBreaks | |
) | |
'-----END CERTIFICATE-----' | |
) -join [Environment]::NewLine | |
} | |
} | |
if($ComputerName) | |
{ $DomainDCs = $ComputerName | Get-ADDomainController | Sort-Object -Property Name } | |
if($Domain) | |
{ $DomainDCs = Get-ADDomainController -Server $Domain -Filter * | Sort-Object -Property Name } | |
foreach($DC in $DomainDCs) | |
{ | |
$Server = $DC.HostName | |
try | |
{ | |
$Connection = New-Object System.Net.Sockets.TcpClient($Server,$Port) | |
$TLSStream = New-Object System.Net.Security.SslStream($Connection.GetStream(), $false, {$true}) | |
# Try to validate certificate, break out if we don't | |
try | |
{ | |
$TLSStream.AuthenticateAsClient($Server, $null, [System.Net.SecurityProtocolType]'Tls, Tls12', $false) | |
$Status = "Validated" | |
} | |
catch | |
{ | |
$Status = "Validation Failed" | |
$Connection.Close | |
Break | |
} | |
#Export as Base64 or PS Object | |
if ($As -eq 'Base64') { | |
return $TLSStream.RemoteCertificate | ConvertFrom-X509Certificate | |
} | |
else { | |
#Grab the Cert and it's Basic Properties | |
$RemoteCert = New-Object system.security.cryptography.x509certificates.x509certificate2($TLSStream.get_remotecertificate()) | |
# Advanced Properties | |
try { $SAN = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '2.5.29.17'}).Format(0)} catch{} | |
try { $AppPolicies = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '1.3.6.1.4.1.311.21.10'}).Format(0)} catch{} | |
try { $V1TemplateName = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '1.3.6.1.4.1.311.20.2'}).Format(0)} catch{} | |
try { $V2TemplateName = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '1.3.6.1.4.1.311.21.7'}).Format(0)} catch{} | |
try { $SKI = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '2.5.29.14'}).Format(0)} catch{} | |
try { $AKI = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '2.5.29.35'}).Format(0)} catch{} | |
try { $BKU = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '2.5.29.15'}).Format(0)} catch{} | |
try { $EKU = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '2.5.29.37'}).Format(0)} catch{} | |
try { $CDP = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '2.5.29.31'}).Format(0)} catch{} | |
try { $AIA = ($RemoteCert.Extensions | Where-Object {$_.Oid.Value -eq '1.3.6.1.5.5.7.1.1'}).Format(0)} catch{} | |
# Object creation | |
New-Object -TypeName PSObject -Property ([ordered]@{ | |
ComputerName = $Server | |
Port = $Port | |
Status = $Status | |
Subject = $RemoteCert.Subject | |
SAN = $SAN | |
FriendlyName = $RemoteCert.FriendlyName | |
Issuer = $RemoteCert.Issuer | |
ValidFrom = $RemoteCert.NotBefore | |
ValidTo = $RemoteCert.NotAfter | |
Thumbprint = $RemoteCert.Thumbprint | |
SignatureAlgorithm = $RemoteCert.SignatureAlgorithm.FriendlyName | |
AIA = $AIA | |
AKI = $AKI | |
BKU = $BKU | |
CDP = $CDP | |
EKU = $EKU | |
SKI = $SKI | |
AppPolicies = $AppPolicies | |
V1TemplateName = $V1TemplateName | |
V2TemplateName = $V2TemplateName | |
}) | |
} | |
} | |
catch { $Status = 'Connection Failed' } | |
finally { $Connection.Close() } | |
} | |
} | |
#Example-Func1 | |
"COMPUTER1.contoso.com" | Test-ServerSSLSupport -Port 636 | |
#Example-Func2 | |
Get-ADDomainControllerCertificate -ComputerName COMPUTER1.contoso.com -Port 636 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment