Dave Herrell - Blog - IT Toolbox - PowerShell Banner

PowerShell Basics: Teams Alerts for Expiring Domain Names

Managing a large number of domain names can be a tedious task, especially when it comes to tracking expiration dates. This PowerShell script automates this process, making it easy to stay on top of your domain renewals.

How it works:

  1. Create a domain list: Prepare a simple text file containing all the domain names you want to monitor.
  2. Set up Microsoft Teams webhook: Configure an incoming webhook URL in your Teams channel to receive alerts.
  3. Run the script: Execute the script, providing the Microsoft Teams webhook URL and the path to your domain list.

The script will:

  • Scan the domain list for expirations within the next 30 days.
  • Send a timely alert to your designated Teams channel for each impending expiration.

Need help with the 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.

Looking to do this with Slack instead?  Check this page out

PowerShell Script

Now that you have your Microsoft 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 your file paths and Teams webhook you setup
$domainFile = "/Users/daveherrell/Desktop/domains.txt"
$webhookUrl = "https://YOURSUPERCOOLTEAMSWEBHOOKURL"

# Function to get expiration details for a domain
function Get-DomainExpirationDetails {
    param (
        [string]$Domain
    )

    try {
        # Get WHOIS data for the domain
        $whoisInfo = whois $Domain | Out-String

        # Parse the registrar information from WHOIS info
        if ($whoisInfo -match "Registrar: (.+)") {
            $registrar = $matches[1].Trim()
        } elseif ($whoisInfo -match "Sponsoring Registrar: (.+)") {
            $registrar = $matches[1].Trim()
        } else {
            $registrar = "Unknown"
        }

        # Parse expiration date based on typical patterns for .org and other domains
        if ($whoisInfo -match "Expiration Date: (\d{4}-\d{2}-\d{2})") {
            $expirationDate = [datetime]::ParseExact($matches[1], "yyyy-MM-dd", $null)
        } elseif ($whoisInfo -match "Registry Expiry Date: (\d{4}-\d{2}-\d{2})") {
            $expirationDate = [datetime]::ParseExact($matches[1], "yyyy-MM-dd", $null)
        } else {
            Write-Host "Could not retrieve expiration date for $Domain" -ForegroundColor Yellow
            return $null
        }

        # Calculate days until expiration
        $daysUntilExpiration = ($expirationDate - (Get-Date)).Days
        return [PSCustomObject]@{
            Domain              = $Domain
            ExpirationDate      = $expirationDate
            DaysUntilExpiration = $daysUntilExpiration
            Registrar           = $registrar
        }
    } catch {
        Write-Host "Error retrieving WHOIS for $Domain" -ForegroundColor Red
        return $null
    }
}

# Initialize list for expiring domains
$expiringDomains = @()

# Read domains from file and get expiration details
foreach ($domain in Get-Content -Path $domainFile) {
    $domain = $domain.Trim()
    if ($domain) {
        $details = Get-DomainExpirationDetails -Domain $domain
        if ($details -and $details.DaysUntilExpiration -le 30) {
            $expiringDomains += $details
        }
    }
}

# Format and send to Microsoft Teams if any domains are expiring soon
if ($expiringDomains.Count -gt 0) {
    $messageText = "**The following domains are expiring within 30 days:**`n"
    foreach ($domain in $expiringDomains) {
        $messageText += "`n**Domain**: $($domain.Domain)`n**Expiration Date:** $($domain.ExpirationDate.ToString('yyyy-MM-dd'))`n**Days Until Expiration:** $($domain.DaysUntilExpiration)`n**Registrar:** $($domain.Registrar)`n"
    }

    # Prepare JSON payload
    $payload = @{
        text = $messageText
    } | ConvertTo-Json -Depth 3

    # Send POST request to Teams webhook
    try {
        Invoke-RestMethod -Uri $webhookUrl -Method Post -Body $payload -ContentType 'application/json'
        Write-Host "Notification sent to Microsoft Teams." -ForegroundColor Green
    } catch {
        Write-Host "Failed to send notification to Microsoft Teams." -ForegroundColor Red
    }
} else {
    Write-Host "No domains expiring within 30 days." -ForegroundColor Cyan
}

				
			

A couple items to note:

  • You can change the date range on line 56 with whatever you wish.  Just make sure it’s in days.  For instance you can set it for 90 days instead of 30 days.
  • Within your TXT file, you can list up to 10 thousand domains 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.  
  • Error Handling: Skips domains without an expiration date or with WHOIS lookup errors.

The Results

Finally you should be able to run your PowerShell Script and receive your alerts.  You should get a similar Microsoft Teams alert:

Domains I knew were expiring were used in this example.

And there you have it.  Simple Alerts to your Teams Channel. 

Hope you find this helpful!