Mario Stoilov
Mario Stoilov

Reputation: 3447

How to use New-NetRoute without specifying the InterfaceIndex?

As you know, we can set up routing in Windows via

route add xxx.xxx.xxx.xxx mask yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz

and the OS decides which interface to use. Now, I want to do this in PowerShell with the command

New-NetRoute –DestinationPrefix "xxx.xxx.xxx.xxx/yy" –InterfaceIndex w –NextHop zzz.zzz.zzz.zzz

The problem here is that InterfaceIndex is mandatory here, but I want the OS to figure this out itself (as it does in the first command). How can I do this?

Upvotes: 2

Views: 8856

Answers (2)

Vesper
Vesper

Reputation: 18747

You can use Get-NetIPAddress to get your IP addresses along with the InterfaceIndex property that you can then pipe into New-NetRoute. You'll have to query if the (ip_address & subnet_mask) is equal to your (z.z.z.zz & subnet_mask). A sample function will look like this:

function Add-NetRouteByDestination {
    param ([String]$destinationPrefix,[System.Net.IPAddress][ValidateNotNullOrEmpty()] $nextHop)
    $isipv6=$nextHop.AddressFamily -eq "InterNetworkV6" # thanks to type conversion
    if ($isipv6) {
        $af="IPv6"
    } else {
        $af="IPv4"
    } # address family filter
    # destination is expected to be "blabla/prefix", get prefix
    $ips=Get-NetIPAddress -AddressFamily $af
    $nhbytes=$nexthop.GetAddressBytes()
    $ifindex=0
    foreach ($ip in $ips) {
        $ipbytes=$ip.GetAddressBytes()
        $tmlen=$ip.prefixlength
        $matched=$true
        $index=0
        while ($tmlen -gt 0 -and $matched) {
            $b1=$ipbytes[$index]
            $b2=$nhbytes[$index]
            if ($tmlen -lt 8) {
                $bytemask=[byte](0,128,192,224,240,248,252,254)[$tmlen]
                $b1 = [byte]($b1 -band $bytemask)
                $b2 = [byte]($b2 -band $bytemask)
            }
            $matched=$b1 -eq $b2
            $index+=1
            $tmlen-=8
        } # a very stupid bitwise comparation
        if ($matched} { 
            $ifindex=$ip.interfaceindex 
            New-NetRoute –DestinationPrefix $destinationPrefix –InterfaceIndex $ifindex –NextHop $nextHop -ea stop
        } # this one matches gateway vs ip&mask, setting route
    }
}

Warning, the code is not tested and might contain typos. This code should work if there's no Find-NetRoute cmdlet available (Windows 8.0, Windows Server 2012).

Upvotes: 0

Matt
Matt

Reputation: 46730

Never played with it myself but there is a cmdlet that does serve the purpose of what you are looking for. It is called Find-NetRoute and it finds the best local IP address and the best route to reach a remote address. That information is returned as a NetIPAddress object and NetRoute object. Both should contain the system chosen index. This is only supported on Windows Server 2012 R2 and Windows 8.1 currently.

A simple use would be to provide a remote address. The following code would return the interfaceindex into the variable $bestIndex which you could then use with New-NetRoute

$bestIndex = Find-NetRoute -RemoteIPAddress "123.456.789.012" | select -first 1  -expandproperty interfaceindex

New-NetRoute –DestinationPrefix "xxx.xxx.xxx.xxx/yy" –InterfaceIndex $bestIndex –NextHop zzz.zzz.zzz.zzz

I encourage you to read more on the TechNet page I linked. I found it by reading up on how New-NetRoute worked.

Upvotes: 1

Related Questions