Skip to content

Instantly share code, notes, and snippets.

@indented-automation
Last active October 4, 2021 18:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save indented-automation/f059a269d55a1a3051e782ad1aba56d9 to your computer and use it in GitHub Desktop.
Save indented-automation/f059a269d55a1a3051e782ad1aba56d9 to your computer and use it in GitHub Desktop.
function Get-WhoIs {
<#
.SYNOPSIS
Get a WhoIs record using servers published via whois-servers.net.
.DESCRIPTION
For IP lookups, Get-WhoIs uses whois.arin.net as a starting point, chasing referrals within the record to get to an authoritative answer.
For name lookups, Get-WhoIs uses the whois-servers.net service to attempt to locate a whois server for the top level domain (TLD).
Get-WhoIs connects directly to whois servers using TCP/43.
.INPUTS
System.String
.EXAMPLE
Get-WhoIs indented.co.uk
.EXAMPLE
Get-WhoIs 10.0.0.1
#>
[CmdletBinding()]
[OutputType([String])]
param (
# The name or IP address to locate the WhoIs record for.
[Parameter(Mandatory, ValueFromPipeline)]
[String]$Name,
# A WhoIs server to use for the query. Discovered, but can be overridden.
[String]$WhoIsServer,
# A command to execute on the WhoIs server if the server requires a command prefixing before the query.
[String]$Command
)
process {
if (-not $WhoIsServer) {
if ([IPAddress]::TryParse($Name, [Ref]$null) -or $Name.EndsWith("arpa")) {
$WhoIsServer = $whoIsServerName = "whois.arin.net"
$Command = "n "
} else {
$WhoIsServer = $whoIsServerName = '{0}.whois-servers.net' -f $Name.Split('.')[-1]
}
}
if (-not ([IPAddress]::TryParse($WhoIsServer, [Ref]$null))) {
$whoIsServerRecord = [System.Net.Dns]::GetHostEntry($WhoIsServer) |
Select-Object -Expand AddressList |
Select-Object -First 1
$WhoIsServer = $whoIsServerRecord
}
if ($WhoIsServer) {
Write-Debug ('Get-WhoIs: Asking {0} ({1}) for {2} using command {3}{4}' -f $whoIsServerName, $WhoIsServer, $Name, $Command, $Name)
$socket = [System.Net.Sockets.Socket]::new('Stream', 'Tcp')
try {
$socket.Connect($WhoIsServer, 43)
} catch [System.Net.Sockets.SocketException] {
$errorRecord = [System.Management.Automation.ErrorRecord]::new(
[System.Net.Sockets.SocketException]::new($_.Exception.InnerException.NativeErrorCode),
'ConnectionFailed',
[System.Management.Automation.ErrorCategory]::ConnectionError,
$WhoIsServer
)
Write-Error -ErrorRecord $errorRecord
}
[Byte[]]$buffer = [System.Text.Encoding]::UTF8.GetBytes("$Command$Name`r`n")
$null = $socket.Send($buffer)
$receivedBytes = do {
$buffer = [Byte[]]::new(4096)
$receivedCount = $socket.Receive($buffer)
if ($receivedCount -gt 0) {
[Array]::Resize([Ref]$buffer, $receivedCount - 1)
$buffer
}
Write-Debug ('Get-WhoIs: Received {0} bytes from {1}' -f $receivedCount, $socket.RemoteEndPoint.Address)
} until ($receivedCount -eq 0)
$socket.Close()
$whoIsRecord = [System.Text.Encoding]::UTF8.GetString($receivedBytes)
if ($whoIsRecord -match 'ReferralServer: whois://(.+):') {
Write-Debug ('Get-WhoIs: Following referral for {0} to {1}' -f $Name, $matches[1])
Get-WhoIs $Name -WhoIsServer $matches[1]
} else {
$whoIsRecord
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment