ChatGPT has become my new programming partner. I tried many variations of .net code to read host bindings from IIS and then run a WHOIS service to get expiration dates, including C# code. Nothing worked and I got very tired of the process. To be clear, it takes knowledge of programming and architecture to get CHATGPT to create the code base you want.
So I ran APPCMD from a command prompt and found that the easiest way to get the bindings. Then I prompted CHATGPT to create various Powershell functions to read the root domain and get the registrar and expiration date for each domain. I then instructed CHATGPT to write code to create a CSV file sorted by expiration date and write out the domain, expiration date, and name of the Registrar. D:\sites.xml and D:\domain_expiration.csv are hard coded in the powershell script. The powershell script also uses the whois service which took several prompts to get CHATGPT to tell me how to install it.
Start with this appcmd
appcmd list sites /xml >d:\sites.xml
Many of us don’t use PowerShell very often and often forget how to run it. I use the developer version of powershell for visual studio 2022.
I ran these commands directly with just a cut and paste. You first need to install the whois utility using the Chocolatey package manager.
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) choco install whois
Here’s the powershell script to run. To run this script I copied the script below into a file called ExpirationDates.ps1. To run the file from PowerShell
./ExpirationDates.ps1
The output again is D:\domain_expiration.csv
Here’s the complete script.
function Get-RootDomain { param ( [Parameter(Mandatory = $true)] [string]$Domain ) if ([string]::IsNullOrWhiteSpace($Domain)) { return "" } $rootDomain = $Domain -replace "^.*?(([^.]+)\.[^.]+)$", '$1' return $rootDomain } function Get-DomainExpirationDate { param ( [Parameter(Mandatory = $true)] [string]$Domain ) $whoisResponse = whois $Domain 2>$null #Write-Host $whoisResponse $expiryPatterns = @( "(?m)Registry Expiry Date:(.+)", "(?m)Registrar Registration Expiration Date:(.+)", "(?m)Expiration Date:(.+)", "(?m)Renewal Date:(.+)" ) $expirationDate = $null foreach ($pattern in $expiryPatterns) { $match = [regex]::Match($whoisResponse, $pattern) if ($match.Success) { $expirationString = $match.Groups[1].Value.Trim() # Extract the date portion from the expiration string $datePattern = "\d{4}-\d{2}-\d{2}" $dateMatch = [regex]::Match($expirationString, $datePattern) if ($dateMatch.Success) { $expirationDate = $dateMatch.Value } break } } #$registrationPattern = "(?m)Registrar:(.+)" # $registrationMatch = [regex]::Match($whoisResponse, $registrationPattern) # if ($registrationMatch.Success) { # $registrationCompany = $registrationMatch.Groups[1].Value.Trim() # } $registrationCompanyPattern = "(?m)Registrar:\s*([\s\S]*?Registrar)" $registrationCompanyMatch = [regex]::Match($whoisResponse, $registrationCompanyPattern) $registrationCompany = "" if ($registrationCompanyMatch.Success) { $registrationCompany = $registrationCompanyMatch.Groups[1].Value.Trim() } $result = [PSCustomObject]@{ Domain = $Domain ExpirationDate = $expirationDate RegistrationCompany = $registrationCompany } return $result #return $expirationDate } $xmlPath = "D:\sites.xml" $outputPath = "D:\domain_expiration.csv" # Read XML from the file $xmlContent = Get-Content $xmlPath -Raw # Load XML content $xml = $xmlContent # Get the SITE nodes $sites = $xml.SelectNodes("//SITE") # Create an array to store the domain names $domainArray = @() # Loop through each SITE node foreach ($site in $sites) { $bindings = $site.GetAttribute("bindings") # Extract the domain names from the bindings attribute $domainNames = $bindings -split "," foreach ($domainName in $domainNames) { $domain = ($domainName -split ":")[2].Trim() #$domain = ($domain -split "\.")[1..($domain -split "\.").Length] -join "." #$domain = $domain -replace ".*?\.", "" #$domain = $domain -replace ".*?(\w+\.\w+)$", '$1' #$domain = $domain -replace ".*?((?:[\w-]+\.)+[\w-]+)$", '$1' if (![string]::IsNullOrWhiteSpace($domain)) { $rootDomain = Get-RootDomain -Domain $domain if (![string]::IsNullOrWhiteSpace($rootDomain) -and $domainArray -notcontains $rootDomain) { Write-Host $domain + ":" + $rootDomain $domainArray += $rootDomain } } } } $domainArray = $domainArray | Select-Object -Unique # Create an array to store the domain name and expiration date $domainExpirationArray = @() # Loop through each domain and retrieve the expiration date foreach ($domain in $domainArray) { $expirationDate = Get-DomainExpirationDate -Domain $domain $domainExpirationArray += [PSCustomObject]@{ Domain = $domain ExpirationDate = $expirationDate.ExpirationDate RegistrationCompany=$expirationDate.RegistrationCompany } } $domainExpirationArray = $domainExpirationArray | Sort-Object -Property ExpirationDate, Domain, RegistrationCompany # Export the domain name and expiration date to a CSV file $domainExpirationArray | Export-Csv -Path $outputPath -NoTypeInformation Write-Host "CSV file generated: $outputPath"