Reputation: 3447
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
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
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