A lot of organizations have multiple websites and multiple subdomains with an SSL Certificate assigned. Tracking the expiry date for these certificates can be a bit of a challenge. PowerShell can help in reading the certificate details and reporting them to the sysadmin.
In this post, I created a PowerShell script to scan a site list, retrieve the certificate information, and export it to CSV or email.
Table of Contents
Downloading PowerShell Certificate Scanner Script
If you are in a rush, feel free and get the script from my Github repo over here or get by running the following code to get it from the PowerShell Gallery
Install-Script -Name CertificateScanner
Prerequisites
- PowerShell 7 or Windows PowerShell
- Recommend being a local admin on the PC
6 March 2023: Fix SaveAsTo
28 Feb 2024: Version 2
What is PowerShell Certificate Scanner
This PowerShell script scans multiple sites and retrieves the SSL certificate information, mainly:
- URL
- Subject CN
- Issuer
- Issued Date
- Expire Date
- Protocol
The SSL certificate can be on a remote domain or internal domain.
PS7 > .\CertificateScanner.ps1 -FilePath C:\Users\sitelist.txt
or
PS7 > .\CertificateScanner.ps1 -SiteToScan "https://www.mysite.com:8443/"
Now you can scan a website with a custom port
The Full result are as the following
URL : www.cnn.com
StartDate : 20-Apr-21 11:10:07 PM
EndDate : 22-May-22 11:10:06 PM
Issuer : CN=GlobalSign Atlas R3 DV TLS CA 2020, O=GlobalSign nv-sa, C=BE
Subject : CN=*.api.cnn.com
Protocol : Default
URL : 192.168.10.10
StartDate : 07-Mar-16 12:27:35 PM
EndDate : 02-Mar-26 12:27:34 PM
Issuer : O=VMESXI.server.com, C=US, DC=local, DC=vsphere, CN=CA
Subject : C=US, CN=VMESXI.server.com
Protocol : TLS12
URL : www.google.com
StartDate : 29-Nov-21 7:36:34 AM
EndDate : 21-Feb-22 7:36:33 AM
Issuer : CN=GTS CA 1C3, O=Google Trust Services LLC, C=US
Subject : CN=www.google.com
Protocol : Default
Also, and as an option, the script supports running the scan using one of the following protocols: SSLv3, TLS1, TLS1.1, and TLS1.2. This helps to scan sites that are running an old webserver that doesn’t support the latest secure protocols.
The script generates the result and can display it in the console, save it as a CSV ,or send the result by email.
Using the PowerShell certificate scanner
The PowerShell Certificate Scanner require some parameters as shown below
- [Mandatory, String]LoadFromFile: Path for a txt file that include the domains
- [Mandatory, String]SiteToScan: the site name you want to scan
- [Optional, ValidationSet]ProtocolVersion: Select the protocol to connect this include TLS, TLS1.1, TLS1.2 and SSLv3
- [Optional, String]SaveAsTo: Location to save the result to (CSV).
- [Optional, String]EmailSendTo: Send a copy of the report.
- [Optional, String]EmailFrom: The Email Sender
- [Optional, String]EmailSMTPServer: SMTP Server to use for mail relay.
- [Optional, String]EmailSMTPServerPort SMTP Server Port, usually its 25
- [Optional, Switch]EmailSMTPServerSSL: Use SSL for communication
- [Optional, String]EmailSubject: The Message Subject to use.
The LoadFromFile should contain a site list one on each line, the format should be only the site without the https. The script can sanitize the list and clean the list, so if your domain list include the protocol, its OK. Also you can include sites with a custome secure port for example www.google.com:8443.
You cannot use both LoadFromFile and SiteToScan together, only one
NOTE
Showing Results on the screen
Running the script without SaveAsTo shows the result on the screen only. The script can return the result to a variable. For example
$MySite=.\CertificateScanner.ps1 -SiteToScan "https://www.google.com"
Saving the results to a file
You can use the PowerShell certificate scanner to save the result to a file .csv by using the -SaveAsTo
.\CertificateScanner.ps1 -LoadFromFile C:\Users\test.txt -SaveAsTo C:\MyResult.csv
The result shows the certificate expiration dates, issuing date, Subject CN, and the issuer, plus the protocol used to run the scan
Selecting the protocol
You can select the protocol to use during the connection. The available protocols are TLS, TLS1.1, TLS1.2, and SSLv3.
In the example below, the script uses SSLv3 to connect and get the certificate information.
.\CertificateScanner.ps1 -LoadFromFile C:\Users\test.txt -SaveAsTo C:\MyResult.csv -ProtocolVersion Tls
If the site doesn’t support the protocol, the script returns an error.
The Full result are as the following
URL : www.cnn.com
StartDate : 20-Apr-21 11:10:07 PM
EndDate : 22-May-22 11:10:06 PM
Issuer : CN=GlobalSign Atlas R3 DV TLS CA 2020, O=GlobalSign nv-sa, C=BE
Subject : CN=*.api.cnn.com
Protocol : Tls
URL : www.powershellcenter.com
StartDate : Exception calling "AuthenticateAsClient" with "4" argument(s): "Authentication failed, see inner
exception."
EndDate : Maybe Unsupported protocol..
Issuer :
Subject :
Protocol :
As shown in the picture, www.powershellcenter.com doesn’t support TLS1.0.
The protocol scan may be effected by some security devices alone the network route, such as WAF and other security firewall.
Sending Result By email
To receive the result by email, multiple parameters should be provided, In the following example, the script sents the result using a local SMTP server:
.\CertificateScanner.ps1 -LoadFromFile C:\Users\Domainlist.txt -ProtocolVersion Tls -EmailSendTo Recp@domain.com -EmailFrom Sender@domain.com -EmailSMTPServer smtpserver.domain.com -EmailSMTPServerSSL $False -EmailSubject "Scanning Results"
The script requests to authenticate with the mail server, you need to provide a username and password to authenticate, or feel free and remove the authentication part from the script.
To send email using Office365, please refer to How to Send Email with Office 365 Direct Send and PowerShell
Conclusion
This script should help sysadmin in finding the assigned SSL certificate on a website list and provide them with the expiration date, which helps them in replacing these certificates before it gets expired.
Let me know in the comment what do you think about it and how to improve it, surely there is still a lot to do, but for now. hope this helps.
Great content! Keep up the good work!
having an issues with “&” in the script
The ampersand (&) character is not allowed.
Would you please explain more, or show the share the part you got issue with?
thanks for the script. For whatever reason, I’m having issues with the “-SaveAsTo” command line option. It never creates the output file. I’ve tried running the script in Administrator ps console. I’ve tried changing the location to several different files/folders. I’ve tried the path with and without quotes. I’ve even manually created the file first, but the script does not update the file. I’m scratching my head to know why it doesn’t create the output file. Any help on this would be appreciated.
Oh yes.
I will update the code, but for now, you can move the return $Fullresult to the end of the code and that should fix it
Thanks for the script! How can I use it to scan on non-standard SSL ports?
Hi,
I will update the script to include this feature and allow to direct scan a website without having to load from the file.
Hi,
The script is updated and version 2 is ready
you can now scan website from a list with a non-standard SSL port.
Thank You Faris!! Hopefully one day I’ll be as good as you are at PS scripting!
I’ve been testing the script and have noted that it doesn’t send an email and also does not produce a CSV. Any advice on how I can fix it? I’ve been trying but this a bit advanced for me right now.
Thank you for updating the script Faris! I’m having the output file not being created issue. I tried moving the return $Fullresult to the end of the script but still nothing.
Any advice on a fix?
My apologies for my last 2 posts! There’s a long LAG from when I post something and it appearing here. I promise I’m not trying to blow you up!
Hiii,
No worry, actually all comments should be approved by my end, there are alot of spammers.
Anyway, I updated the script.
Get the latest version Install-Script -Name CertificateScanner
The Email should be working now and the Writing to a file also
You can Write to a file and send email together, or list the scanning on the console and send email also.
Hi Faris – this code is great!! I did find that it outputs errors if you have a site with valid DNS but no listener on :443, which might be a nice enhancement to consider.
I’d also love to marry this together with a call out to the http://www.ssllabs.com/ssltest API to report back the current score. I did find a link to a PSUG that had a demo of such code, but not the actual code to play with.
Line |
82 | $stream = $socket.GetStream()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.
Line |
83 | … sslStream = New-Object System.Net.Security.SslStream($stream, $false, …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Exception calling “.ctor” with “3” argument(s): “Value cannot be null. (Parameter ‘innerStream’)”
Line |
84 | … $sslStream.AuthenticateAsClient($URLScanSiteInfo, $null, …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.
Line |
85 | $socket.close()
| ~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.
Hi Paul,
Yes I can consider checking if the endpoint is up or not, this is good.
I will review the SSLlabs API and if possible I will add it as a paramenter.
sometime these provider will provide the API but not for free. anyway, will check it
Thanks for the comment.
Cool, this is the video from the PSUG I mentioned https://www.youtube.com/watch?v=F0uRGdemllo
I received follow error :
S C:\WINDOWS\system32> CertificateScanner.ps1 -SiteToScan “https://www.google.com”
— ERROR –> Não é possível converter o valor “27/05/2024 04:19:06” para o tipo “System.DateTime”. Erro: “Cadeia de caracteres não foi reconhecida como DateTime válido.”
Maybe Unsupported protocol..
URL :
StartDate : Não é possível converter o valor “27/05/2024 04:19:06” para o tipo “System.DateTime”. Erro: “Cadeia de
caracteres não foi reconhecida como DateTime válido.”
EndDate : Maybe Unsupported protocol. Try using -ProtocolVersion Tls12
Issuer :
Subject :
Protocol :
Hi Adriano,
Strange error!!
Are you using the latest version?
I found problem, the computer is behind Internet proxy . thanks for all.
Getting below errror for all Url’s
StartDate : Cannot convert value “24-04-2025 05:29:59” to type “System.DateTime”. Error: “String ’24-04-2025 05:29:59′
was not recognized as a valid DateTime.”
EndDate : Maybe Unsupported protocol. Try using -ProtocolVersion Tls12
Issuer :
Subject :
Protocol :
Did you try to use the -ProtocolVersion Tls12
if we can give an IP Range and few generic port number to scan internal certificates, that will be great.
Thanks for your comment.
So you want the script to accept multiple IP address, scan the generic ports on each IP address.
Give me an example to better understand.
For now try the LoadFromFile and append the port