Last active
December 6, 2020 23:55
-
-
Save dindoliboon/32d9aa78842d33359c5ce624c570ca96 to your computer and use it in GitHub Desktop.
PowerShell library for performing geo IP lookups.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
PowerShell library for performing geo IP lookups. | |
Requirements: | |
- PowerShell 7.0.0 or Windows PowerShell 5.1.18362.628 | |
https://github.com/PowerShell/PowerShell/releases | |
- nuget 5.4.0.6315 | |
Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -OutFile (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\nuget.exe') | |
- MaxMind.DB 2.6.1 nuget package | |
Install the nuget package on Windows: | |
& (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\nuget.exe') Install MaxMind.Db -Version 2.6.1 -OutputDirectory (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\.nuget') | |
Install the nuget package on macOS with mono: | |
& mono (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\nuget.exe') Install MaxMind.Db -Version 2.6.1 -OutputDirectory (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\.nuget') | |
- GeoLite2 City and Country binary databases | |
Requires free registration to download. | |
https://www.maxmind.com | |
Installation: | |
- You may need to change your execution policy to import unsigned modules. | |
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser | |
- Download the module: | |
Invoke-WebRequest -Uri 'https://gist.githubusercontent.com/dindoliboon/32d9aa78842d33359c5ce624c570ca96/raw/libMaxMindGeoIp2V1.psm1' -OutFile (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\libMaxMindGeoIp2V1.psm1') | |
- Import the module: | |
Import-Module -Name (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\libMaxMindGeoIp2V1.psm1') | |
#> | |
New-Module -Name libMaxMindGeoIp2V1 -ScriptBlock { | |
function New-GeoIp2Reader { | |
param ( | |
$Library, | |
$Database | |
) | |
Add-Type -Path $Library | Out-Null | |
return [MaxMind.Db.Reader]::new($Database) | |
} | |
function Close-GeoIp2Reader { | |
param ( | |
[ref]$Reader | |
) | |
$Reader.Value.Dispose() | |
$Reader.Value = $null | |
} | |
function Find-GeoIp2 { | |
param ( | |
$Reader, | |
$IpAddress, | |
$Library, | |
$Database | |
) | |
$results = $null | |
$useInternalReader = $Reader -eq $null -and $Library -ne $null -and $Database -ne $null | |
$ip = [System.Net.IPAddress]$IpAddress | |
if ($useInternalReader) { | |
$Reader = New-GeoIp2Reader -Library $Library -Database $Database | |
} | |
if ($Reader) { | |
# Use the first Find method and tell it to return type Dictionary<string, object>. | |
$oldMethod = ($Reader.GetType().GetMethods() |? {$_.Name -eq 'Find'})[0] | |
$newMethod = $oldMethod.MakeGenericMethod(@([System.Collections.Generic.Dictionary`2[System.String,System.Object]])) | |
# Call our new method, T Find[T](ipaddress ipAddress, MaxMind.Db.InjectableValues injectables) | |
$results = $newMethod.Invoke($Reader, @($ip, $null)) | |
if ($useInternalReader) { | |
Close-GeoIp2Reader -Reader ([ref]$Reader) | |
} | |
} | |
else { | |
throw 'MaxMind.Db.Reader not defined.' | |
} | |
return $results | |
} | |
Export-ModuleMember -Function 'New-GeoIp2Reader', 'Find-GeoIp2', 'Close-GeoIp2Reader' | |
} |
Author
dindoliboon
commented
Jul 13, 2018
•
# Perform an IP lookup of multiple IPs using the country database.
# Database reader is kept open until manually closed.
Import-Module -Name (Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\libMaxMindGeoIp2V1.psm1')
if ($PSVersionTable.PSEdition -eq 'Desktop') {
$maxMindDbDll = Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath '.nuget\packages\maxmind.db\2.6.1\lib\net45\MaxMind.Db.dll'
} else {
$maxMindDbDll = Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath '.nuget\packages\maxmind.db\2.6.1\lib\netstandard2.1\MaxMind.Db.dll'
}
$ipDbCountry = Join-Path -Path ([Environment]::GetFolderPath('UserProfile')) -ChildPath 'Downloads\GeoLite2-Country_20200317\GeoLite2-Country.mmdb'
$reader = New-GeoIp2Reader -Library $maxMindDbDll -Database $ipDbCountry
Find-GeoIp2 -Reader $reader -IpAddress '8.8.8.8' | ConvertTo-Json -Depth 5
Find-GeoIp2 -Reader $reader -IpAddress '8.8.4.4' | ConvertTo-Json -Depth 5
Find-GeoIp2 -Reader $reader -IpAddress '1.2.3.4' | ConvertTo-Json -Depth 5
Close-GeoIp2Reader -Reader ([ref]$reader)
Hello,
Thanks for sharing the code.
I have one question.
There may be an error when adding a dll through add-type.
Add-Type : Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
At line:5 char:1
- Add-Type -Path $ Library
-
+ CategoryInfo : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException + FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeCommand
Some servers work fine, but some servers get errors I can't find the difference.
So instead of add-type I use [System.Reflection.Assembly]::LoadFrom($Library)
I've tried it, but I get an error in the return [MaxMind.Db.Reader]::new($database) part.
The problem occurs only in the powershell-core version or running powershell as an administrator account.
Any problems can you help me?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment