Resolve-Location
Looks up physical addresess (in the US), ip addresses, or hostnames. Returns results as a http://schema.org/Place

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]            
                    
    }            
            
}