Resolve-Location.ps1
function Resolve-Location { <# .Synopsis Resolves a location to it's place on Earth .Description Looks up physical addresess (in the US), ip addresses, or hostnames. Returns results as a [http://schema.org/Place](http://schema.org/Place) .Example # Resolve Location by GeoIP Resolve-Location -Address "69.89.88.122" .Example # Resolve physical locations within the US Resolve-Location -Address "1600 Pennsylvania Ave, Washington, DC" .Link Get-Web #> [OutputType('http://schema.org/Place')] param( # The physical address or IP address. [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [string] $Address ) begin { if (-not $script:resolvedLocations) { $script:resolvedLocations= @{} } } process { if (-not $script:resolvedLocations[$address]) { #region Cache result if it has not already been retreived $script:resolvedLocations[$address] = if (($address -notlike "* *") -and ($address -as [IPAddress] -or $Address -like "*.*")) { # IpAddress or hostname, lookup on http://freegeoip.net $lookup = Get-Web -Url "http://freegeoip.net/json/$Address" -AsJson if (-not $lookup) { return } $lookup.pstypenames.clear() $lookup.pstypenames.add('http://schema.org/Place') $lookup | Add-Member AliasProperty Country Country_Name -Force -PassThru | Add-Member AliasProperty Locality City -Force -PassThru | Add-Member AliasProperty PostalCode ZipCode -Force -PassThru } else { $safeAddress = [Web.HttpUtility]::UrlEncode($address) $chunks = @($region -split " " -ne "") if ($chunks.Count -gt 1 ) { $postalCode = $chunks[-1] $region = $chunks[0..($chunks.Count -2)] -join " " } # Call geocoder.us to resolve the address, then parse out the Geocoordinates $tr = Get-Web -Url "http://geocoder.us/demo.cgi?address=$safeAddress" -tag tr $rows = $tr | Select-Object -First 2 -Skip 1 | ForEach-Object { $_.Xml.Td} if (-not $rows) { Write-Error "Address could not be resolved" return } # Pick out the pieces of the address $streetAddress, $locality, $region = $Address -split "," # Extract latitude and longitude $lat = $rows[1].innerText -split "[$([Environment]::NewLine)]" | Select-Object -First 1 $long = $rows[3].innerText -split "[$([Environment]::NewLine)]" | Select-Object -First 1 $out = New-Object PSObject | Add-Member NoteProperty StreetAddress "$streetAddress".Trim() -Force -PassThru | Add-Member NoteProperty Locality "$locality".Trim() -Force -PassThru | Add-Member NoteProperty Region "$Region".Trim() -Force -PassThru | Add-Member NoteProperty PostalCode "$postalCode".Trim() -Force -PassThru | Add-Member NoteProperty Latitude ($lat.Trim().TrimEnd("°").Trim() -as [Double]) -Force -PassThru | Add-Member NoteProperty Longitude ($long.Trim().TrimEnd("°").Trim() -as [Double]) -Force -PassThru $out.pstypenames.clear() $out.pstypenames.add('http://schema.org/Place') $out } #endregion Cache result if it has not already been retreived } $script:resolvedLocations[$address] } } |