单网卡玩转智能网关——一键自动启停脚本

接前文单网卡玩转智能网关——把OpenWRT塞进虚拟机,我们纯手工完成了全局软路由的配置,但是有时候我们并不希望一直开启软路由,于是又得手工改回各项配置;然而有时候又需要软路由了,又要改配置……改来改去的过程那个麻烦那个痛苦啊,还是弄个自动化配置脚本吧。我们的目标是:

于是我们有了以下自动化脚本,基于微软家的powershell,使用需要管理员权限。其中脚本的前面几行是定义的基本变量,需要跟自己的本地环境保持一致。例如我的WiFi网卡在控制面板->网络和Internet->网络连接中,显示的名称为WLAN,那么就有定义的变量$wifi_name='WLAN',其他几个变量参考前文中网卡的命名。

#variables
$switch_name='Bridge Switch'
$wifi_name='WLAN'
$vm_name='openwrt'
$net_alias_name='vEthernet (Bridge Switch)'
$destination = '0.0.0.0/0'

function Write-Log {
    Param(
        $Message,
        $Path = "$env:USERPROFILE\gateway_change.log"
    )

    function TS {Get-Date -Format 'hh:mm:ss'}
    "[$(TS)]$Message" | Tee-Object -FilePath $Path -Append | Write-Host
}

#Start VM and changing the Gateway
Function Start-Gateway() {
    $cur_index = get-netroute -DestinationPrefix $destination | select -ExpandProperty ifIndex
    $cur_ip = get-netipaddress | where-object {$_.InterfaceIndex -eq $cur_index} | select -ExpandProperty IPAddress
    $prefixLength = Get-NetIPAddress -InterfaceAlias $wifi_name | Select-Object -ExpandProperty PrefixLength

    Write-Log -Message "==============Start Gateway at $(Get-Date)=============="
    Write-Log -Message "Gateway is $cur_gateway and will be changed to $vm_name IpAddress"

    #修改桥接器
    Write-Log "Enable bridged virtual switch: $switch_name ..."
    Set-VMSwitch $switch_name -NetAdapterName $wifi_name

    #取消VMQ
    #Get-VMNetworkAdapter -ManagementOS
    Write-Log "Cancel VMQ on bridged virtual switch: $switch_name ..."
    Set-VMNetworkAdapter –ManagementOS -Name $switch_name -VmqWeight 0

    #启动vm
    Write-Log "Start virtual mathine: $vm_name ..."
    Start-VM -Name $vm_name
    Write-Log "Trying to get IP address, this might take several minutes..."
    sleep 10
    $vm_ip = (Test-Connection -ComputerName $vm_name -Count 20 | Where-Object {$_.IPV4Address -ne $null} | Select-Object -ExpandProperty IPV4Address -First 1).IPAddressToString
    Write-Log "Virtual mathine IP is $vm_ip"

    #修改接口路由与默认dns
    Write-Log "Set static IP address to $cur_ip, prefix length to $prefixLength, and gateway to $vm_ip ..."
    Remove-NetIPAddress -InterfaceAlias $net_alias_name -confirm:$false
    New-NetIPAddress -InterfaceAlias $net_alias_name -IPAddress $cur_ip -AddressFamily IPv4 -PrefixLength $prefixLength -DefaultGateway $vm_ip


    Write-Log "Set static DNS Server: $vm_ip ..."
    Set-DnsClientServerAddress -InterfaceAlias $net_alias_name -ServerAddresses @($vm_ip)

    #重启WLAN网卡使VMQ生效
    Write-Log  "Restart phisical network adapter: $wifi_name ..."
    Restart-NetAdapter -Name $wifi_name
}

#Stop VM and changing the Gateway to DHCP
Function Stop-Gateway() {
    Write-Log -Message "==============Stop Gateway at $(Get-Date)=============="
    Write-Log -Message "Gateway is $cur_gateway and will be changed to DHCP default settings"

    #关闭vm
    Write-Log "Shutdown virtual mathine: $vm_name ..."
    Stop-VM -Name $vm_name
    sleep 3

    #取消桥接器
    Write-Log "Remove bridged virtual switch: $switch_name ..."
    Set-VMSwitch $switch_name  -SwitchType Private

    #修改接口路由与默认dns
    Write-Log "Reset phisical network adapter: $wifi_name to DHCP default settings ..."
    Set-NetIPInterface -InterfaceAlias $wifi_name -Dhcp Enabled
    Set-DnsClientServerAddress -InterfaceAlias $wifi_name -ResetServerAddresses

    Write-Log "Restart phisical network adapter: $wifi_name ..."
    Restart-NetAdapter -Name $wifi_name
}


#region 强制以管理员权限运行
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{   
    $arguments = "& '" + $myinvocation.mycommand.definition + "'"
    Start-Process powershell -Verb runAs -ArgumentList $arguments
    Break
}
#endregion


$state = Get-VMSwitch $switch_name | select -ExpandProperty SwitchType
$cur_gateway = get-netroute -DestinationPrefix $destination | select -ExpandProperty NextHop
if ($state -eq "External") {
    Stop-Gateway 
}
else {
    Start-Gateway
}

[返回首页]