I am not familiar with a way to do this check with VBS and/or WMI as that is possibly a security whole because it could potentially expose the private key. However, there is a way to leverage a normal HTTPS connection to get to the public information about the certificate. If you connect to any secure web site using IE, you can then go to the File menu and look at the Properties and then click the Certificates button. That shows the public certificate information dialog for the site. You can get to this information programmatically using C#.
Basically, what you have to do is to open a TCP connection to the server on port 443 and then receive the SSL data. In this data stream is the public information about the certificate and you can validate it and extract all the information you need from it, including expiration date. Here is some sample code:
static void Main(string[] args) {
foreach (string servername in args) {
Console.WriteLine("\n\nFetching SSL cert for {0}\n", servername);
TcpClient client = new TcpClient(servername, 443);
SslStream sslStream = new SslStream(client.GetStream(), false, callback, null);
try {
sslStream.AuthenticateAsClient(servername);
} catch (AuthenticationException ex) {
Console.WriteLine("Exception: {0}", ex.Message);
if (ex.InnerException != null) {
Console.WriteLine("Inner exception: {0}", ex.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
}
client.Close();
}
}
And the code for the callback that handles certificate information:
static RemoteCertificateValidationCallback callback = delegate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslError) {
X509Certificate2 x509 = new X509Certificate2(cert);
// Print to console information contained in the certificate.
Console.WriteLine("Subject: {0}", x509.Subject);
Console.WriteLine("Issuer: {0}", x509.Issuer);
Console.WriteLine("Version: {0}", x509.Version);
Console.WriteLine("Valid Date: {0}", x509.NotBefore);
Console.WriteLine("Expiry Date: {0}", x509.NotAfter);
Console.WriteLine("Thumbprint: {0}", x509.Thumbprint);
Console.WriteLine("Serial Number: {0}", x509.SerialNumber);
Console.WriteLine("Friendly Name: {0}", x509.PublicKey.Oid.FriendlyName);
Console.WriteLine("Public Key Format: {0}", x509.PublicKey.EncodedKeyValue.Format(true));
Console.WriteLine("Raw Data Length: {0}", x509.RawData.Length);
if (sslError != SslPolicyErrors.None) {
Console.WriteLine("Certificate error: " + sslError);
}
return false;
};
And the cool thing is that this approach should, technically, work with any webserver... I only tested on IIS 6 and 7.