Sorry if this has already been asked before, but I've not been able to find this by searching online or in the forums.
When you initially make a connection to either a VC/ESXi host, there's some information displayed about x509 Certificate as seen below.
* The X509 chain could not be built up to the root certificate.
Certificate: [Subject]
C=US, CN=vcenter60-4.primp-industries.com
[Issuer]
O=vcenter60-4.primp-industries.com, C=US, DC=local, DC=vghetto, CN=CA
[Serial Number]
00D9B9AE28CFD6CF4D
[Not Before]
2/8/2015 9:19:14 AM
[Not After]
2/2/2025 9:19:13 AM
[Thumbprint]
B846B9F36C1D978CEDA0199294E61B4515656396
I would like to capture the SSL Thumbprint "B846B9F36C1D978CEDA0199294E61B4515656396"? I've looked online and even asked some folks but never been able to retrieve this property using PowerShell/PowerCLI. I can easily do this on a non-Windows system with openssl (http://www.virtuallyghetto.com/2012/04/extracting-ssl-thumbprint-from-esxi.html) but wanted to see if there's a way without having to relay on external packages and since it's available as part of the Connect-VIServer, I figured it must be possible but my PowerCLI-Fu is not quite up to par as others, so figure I ask. If this is indeed extractable, which I assume it is then a bonus would be to format it so I have a variable that looks like: B8:46:B9:F3:6C:1D:97:8C:ED:A0:19:92:94:E6:1B:45:15:65:63:96
Thanks Luc in advance
Function Test-WebServerSSL {
# Function original location: http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?List=332991f0-bfed-4143-9eea-f521167d287c&ID=60
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$URL,
[Parameter(Position = 1)]
[ValidateRange(1,65535)]
[int]$Port = 443,
[Parameter(Position = 2)]
[Net.WebProxy]$Proxy,
[Parameter(Position = 3)]
[int]$Timeout = 15000,
[switch]$UseUserContext
)
Add-Type @"
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace PKI {
namespace Web {
public class WebSSL {
public Uri OriginalURi;
public Uri ReturnedURi;
public X509Certificate2 Certificate;
//public X500DistinguishedName Issuer;
//public X500DistinguishedName Subject;
public string Issuer;
public string Subject;
public string[] SubjectAlternativeNames;
public bool CertificateIsValid;
//public X509ChainStatus[] ErrorInformation;
public string[] ErrorInformation;
public HttpWebResponse Response;
}
}
}
"@
$ConnectString = "https://$url`:$port"
$WebRequest = [Net.WebRequest]::Create($ConnectString)
$WebRequest.Proxy = $Proxy
$WebRequest.Credentials = $null
$WebRequest.Timeout = $Timeout
$WebRequest.AllowAutoRedirect = $true
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
try {$Response = $WebRequest.GetResponse()}
catch {}
if ($WebRequest.ServicePoint.Certificate -ne $null) {
$Cert = [Security.Cryptography.X509Certificates.X509Certificate2]$WebRequest.ServicePoint.Certificate.Handle
try {$SAN = ($Cert.Extensions | Where-Object {$_.Oid.Value -eq "2.5.29.17"}).Format(0) -split ", "}
catch {$SAN = $null}
$chain = New-Object Security.Cryptography.X509Certificates.X509Chain -ArgumentList (!$UseUserContext)
[void]$chain.ChainPolicy.ApplicationPolicy.Add("1.3.6.1.5.5.7.3.1")
$Status = $chain.Build($Cert)
New-Object PKI.Web.WebSSL -Property @{
OriginalUri = $ConnectString;
ReturnedUri = $Response.ResponseUri;
Certificate = $WebRequest.ServicePoint.Certificate;
Issuer = $WebRequest.ServicePoint.Certificate.Issuer;
Subject = $WebRequest.ServicePoint.Certificate.Subject;
SubjectAlternativeNames = $SAN;
CertificateIsValid = $Status;
Response = $Response;
ErrorInformation = $chain.ChainStatus | ForEach-Object {$_.Status}
}
$chain.Reset()
[Net.ServicePointManager]::ServerCertificateValidationCallback = $null
} else {
Write-Error $Error[0]
}
}
$cert = Test-WebServerSSL MYVC
$cert.Certificate.Thumbprint
Hi William,
Try like this
$vcenter = 'vcenter'
$user = 'account'
$pswd = 'password'
Connect-VIServer -Server $vcenter -User $user -Password $pswd | Out-Null
$thumbprint = Get-ChildItem -Recurse -Path cert: | where {$_.Subject -match $vcenter} | select -ExpandProperty Thumbprint
($thumbprint -split '(..)' | where {$_}) -join ':'
Don't you just love PowerCLI
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Luc,
Is there other way to generate the SHA1 Fingerprint? I just noticed that this info is only displayed on initial connection, it's not shown again after the fact. Thanks
I would have thought it would be shorter one-liner like the following?
echo -n | openssl s_client -connect 172.30.0.252:443 2>/dev/null | openssl x509 -noout -fingerprint -sha1
You want an unreadable one-liner, here you go :smileygrin:
dir -r cert: | ? Subject -ma $vcenter | Select -exp Thumbprint
The Thumbprint is indeed only shown at the first Connect-VIServer in a PowerShell session.
In fact, it is stored in the Cert repository, you don't even need to do a Connect-VIServer.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Function Test-WebServerSSL {
# Function original location: http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?List=332991f0-bfed-4143-9eea-f521167d287c&ID=60
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
[string]$URL,
[Parameter(Position = 1)]
[ValidateRange(1,65535)]
[int]$Port = 443,
[Parameter(Position = 2)]
[Net.WebProxy]$Proxy,
[Parameter(Position = 3)]
[int]$Timeout = 15000,
[switch]$UseUserContext
)
Add-Type @"
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace PKI {
namespace Web {
public class WebSSL {
public Uri OriginalURi;
public Uri ReturnedURi;
public X509Certificate2 Certificate;
//public X500DistinguishedName Issuer;
//public X500DistinguishedName Subject;
public string Issuer;
public string Subject;
public string[] SubjectAlternativeNames;
public bool CertificateIsValid;
//public X509ChainStatus[] ErrorInformation;
public string[] ErrorInformation;
public HttpWebResponse Response;
}
}
}
"@
$ConnectString = "https://$url`:$port"
$WebRequest = [Net.WebRequest]::Create($ConnectString)
$WebRequest.Proxy = $Proxy
$WebRequest.Credentials = $null
$WebRequest.Timeout = $Timeout
$WebRequest.AllowAutoRedirect = $true
[Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
try {$Response = $WebRequest.GetResponse()}
catch {}
if ($WebRequest.ServicePoint.Certificate -ne $null) {
$Cert = [Security.Cryptography.X509Certificates.X509Certificate2]$WebRequest.ServicePoint.Certificate.Handle
try {$SAN = ($Cert.Extensions | Where-Object {$_.Oid.Value -eq "2.5.29.17"}).Format(0) -split ", "}
catch {$SAN = $null}
$chain = New-Object Security.Cryptography.X509Certificates.X509Chain -ArgumentList (!$UseUserContext)
[void]$chain.ChainPolicy.ApplicationPolicy.Add("1.3.6.1.5.5.7.3.1")
$Status = $chain.Build($Cert)
New-Object PKI.Web.WebSSL -Property @{
OriginalUri = $ConnectString;
ReturnedUri = $Response.ResponseUri;
Certificate = $WebRequest.ServicePoint.Certificate;
Issuer = $WebRequest.ServicePoint.Certificate.Issuer;
Subject = $WebRequest.ServicePoint.Certificate.Subject;
SubjectAlternativeNames = $SAN;
CertificateIsValid = $Status;
Response = $Response;
ErrorInformation = $chain.ChainStatus | ForEach-Object {$_.Status}
}
$chain.Reset()
[Net.ServicePointManager]::ServerCertificateValidationCallback = $null
} else {
Write-Error $Error[0]
}
}
$cert = Test-WebServerSSL MYVC
$cert.Certificate.Thumbprint
I prefer not to rely on cached content as it can change. The one-liner using OpenSSL is simple enough to make a quick connect, but was hoping there was an equivalent in PowerShell or easier way via PowerCLI if we had that info. I guess Alan's reply confirmed my suspicion that retrieving this particular property is not as easy as I had hoped. I'll just use use Alan's method for now and have already asked for an enhancement to PowerCLI
Thanks again for your assistance Luc, good to known about these other methods and hopefully this can help others with similar requests
Feature request added
I tried below on couple of my servers it worked for me, I had to to make sure your powercli ignoresettings are set to unset.
$test = Powershell -Command "Add-PSSnapin vmware.vimautomation.core; Connect-VIServer esxi -User Username -Password Password"
$test[46].trim()
for vcenter i found thumbprint comes on 44 line. and for esxi it comes on 46. I could be on different line for you environment.
This function worked fine till I was using comodo ssl certificate. Now I started using entrust ssl certificates and its throwing the exception "An error occured retrieving the SSL certificate".
Any help here would be really appreciatred.
Regards
Ramakrishnan
Hi LucD,
Could you tell me, How can I find these information of ESXi Hosts (Powercli).
Thank you for your answer.
In fact the same way as for a vCenter.
Just use the ESXi Uri.
William wrote a function for this Get-SSLThumprint.
Instead of the thumbprint, you can also retrieve the Issuer, the Subject and many other properties.
What exactly do you want?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you so much LucD,
I want these informations:
serial number:
Signature algorithm:
issuer:
valid from:
valid to:
subject:
Hi LucD
Thank you for your help.
I have tried to find these information, but I can't.
Could you please help me?
Thank you.
If you use Alan's code from earlier in this thread, the information is in $cert.Certificate.SignatureAlgorithm.FriendlyName
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD
Thank you for your answer, your mean:
[System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy
# Need to connect using simple GET operation for this to work
Invoke-RestMethod -Uri $URL -Method Get | Out-Null
$ENDPOINT_REQUEST = [System.Net.Webrequest]::Create("$URL")
$SSL_THUMBPRINT = $ENDPOINT_REQUEST.ServicePoint.Certificate.GetCertHashString()
$FriendlyName = $ENDPOINT_REQUEST.ServicePoint.Certificate.signatureAlgorithm.FriendlyName
return $SSL_THUMBPRINT -replace '(..(?!$))','$1:'
$FriendlyName
But it doesn't work for me.
I mean Alan's Test-WebServerSSL function.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD
Thank you for your support.
It doesn't work for me.
Do you have any other idea?
Thank you.