使用PowerShell通过不同网络(网卡)访问不同网站

序
在学校生活时经常有一种需求:访问某些网站(如校内系统)时需要使用校园网,访问另一些网站(如Steam、Github等)校园网很慢,需要使用手机浏览器等其他网络加速。此时我就觉得如果能同时使用两个网络该多好
本文就介绍如何用PowerShell实现这个功能(需要Windows平台,版本XP及以上)
原理
首先需要明确,同一张网卡是无法同时连接两个网络的(除非同时使用多个代理达到这种效果)。幸运的是,现在绝大多数电脑都同时拥有有线和无线两张网卡,所以可以实现这个效果
其次,一般应用程序无法直接指定网卡上网(例如虚拟机软件除外),不过我们有代替的方法:设置路由表
路由表的基本原理是:要求IP的某些网段,走指定的网关。而网关又和网络有密不可分的联系,从而实现隐式地指定网卡
查看电脑信息
首先可以同时连上有线和无线网,方便查看
1、网络适配器
一台电脑上会有多个网络适配器,其中有物理网卡,也有虚拟网卡。我们要找出其中物理网卡里的有线和无线网卡:首先键入ipconfig,可以对此有一个大致印象:
十分明显地看到,有好多适配器。但比如说名字里带virtual的,或者vEthernet这种显然是虚拟网卡。剩下很快就能发现有线和无线网络适配器分别是:以太网和WLAN(不同电脑可能名字不一样)

接下来使用Get-NetIPConfiguration指令,就可以看到物理网卡的信息了:
其中我们要注意Gateway的项,这就是网关

其他相关指令:netsh interface show interface、Get-NetAdapter,感兴趣可以看看
2、路由
使用Get-NetRoute指令(或route print)可以查看路由表:
表中每一条代表一个路由,注意他所有的属性:
ifIndex (interface index)(接口序号):即和上图同名的属性
DestinationPrefix(目标前缀):即指定的网段,属于这个网段的会找对应的网关(其中前面四段句点分开的是IP,斜杠后的是子网掩码从左往右数1的位数)
NextHop(下一跳):即指定的网关
两个Metric(跃点):大致表示这个路由的优先级,数字越小越优先
PolicyStore(存储策略):表示这是临时路由(ActiveStore)还是永久路由(PersistentStore),其中临时路由会在重启后删除重设

注意NextHop不为空的路由(一般Metric也最小),这就是有线和无线网默认的路由,我们新建路由时为避免冲突,要先删除这个(不用担心失误,重启后会恢复)
这些路由前面网段都是0.0.0.0/0(或::/0),表示全网段都可以使用这个路由。
从Metric可以发现,绝大多数电脑同时连有线和无线网时,都是有线网的Metric比较小,这也是为什么路由总是会优先选择有线网连接。Windows默认开启了AutomaticMetric,会按照带宽网速自动设定Metric,有需要可以去设置关闭
3、设备地址
输入指令Get-CimInstance Win32_NetworkAdapterConfiguration | Select-Object Description, SettingID,可以看到网卡以及对应的Guid
我们将来可以通过这个Guid,从注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\{对应设备Guid}\Connection的PnPInstanceId项判断是不是物理网卡(值以PCI开头是物理网卡,BTH开头是蓝牙网卡,其他是虚拟网卡)

实现思路
接下来就是实现环节了,虽然指定网关听起来很容易。但如果切换网络之后,不仅网关可能会变,而且接口别名(InterfaceAlias)也会变,到时候再调整比较麻烦。
如果可以指定网卡,并指定网段就很方便了。实际上我们确实可以这样做,因为Get-NetIPConfiguration(或Get-NetAdapter)可以看出来:接口描述(InterfaceDescription)、接口别名(InterfaceAlias)和网关(Gateway)几乎是一一对应的关系,所以我们可以通过PowerShell(或C/C++)从接口描述查找网关,并设置路由,就可以达成目的
至于网段分配,一般校园网都是连续的网段,比如说172.18.XXX.XXX都是校园网IP,那么就设置目标前缀(DestinationPrefix)为172.18.0.0/16,表示子网掩码是255.255.0.0,即前16位是固定的,后面可以变化。将这段路由优先级设最高,然后再设置剩下的路由(直接用0.0.0.0/0)全部走另一个网络(优先级第二高)
另外还可以结合Proxifier等软件管理,如用Proxifier强大的代理筛选功能将校园网所有IP或程序都代理到某一台学校的服务器上,这样路由规则就可以只要指定一个IP了(如172.18.6.57/32)
脚本代码
需要使用PowerShell7及以上运行
在使用的时候,只需要按照需要修改# Main部分
代码仓库
包含完整PowerShell代码和部分C++方法
Github:https://github.com/Poker-sang/RouteModifier
引用图片


参考资料
[1] NetTcpIp(https://learn.microsoft.com/powershell/module/nettcpip)