# $Global:TestDomain = "www.google.com" #测试代理是否可用 # $Global:TestIP = "223.5.5.5" #测试是否连接网络 # $Global:originalDns = "223.5.5.5" #默认DNS # $Global:originalGateway = "192.168.6.1" #默认网关 # $Global:CustomGateway = "192.168.6.2" #代理网关 # $Global:CustomIP = "192.168.6.4" #默认ip # $Global:TargetNetworkAdapter = {} #网络适配器实例 # $Global:TargetNetworkAdapterKeyword = "Ethernet" #网络适配器名字通配符 # $Global:isCustomGateway = $false #是否为自定义网关 . $(-Join($(Get-Location).Path, '\config.ps1')) . $(-Join($(Get-Location).Path, '\proxy-test.ps1')) . $(-Join($(Get-Location).Path, '\logger.ps1')) function isDhcpEnable(){ return Get-NetIPConfiguration | select-object InterfaceAlias, IPv4Address, @{n="dhcp";e={$_.NetIPv4Interface.DHCP}} | Select-Object -ExpandProperty dhcp } function isForeignConnected { # check foreign network availability $result = Test-NetConnection -ComputerName $Global:TestDomain -Port 443 if ($result.TcpTestSucceeded) { Write-Log -Message "Successfully connected to $($Global:TestDomain) via HTTPS. isCustomGateway:$($Global:isCustomGateway)" return $true } else { Write-Log -Message "Failed to connect to $($Global:TestDomain) via HTTPS. isCustomGateway:$($Global:isCustomGateway)" return $false } } function isNetworkConnected { # check network availability $result = $(Test-Connection -ComputerName $Global:TestIP -Count 1).Status -eq 'Success' if ($result) { Write-Log -Message "Successfully connected to $($Global:TestIP) via ICMP. isCustomGateway:$($Global:isCustomGateway)" return $true } else { Write-Log -Message "Failed to connect to $($Global:TestIP) via ICMP. isCustomGateway:$($Global:isCustomGateway)" return $false } } function setDhcp($enable){ if($enable){ Set-NetIPInterface -InterfaceAlias $Global:TargetNetworkAdapter.name -Dhcp Enabled Write-Log -Message "enable dhcp" } else { Set-NetIPInterface -InterfaceAlias $Global:TargetNetworkAdapter.name -Dhcp Disabled Write-Log -Message "disable dhcp" } } function changeGateway{ param( $adapter,$isCustomGateway ) Write-Log -Message "Changing gateway for adapter: $($adapter.Name) isCustomGateway $($isCustomGateway)" # check gateway availability if($isCustomGateway){ $currentGateway = $(Get-NetIPConfiguration).IPv4DefaultGateway.NextHop if($currentGateway -eq $Global:CustomGateway){ Write-Log -Message "current gateway is $currentGateway same as targetGateway $Global:TargetGateway, change gateway canceled" $Global:isCustomGateway = $true return } $result = $(Test-Connection $Global:CustomGateway -Count 1).Status if (! ($result -eq 'Success')){ Write-Log -Message "custom gateway $Global:CustomGateway is $result, refuse to change" return } } # check current ip configuration $existingIP = Get-NetIPAddress -InterfaceAlias $adapter.Name -AddressFamily IPv4 # if have ip configuration, delete it if ($existingIP) { Write-Log -Message "Removing existing IP address: $($existingIP.IPAddress)" Remove-NetIPAddress -InterfaceAlias $adapter.Name -Confirm:$false } # delete current route(gateway) $existingRoute = Get-NetRoute -InterfaceAlias $adapter.Name -DestinationPrefix "0.0.0.0/0" if ($existingRoute) { Write-Log -Message "Removing existing default route..." Remove-NetRoute -InterfaceAlias $adapter.Name -Confirm:$false } if ($isCustomGateway){ #setting gateway # config customGateway $Global:isCustomGateway = $true # setting dns server Set-DnsClientServerAddress -InterfaceAlias $adapter.name -ServerAddresses ($Global:CustomGateway, $Global:CustomGateway) # disable dhcp setDhcp($false) # setting gateway to customGateway New-NetIPAddress -InterfaceAlias $adapter.Name -AddressFamily IPv4 -IPAddress $Global:CustomIP -PrefixLength 24 -DefaultGateway $Global:CustomGateway } else { # config originalGateway $Global:isCustomGateway = $false # setting dns server Set-DnsClientServerAddress -InterfaceAlias $adapter.name -ServerAddresses ($Global:originalDns, $Global:originalDns) # disable dhcp setDhcp($false) # setting gateway to originalGateway New-NetIPAddress -InterfaceAlias $adapter.Name -AddressFamily IPv4 -IPAddress $Global:CustomIP -PrefixLength 24 -DefaultGateway $Global:originalGateway } Start-Sleep 3 } function getIPAddress(){ $IP = Get-NetIPConfiguration | Select-Object -ExpandProperty IPV4Address | Select-Object -ExpandProperty IPAddress return $IP } function getNetworkAdapter(){ $networkAdapters = Get-NetAdapter | ForEach-Object { [PSCustomObject]@{ Name = $_.Name Interface = $_.InterfaceDescription Status = $_.Status LinkSpeed = $_.LinkSpeed MacAddress = $_.MacAddress } } foreach ($networkAdapter in $networkAdapters){ if($networkAdapter.name.Contains($TargetNetworkAdapterKeyword)){ $Global:TargetNetworkAdapter = $networkAdapter break; } } Write-Log -Message "getNetworkAdapter: $Global:TargetNetworkAdapter" } function init { Write-Log -Message "GateWay-KeepAliveForPowershell is start" -ToEventLog # check permission $IsAdmin = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() if (-not $IsAdmin.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { # if not admin permission, restart it with admin permission Write-Log -Message "Requesting Administrator privileges..." Start-Process pwsh -ArgumentList "-NoExit", "-File", $PSCommandPath -Verb RunAs exit } Write-Log -Message "Running with Administrator privileges!" # get netAdapter instance getNetworkAdapter Write-Log -Message "current adapter: $($Global:TargetNetworkAdapter.name)" # try to change to customGateway at start changeGateway $Global:TargetNetworkAdapter $true } function loop(){ while($true){ # if network offline and using customGateway, try to restore to originalGateway if((!$(isNetworkConnected)) -and $Global:isCustomGateway){ Write-Log -Message "Network is down, change to original gateway" -ToEventLog changeGateway $Global:TargetNetworkAdapter $false } # if customGateway proxy is working and using original gateway, try to change to customGateway if($(Test-SocksProxy -ProxyHost $Global:CustomGateway -ProxyPort 1070) -and (!$Global:isCustomGateway)){ Write-Log -Message "isCustomGateway $Global:isCustomGateway" Write-Log -Message "proxy host is up, change to custom gateway" -ToEventLog changeGateway $Global:TargetNetworkAdapter $true } # if customGateway proxy is not working but network still online, do nothing Start-Sleep 1 } } init loop