Resolve-ASN.psm1
<#
.SYNOPSIS This script takes as input hostnames or IP addresses, and returns information on the autonomous system associated with the entity. It's a PowerShelly version of whois. .DESCRIPTION This script takes a hostname, resolves it to an IP address, and attempts to identify the autonomous system on the Internet responsible for that address. If an IP address is provided, we us that directly. We return some basic information on the AS like its advertising prefix, locale, and organization. This script relies on the IP-to-ASN mapping service provided by Team Cymru, which provides fairly good ASN data through DNS. Proper whois would actually use a whois server and the whois protocol, but its much easier to use a DNS service. .PARAMETER HostName The hostname used to gather ASN information. .PARAMETER IPAddress The IP address used to gather ASN information .PARAMETER IPv4Only This parameter indicates that ASN information should be returned only for IPv4 addresses. By default a random address for the host name is used. .PARAMETER IPv6Only This parameter indicates that ASN information should be returned only for IPv6 addresses.By default a random address for the host name is used. .INPUTS None .OUTPUTS The script outputs a System.Object for each AS that is declared as an owner of the specified host. .EXAMPLE .\Resolve-ASN.ps1 bing.com IPAddress : 65.52.107.149 ASNumber : 8075 ASPrefix : 65.52.104.0/21 Locale : US Description : MICROSOFT-CORP---MSN-AS-BLOCK - Microsoft Corp .EXAMPLE Get-NetIPAddress -IPAddress 2001* | .\Resolve-ASN.ps1 IPAddress : 2001:4898:0:fff:200:5efe:157.59.25.188 ASNumber : 3598 ASPrefix : 2001:4898::/32 Locale : US Description : MICROSOFT-CORP-AS - Microsoft Corp .EXAMPLE .\Resolve-ASN.ps1 xbox.com -IPv6Only IPAddress : 2a01:111:f009::3b03 ASNumber : 8075 ASPrefix : 2a01:111::/32 Locale : GB Description : MICROSOFT-CORP---MSN-AS-BLOCK - Microsoft Corp .NOTES Requires Windows 8 or later. .LINK The DNS service used for the script: http://www.team-cymru.org/Services/ip-to-asn.html The cmdlet that does all the hard work: Resolve-DNSName #> function Resolve-ASN{ param ( [Parameter(ParameterSetName="HostName",Mandatory=$True, ValueFromPipelineByPropertyName=$True , Position=0)] [string]$HostName = $null, [Parameter(ParameterSetName="IPAddress", Mandatory=$True, ValueFromPipelineByPropertyName=$True)] [ipaddress]$IPAddress=$null, [Parameter(ParameterSetName="HostName", Mandatory=$false, ValueFromPipelineByPropertyName=$True)] [switch]$IPv4Only=$false, [Parameter(ParameterSetName="HostName", Mandatory=$false, ValueFromPipelineByPropertyName=$True)] [switch]$IPv6Only=$false ) ##Services we're getting the ASN information from. $OriginService= ".origin.asn.cymru.com" $ASNService = ".asn.cymru.com" ##Convert the supplied hostname into a set of IP addresses. if($IPAddress -eq $null) { write-debug "Hostname provided, will have to resolve to DNS name" try{ if($IPv4Only) {$Records = Resolve-DnsName $HostName -Type A -erroraction Stop} if($IPv6Only) {$Records = Resolve-DnsName $HostName -Type AAAA -erroraction Stop} if(!($IPv4Only -or $IPv6Only)) {$Records = Resolve-DnsName $HostName -Type A_AAAA -erroraction Stop} } catch{ throw "Could not resolve the provided hostname" exit } $Records = $Records | where {$_.IPAddress -ne $null} if ($Records -eq $null) { throw "No records found for the provided hostname" exit } else { $IPAddress = $Records[0].IPAddress } write-debug "Hostname resolved" } $IPAddressCasted = $null ##Check if its an IPv6 Address. If so, we need to reverse the characters of the IP address if($IPAddress.AddressFamily -eq "InterNetworkV6") { $OriginService= "origin6.asn.cymru.com" $IPString = $IPAddress.IPAddressToString ##We're going to do some URI magic because it'll make our string conversions easier. $x = new-object -TypeName System.Uri -ArgumentList "http://[$IPString]" $ExpandedString = $x.DnsSafeHost $ExpandedString = $ExpandedString.ToCharArray() $ReversedString = "" foreach($character in $ExpandedString) { if($character -ne ":") { $ReversedString = $ReversedString.Insert(0,"$character.") } } $IPAddressCasted = $ReversedString } else { ##Little bit easier to do reverse DNS lookups with IPv4 if($IPAddressCasted -eq $null) {$IPAddressCasted = $IPAddress.ToString()} $Octets = $IPAddressCasted.Split(".") $Reversed = "" foreach ($Octet in $Octets) { $Reversed = "." + $Reversed.Insert(0,$Octet) } $IPAddressCasted = $Reversed.Substring(1) } ##Resolve the name against the ASN-IP service $NameToResolve = $IPAddressCasted + $OriginService try{ write-Debug "START. Name to resolve against ASN-IP service" write-Debug $NameToResolve write-Debug "END." $DNSRecords = Resolve-DnsName $NameToResolve -Type TXT -ErrorAction Stop } catch{ throw "Could not find AS information for $NameToResolve" exit } ##Each record represent an ASN. We're going to populate more information on each object before returning them. ##This loop also generates the objects we'll be returning #foreach ($Record in $DNSRecords) #{ $Record = $DNSRecords[0] write-Debug "START. Print the record." write-debug $Record write-Debug "END. Record is printed." $Result = New-Object System.Object $Result | Add-Member -Type NoteProperty -Name IPAddress -Value $IPAddress Write-Debug -Message what $Result | Add-Member -Type NoteProperty -Name ASNumber -Value $Record.Strings.Split("|")[0].Trim() $Result | Add-Member -Type NoteProperty -Name ASPrefix -Value $Record.Strings.Split("|")[1].Trim() $Result | Add-Member -Type NoteProperty -Name Locale -Value $Record.Strings.Split("|")[2].Trim() $NameToResolve = "AS" +$Result.ASNumber + $ASNService Write-Debug $NameToResolve try{ $DNSRecord = Resolve-DnsName $NameToResolve -Type TXT } catch{ throw "Could not resolve detailed infromation for AS" +$Result.ASNumber exit } $Result | Add-Member -Type NoteProperty -Name Description -Value $DNSRecord.Strings.Split("|")[4].Trim() $Result #} } export-modulemember -function Resolve-ASN |