Powershell GEOIP Lookup using IPWhois.io

Sometimes, you want to look at a bunch of IPs and figure out where they are coming from. It could be firewall logs, maybe some web host logs. This script was originally developed for a very specific use case, it takes a bunch of IPs in a CSV (with a column header of ‘IP’) and uses a service from https://ipwhois.io/ to pull back details of those IPs.

There are a few variables to set, $prousage which can be set to $true or $false and $apikey which is required if you are using the premium service. (The free service gives you 10000 lookups a month). $showmap which can be set to $true or $false and requires a google maps API key in $googleapikey for static maps.

This prompts for a CSV file, and when complete prompts you where to save the output CSV file

#########################################################
#       Script to get information for IP addresses      #
#########################################################
function Get-MyDate {
    
    return "{0:dd-MM-yy}" -f (Get-Date)
    
}
function Get-TimeStamp {
    
    return "{0:dd-MM-yy}-{0:HH:mm:ss}" -f (Get-Date)
    
}
Function Get-FileName($initialDirectory)
{   
  [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
  Out-Null
    $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
  $SaveFileDialog.initialDirectory = $initialDirectory
  $SaveFileDialog.filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*"
  $SaveFileDialog.ShowDialog() | Out-Null
  $SaveFileDialog.filename
}

clear-host
##########################
# Put your api key here: #
##########################
$prousage = $true
$apikey = "YOURAPIKEY"
# you need a goole maps API key for a static map, sign up here https://developers.google.com/maps/documentation/maps-static/start
$showmap = $true
$googleapikey = "GOOGLEAPIKEY"

write-host "`n"
write-host "`n"
write-host "`n"
write-host "`n"
write-host "`n"
write-host "`n"
Write-host "
 _____  _____       _______ _     _ _______ _______ _     _ _______  ______
   |   |_____]      |       |_____| |______ |       |____/  |______ |_____/
 __|__ |            |_____  |     | |______ |_____  |    \_ |______ |    \_
                                                                           
"
$ipdetails=@{}
$collection=@()


$g=1
############################################################
#    Lets get the list of IPS from a CSV file, heading IP  #
############################################################
# Prompt for the csv file
Add-Type -AssemblyName System.Windows.Forms
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{InitialDirectory = [Environment]::GetFolderPath('Desktop') 
    Filter = 'Spreadsheets (*.csv)|*.csv'
    Title = 'Select input file'
}
$null = $FileBrowser.ShowDialog()

$infile = $FileBrowser.FileName
$results = import-csv -path $infile

##########################################################
#    Now go through the results and look up the details  #
##########################################################
foreach ($result in $results)
{
    $log = ($result.message -replace "`0", " ")
    #($log | convertfrom-json).detail
    $ip = $result.ip

    $gpct = [math]::Round((100/($results | measure-object).count) * $g,2)
    Write-Progress -Id 2 -Activity "Working on IP" -status "$gpct% Complete:" -PercentComplete $gpct -CurrentOperation $ip
    if ($prousage -eq $true){
            $uri = "https://ipwhois.pro/json/" + $ip + "?key=" + $apikey
        }
        else
        {
            $uri = "https://ipwhois.app/json/" + $ip
        }
    $location = Invoke-RestMethod -uri $uri
    if($location.success -eq $false){
        write-host "API Limit Hit, exiting" -ForegroundColor Red
        Start-Sleep -Seconds 10
        exit
    }
    $country=$location.country_code
    
      
    $ipdetails.country = $country
    $ipdetails.city = $location.city
    $ipdetails.region = $location.region
    $ipdetails.ipaddress = $ip
    $ipdetails.organisation = $location.org
    $ipdetails.isp = $location.isp
    $ipdetails.lat = $location.latitude
    $ipdetails.long = $location.longitude
    $collection += New-Object psobject -Property $ipdetails
    $G++
}



#####################################################
#    Export a CSV of offenders for good measure     #
#####################################################
$outfile = Get-Filename -initialdirectory $env:UserProfile\Desktop

if("" -eq $outfile){
    Write-host "No File selected, aborting" -ForegroundColor red
    start-sleep -s 5
    exit
}
   $collection | export-csv $outfile -NoTypeInformation
Write-host "
 _______ _____ __   _ _____ _______ _     _ _______ ______ 
 |______   |   | \  |   |   |______ |_____| |______ |     \
 |       __|__ |  \_| __|__ ______| |     | |______ |_____/
                                                           
" -ForegroundColor Green
#####################################################
# Lets Plot them on a Map - needs a google API Key  #  
#####################################################

if($showmap -eq $true){

    $BaseGoogleMapsURL = "https://maps.googleapis.com/maps/api/staticmap?scale=2&size=640x400&maptype=hybrid "
    $FinalURL = $BaseGoogleMapsURL
    $Region = "GB"
    foreach ($item in $collection)
    {
        $Lat = $item.lat
        $Lon = $item.long
        $magnitude=1

        $MarkerURL = "&markers=color:blue%7Clabel:S%7C$Lat,$Lon"
        $FinalURL = $FinalURL + $MarkerURL 
    }
    $FinalURL = $FinalURL + "&key=" + $googleapikey
    if($FinalURL.Length -ge 8192){
        write-host "URL is over reccomended max lenght, errors may occur" -ForegroundColor Magenta
        Start-Process $FinalURL
    }else
    {
        Start-Process $FinalURL
    }
}

Example Map

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.