The August 2015 Scripting Games puzzle was a simple ‘get data from a web service’ request. You had to retrieve data from a given web service
£> Invoke-RestMethod -Uri ‘http://www.telize.com/geoip’ |
Select-Object -Property longitude, latitude, continent_code, timezone
longitude latitude continent_code timezone
——— ——– ————– ——–
-0.13 51.5 EU Europe/London
Apart from the inaccuracy in the continent information – England isn’t part of Europe – its pretty straight forward. The trick is remembering that Invoke-RestMethod exists and selecting out the properties you need.
If you wanted to productionise this you end up with the follwoing function as a minimum
function Get-GeoInformation
{
[CmdletBinding(SupportsShouldProcess=$true)]
param (
[Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[Alias(‘ip’, ‘address’)]
[ValidateScript({([System.Net.IPAddress]::TryParse($_, [ref]’127.0.0.1′)) -eq $true})]
[string[]]$ipaddress
)
BEGIN {} #end begin
PROCESS {
try {
if ($ipaddress) {
foreach ($ip in $ipaddress){
if ($psCmdlet.ShouldProcess("$ip", ‘Retreiving geo-location data’)) {
Write-Verbose -Message "Retrieving data for $ip"
Invoke-RestMethod -Method GET -Uri "http://www.telize.com/geoip/$ip" -ErrorAction Stop
}
} # end foreach ($ip in $ipaddress)
} # end if ($ipaddress)
else {
Write-Verbose -Message ‘Retrieving data’
if ($psCmdlet.ShouldProcess(‘default ip address’, ‘Retreiving geo-location data’)) {
Invoke-RestMethod -Uri ‘http://www.telize.com/geoip’-ErrorAction Stop
}
} #end else
} # end try
catch [System.Net.WebCmdletWebResponseException] {
throw ‘Error connecting to web service’
}
catch {
throw ‘Unresolved error’
} # end catch
} #end process
END {} # end end
<#
.SYNOPSIS
Get-GeoInformation returns data from the geoip web service
at http://www.telize.com/
.DESCRIPTION
Get-GeoInformation returns data from the geoip web service
at http://www.telize.com/
If an IP address is presented to the function that will be sent to
the web service otherwise the current public IP address of the user,
or their ISP, is used.
.PARAMETER ipaddress
IP address to be tested. The IP address will be validated on input
and an error thrown if invalid
.EXAMPLE
£> Get-GeoInformation
longitude : -0.13
latitude : 51.5
asn : AS9105
offset : 1
ip : 88.108.92.247
area_code : 0
continent_code : EU
dma_code : 0
timezone : Europe/London
country_code : GB
isp : Tiscali UK
country : United Kingdom
country_code3 : GBR
No IP address is presented so the user’s public (ISP address) is used
.EXAMPLE
£> Get-GeoInformation -ipaddress 88.108.92.247
longitude : -0.13
latitude : 51.5
asn : AS9105
offset : 1
ip : 88.108.92.247
area_code : 0
continent_code : EU
dma_code : 0
timezone : Europe/London
country_code : GB
isp : Tiscali UK
country : United Kingdom
country_code3 : GBR
An IP address is used
.NOTES
Written in response to the August 2015 Scripting Games puzzle
from PowerShell.org
.LINK
http://www.telize.com
http://powershell.org/wp/2015/08/01/august-2015-scripting-games-puzzle/
#>
}
The function takes one, or more, IP addresses as an optional parameter and after testing its a valid IP address proceeds to call the web service for each IP address.
The –Confirm and –WhatIf parameters are available on the function via the CmdletBinding:
[CmdletBinding(SupportsShouldProcess=$true)]
I’ve also added comment based help.
Its interesting that a single PowerShell pipeline goes to over 100 lines of code when you add in the validation, error handling and other aspects of producing production code