Home > Blogs > VMware PowerCLI Blog


Automating SSL Checks for vCenter and Host Certificates

AlanFeb2012_thumb_thumb1_thumb_thumb[2]
Posted by
Alan Renouf
Technical Marketing

Recently William Lam wrote a great article showing how easy it was to check your hosts SSL Certificates and Expiry information using a free tool called ssl-cert-check, he explains that it is best practice to replace VMware’s self-signed SSL certificates that are included with the vCenter Server and on all hosts, make sure you read his post here and in turn make sure you also read Michael Websters articles which take you through this process here.

But what if we wanted to check these certificates in PowerCLI, recently I found a great PowerShell Advanced function which allows us to do just this, we are able to test the certificate of any given website and return the details.

Using this script and a little code of our own we can easily check all our hosts and the vCenter Certificates as seen below:

SNAGHTML1f5e280e

The code will output the most important details included who the issuer of the certificate is, whether it is valid and when it expires, both in date and length of time.

This could easily be adapted to check on a regular basis and email closer to the expiry date.

Code

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]
    }
}

Connect-VIServer MyVC -User Administrator –Password Password!

# Check for Host Certificates
Get-VMHost | Foreach { Test-WebServerSSL -URL $_.Name | Select OriginalURi, CertificateIsValid, Issuer, @{N="Expires";E={$_.Certificate.NotAfter} }, @{N="DaysTillExpire";E={(New-TimeSpan -Start (Get-Date) -End ($_.Certificate.NotAfter)).Days} }}

# Check for vCenter Certificate
Test-WebServerSSL -URL $DefaultVIServer | Select OriginalURi, CertificateIsValid, Issuer, @{N="Expires";E={$_.Certificate.NotAfter} }, @{N="DaysTillExpire";E={(New-TimeSpan -Start (Get-Date) -End ($_.Certificate.NotAfter)).Days} }

Get notification of new blog postings and more by following VMware PowerCLI on Twitter: @PowerCLI

 

This entry was posted in Advanced by Alan Renouf. Bookmark the permalink.
Alan Renouf

About Alan Renouf

Alan Renouf is a Senior Technical Marketing Architect at VMware focused on the automation and integration of VMware products. Alan is a frequent blogger at http://blogs.vmware.com/vipowershell and has a personal blog at http://virtu-al.net. You can follow Alan on twitter as @alanrenouf.

2 thoughts on “Automating SSL Checks for vCenter and Host Certificates

  1. I recommend to use the version 1.8 of the PsPki module on CodePlex, from the author of this function, because the posted code version “leaks” Response objects, causing issues.
    Bye
    Claudio