
PowerShell: Send SSL Cert Expirations to Teams
If your organization uses SSL certificates for servers and websites, manually tracking their expiration dates can be time-consuming. This PowerShell script automates this process by:
- Reading a list of URLs from a text file.
- Validating each SSL certificate’s issuer and expiration date.
- Sending alerts to a specified Microsoft Teams channel for certificates nearing expiration (within a customizable timeframe).
Note: Most registrars won’t renew SSL certs more than 30 days before they expire.
Need help with the Microsoft Teams webhook setup? I’ve included a brief guide below to get you started.
Create Microsoft Teams Webhook
If you haven’t already, create a Teams channel to host your domain alerts. Click the there *** (dots) on the name of the channel and choose Manage channel.
If not already expanded, expand the area under Connectors. Choose Edit.
Search for Incoming Webhook if the connector isnt already showing in your options. Click Configure.
Create your webhook name, and upload an image (optional) for your webhook and click Create.
Last thing you need to do is copy the Webhook URL. You will need this for the PowerShell script. Click the X button to close the pop-up.
PowerShell Script
Now that you have your Teams Webhook URL, it’s time to setup your alert script. Below is the script you can copy. Make sure you update the .txt file path and Webhook URL with your own information.
# Define the path to your the URL file
$urlsFile = "/Users/daveherrell/Desktop/urls.txt"
# Make sure you define the Teams Webhook URL
$teamsWebhookUrl = "YOUR TEAMS URL GOES HERE"
# Set the number of days to check for certificate expiration
$warningDays = 30
# Function to fetch SSL certificate information
function Get-SSLCertificateInfo {
param (
[string]$url
)
try {
$uri = New-Object System.Uri($url)
$tcpClient = New-Object System.Net.Sockets.TcpClient
$tcpClient.Connect($uri.Host, 443)
$sslStream = New-Object System.Net.Security.SslStream($tcpClient.GetStream(), $false, ({ $true }))
$sslStream.AuthenticateAsClient($uri.Host)
$cert = $sslStream.RemoteCertificate
$cert2 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert
$tcpClient.Close()
return @{
Url = $url
Issuer = $cert2.Issuer
NotAfter = $cert2.NotAfter
Registrar = $cert2.GetNameInfo([System.Security.Cryptography.X509Certificates.X509NameType]::DnsName, $false)
IsValid = $cert2.Verify()
}
} catch {
Write-Output "Failed to fetch certificate for $url"
return $null
}
}
# Function to send notification to Microsoft Teams
function Send-TeamsNotification {
param (
[string]$message
)
$payload = @{
"@type" = "MessageCard"
"@context" = "http://schema.org/extensions"
"summary" = "SSL Certificate Expiry Alert"
"themeColor" = "FF0000"
"title" = "SSL Certificate Expiry Alert"
"text" = $message
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri $teamsWebhookUrl -Method Post -ContentType 'application/json' -Body $payload
if ($response.StatusCode -ne 200) {
Write-Output "Failed to send Teams message: $($response.StatusCode), $($response.Content)"
}
}
# Read URLs from file
if (Test-Path $urlsFile) {
$urls = Get-Content -Path $urlsFile
foreach ($url in $urls) {
$certInfo = Get-SSLCertificateInfo -url $url
if ($certInfo -ne $null -and $certInfo.IsValid) {
$daysToExpire = ($certInfo.NotAfter - (Get-Date)).Days
if ($daysToExpire -le $warningDays) {
$message = "SSL Certificate for $($certInfo.Url) issued by $($certInfo.Issuer) (Registrar: $($certInfo.Registrar)) will expire in $daysToExpire days on $($certInfo.NotAfter)."
Send-TeamsNotification -message $message
Write-Output $message
}
} else {
Write-Output "Invalid certificate for $url or unable to retrieve certificate."
}
}
} else {
Write-Output "URLs file not found at $urlsFile"
}
A couple items to note:
- You can change the date range on line 8 with whatever you wish. Just make sure it’s in days. For instance you can set it for 30 days instead of 90 days.
- Within your TXT file, you can list up to five hundred URLs before this breaks. However, make sure the file only contains one domain per line!
- You can easily set this script to run via Scheduled task on Windows server.
- Even if the url in the txt file is no longer available, the script will still run.
Categories
Recent Posts
- PowerShell: How to Add an Alias to Every Users Mailbox and Groups in Microsoft 365
- Slack: Disable Entra ID User using a slash command.
- Slack: Retrieve Entra ID (MS365) User Information with a slash command.
- Jira Cloud: Disabling Entra ID User Accounts via Automation and Microsoft Runbook
- Jira Cloud: Restart an Azure VM using JSM Assets and Automation