Expired SSL certificates can lead to service disruptions and security vulnerabilities. Staying on top of hundreds or even thousands of certificates is a critical but often difficult job for any IT team. This post provides the solution: a robust and fully-featured PowerShell certificate scanner. This script is created to simplify the process of tracking SSL/TLS expiration dates, giving you the power to scan multiple websites and services, gather critical certificate details, and receive automated reports in a CSV file or via 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
15 Aug 2025: Version 3.0.0: Thanks for Alessandro Tanino for his great contribution in expanding this script with loads of new features. The script now support several parameter, such as:
- Networks: CIDR notation networks
- Port: Primary HTTPS port
- TimeoutSeconds: Connection timeout in seconds
- LDAPS scanning
- DnsServer: Custom DNS server for reverse lookups
- GetOsType: Detect operating system of certificate hosts
use
.\CertificateScanner.ps1 -Examplesfor more information
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
Key Features and Parameter Usage
The updated script, now at version 3, introduces several powerful new features. The script is designed to support different parameter sets, allowing for flexible usage in various scenarios.
Core Scanning Parameters
- -SiteToScan <URL>: Scans a single website or IP address. You can specify a custom port by using the format hostname:port.
- -Networks <CIDR>: Scans a network range using CIDR notation (e.g., “192.168.1.0/24”). Multiple networks can be scanned by separating them with a comma.
- -LoadFromFile <FilePath>: Imports a list of URLs or IP addresses from a text file for a bulk scan.
Network Scan and Protocol Parameters
- -Port <Int>: Specifies the primary HTTPS port to scan (default is 443).
- -AdditionalHTTPSPorts <Array>: Allows you to scan for HTTPS certificates on multiple non-standard ports, in addition to the main -Port.
- -IncludeLDAPS: Expands the scan to include LDAPS certificates on port 636 along with the specified HTTPS ports.
- -LDAPSOnly: Restricts the scan to only check for LDAPS certificates on port 636.
- -ProtocolVersion <String>: Specifies the SSL/TLS version to use for the scan. This is useful for checking certificates on older, legacy systems that don’t support modern protocols like TLS 1.2. Valid options include “Tls12”, “Tls11”, “Tls”, “Ssl3”, or “Default”.
Advanced Information and Discovery
- -GetOsType: Attempts to detect the operating system of the host.
- -DnsServer <String>: A newly added parameter that works with -IncludeReverseDNS. It lets you specify a custom DNS server for all reverse lookup queries, which is crucial for internal networks or specific DNS configurations.
- -IncludeReverseDNS: Performs a reverse DNS lookup for each IP address to find its associated hostname.
Reporting and Filtering
- -ExpiresInDays <Int>: A powerful filter that displays only the certificates that will expire within the specified number of days. Using
0will show only certificates that have already expired. - -SaveAsTo <String>: Saves the scan results to a CSV file. If the filename is prefixed with a
+, the script will append the new results to an existing file, which is perfect for scheduled monitoring tasks. - -EmailSendTo, -EmailFrom, -EmailSMTPServer, etc.: These parameters enable email reporting. The script can send a formatted report of the scan results directly to an email address. You can configure the SMTP server, port, and SSL/TLS settings for secure delivery.
PRO Features
Performance optimization for large networks
- Use –MaxThreads between 10-50 (test optimal value for your network)
- Append mode (+filename) is perfect for scheduled monitoring
.\CertificateScanner.ps1 -Networks "10.0.0.0/16" -ExpiresInDays 0 -SaveAsTo +expired_certs.csv
Practical Examples for the Post
To make the post easy to follow, you should include a new section with practical examples that demonstrate the new features. You can organize these examples by functionality.
Example 1: Basic Scans
- Scan a single website
.\CertificateScanner.ps1 -SiteToScan www.powershellcenter.com
- Scan a specific network range:
.\CertificateScanner.ps1 -Networks "192.168.1.0/24"
- Scan from a list of servers in a file:
.\CertificateScanner.ps1 -LoadFromFile C:\servers\critical_servers.txt
Example 2: Advanced Network Discovery
- Scan a network for certificates, perform OS detection, and use a custom DNS server for hostnames:
.\CertificateScanner.ps1 -Networks "10.0.0.0/16" -GetOsType -IncludeReverseDNS -DnsServer 10.0.0.1 -SaveAsTo C:\reports\network_scan.csv
Example 3: Expiration Monitoring & Automation
- Find all certificates expiring in the next 30 days and append them to a report:
.\CertificateScanner.ps1 -Networks "192.168.1.0/24" -ExpiresInDays 30 -SaveAsTo +C:\reports\expiring_certs.csv
- Find all already expired certificates and send an email alert:
.\CertificateScanner.ps1 -Networks "10.1.1.0/24" -ExpiresInDays 0 -EmailSendTo admin@yourco.com -EmailFrom noreply@scanner.com -EmailSMTPServer mail.yourco.com -EmailSubject "URGENT: Expired Certificates Found"
Example 4: LDAPS Scanning
- Scan a network for both HTTPS and LDAPS certificates:
.\CertificateScanner.ps1 -Networks "192.168.1.0/24" -IncludeLDAPS
- Scan only for LDAPS certificates and save to a file:
.\CertificateScanner.ps1 -Networks "10.2.0.0/24" -LDAPSOnly -SaveAsTo ldaps_certs.csv
- LDAPS expiration monitoring
.\CertificateScanner.ps1 -Networks "10.0.0.0/16" -LDAPSOnly -ExpiresInDays 60 -SaveAsTo ldaps_expiring.csv
- High-speed enterprise scan
.\CertificateScanner.ps1 -Networks "10.0.0.0/8" -MaxThreads 50 -TimeoutSeconds 2 -Port 443 -AdditionalHTTPSPorts 8443,9443
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
It would be great if it could scan ip networks like 10.10.3.0/24 or lists of networks like 10.10.3.0/24, 10.2.3.0/22, 172.24.0.0/16 on lists of ports like 443, 8443