Search code examples
powershellipipv6ip2location

How to convert IP number to IPV6 using PowerShell?


I have CSV containing IP number's related to IPv6 and I am reading and converting them to IPv6 ip address which is failing at the moment.

I am using below code but getting error:

Cannot convert value "281470698520576" to type "System.Net.IPAddress". Error: "Specified argument was out of the range of valid values.

function Convert-NumberToIP
{
    param(
        [Parameter(Mandatory=$true)][string]$number
    )

    [Int64] $numberInt = 0
    
    if([Int64]::TryParse($number, [ref]$numberInt))
    {
        if(($numberInt -ge 0) -and ($numberInt -le 0xFFFFFFFFl))
        {
            #([IPAddress] $numberInt).ToString()
            $ipBytes = ([IPAddress]$numberInt).GetAddressBytes()
            [array]::Reverse($ipBytes)
            ([IPAddress]$ipBytes).IPAddressToString
        }
    }
}

$startIP = Convert-NumberToIP -number '281470698520576'
$endIP = Convert-NumberToIP -number '281470698520580'

Solution

  • To use a 128bit integer in PowerShell you can leverage .NET System.Numerics.BigInteger class. Like this:

    $ipv6Decimal = [System.Numerics.BigInteger]::Parse($number)

    Then you can convert the BigInt to a byte array using ToByteArray(). However the resulting array needs to be "padded" to 16 bytes and reversed (Host vs Network order).

    This works for me:

    function Convert-NumberToIPv6
    {
        param(
            [Parameter(Mandatory=$true)][string]$number
        )
         
        $ipv6Decimal  = [System.Numerics.BigInteger]::Parse($number)
        $ipv6Bytes = $ipv6Decimal.ToByteArray()
        # pad to 16 bytes
        [Array]::Resize([ref]$ipv6Bytes, 16)
    
        # reverse the bytes
        [Array]::Reverse($ipv6Bytes)
        
        # provide a scope identifier to prevent "cannot find overload error"
        $ipAddress = New-Object Net.IPAddress($ipv6Bytes, 0)
        $ipAddress.ToString()
    }
    

    So the output for: Convert-NumberToIPv6 -number '281470698520576' is ::ffff:1.0.0.0