Recently, I needed to review a whole bunch of domains and see if the domain information is up to date. I'm sure there are plenty of ways to do this but seen as there was quite a few (100+) I'd thought I would create a quick and dirty PowerShell script.
There are plenty of APIs about that allow you to query WHOIS information for domains and I just picked one that had a free tier and was straight forward to use. The one that ticked the box was whoisxmlapi.com, you can sign up and get 500 queries a month for free which is fine for my use case.
Once you've signed up you are given an API key that you will need to supply every time you call their API. They can even return the response as XML or JSON.
Making requests are straight forward, just call the following GET method:
whoisxmlapi.com/whoisserver/WhoisService?ap..[[API_KEY]]
&domainName=[[DOMAIN_NAME]]
&outputFormat=JSON
We are specifying JSON as the default output format is XML. You can read the docs here.
Scripting the queries
Basically I want to supply a bunch of domain names and have a nice CSV output with only the information I need. Namely, the default dates and any registrant/contact information.
Annoyingly, the dates can be listed in two places and are in different formats, so a bit parsing is required. No worries, PowerShell to the rescue.
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[String]
$APIKey,
[Parameter(Mandatory = $true)]
[string[]]
$DomainName
)
$responses = @()
$DomainName | ForEach-Object {
$requestUri = "https://www.whoisxmlapi.com/whoisserver/WhoisService?apiKey=$APIKey&domainName=$_&outputFormat=JSON"
$responses += Invoke-RestMethod -Method Get -Uri $requestUri
}
function Get-ValidDate ($Value, $Date) {
$defaultDate = $Value."$($Date)Date"
$normalizedDate = $Value.registryData."$($Date)DateNormalized"
if (![string]::IsNullOrEmpty($defaultDate)) {
return Get-Date $defaultDate
}
return [datetime]::ParseExact($normalizedDate, "yyyy-MM-dd HH:mm:ss UTC", $null)
}
$properties = "domainName", "domainNameExt",
@{N = "createdDate"; E = { Get-ValidDate $_ "created" } },
@{N = "updatedDate"; E = { Get-ValidDate $_ "updated" } },
@{N = "expiresDate"; E = { Get-ValidDate $_ "expires" } },
"registrarName",
"contactEmail",
"estimatedDomainAge",
# @{N = "registrant"; e = { $_.registrant.rawtext } },
@{N = "contact"; e = { ($_.registrant | Select-Object -Property * -ExcludeProperty rawText ).PSObject.Properties.Value -join ", " } }
$whoIsInfo = $responses.WhoisRecord | Select-Object -Property $properties
$whoIsInfo | Export-Csv -NoTypeInformation domain-whois.csv
$whoIsInfo | Format-Table
Save that script to file with a useful name like Get-WhoIsInformation.ps1 and you can call it like so:
.\Get-WhoIsInformation.ps1 -APIKey "API_KEY" - DomainName "DOMAIN"
You can specify multiple domain names by using a string array (e.g. "domain1.com", "domain2.co.uk"). You could even grab your domains from a csv and pass that string array in.
It's not perfect but it will do.