Set-WindowsProxy.ps1
1#Requires -Version 7.02<#3.SYNOPSIS4Manages the current Windows user's proxy settings and proxy environment variables.5.DESCRIPTION6Enable mode sets a manual HTTP proxy and replaces its bypass list. It also7sets HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY in User and Process scopes.89Disable mode turns off manual proxy, PAC and automatic detection for LAN,10clears the PAC URL, and removes the four proxy environment variables.11The saved manual proxy address and bypass list are retained. Enable mode12does not change or restore PAC and automatic detection settings.1314VPN and WinHTTP settings are separate and are not modified.15.PARAMETER Disable16Turns off LAN proxy settings and removes proxy environment variables.17.PARAMETER ProxyAddress18HTTP proxy endpoint in host:port format, without a URL scheme or credentials.19Defaults to 127.0.0.1:10808. Bracket IPv6 addresses, for example [::1]:10808.20.EXAMPLE21& ./Set-WindowsProxy.ps122Enables the default proxy and sets proxy environment variables.23.EXAMPLE24& ./Set-WindowsProxy.ps1 -ProxyAddress '192.168.1.10:7890'25Uses a custom endpoint for the manual proxy and proxy environment variables.26.EXAMPLE27& ./Set-WindowsProxy.ps1 -Disable28Turns off manual proxy, PAC and automatic detection, and removes proxy variables.29.NOTES30Requires Windows and PowerShell 7; administrator privileges are not required.31Run from an existing PowerShell session to update that session's environment.32A separate pwsh -File process cannot change its parent terminal's environment.33Other running applications may need to be restarted.3435NO_PROXY uses comma-separated hosts and CIDR ranges, rather than Windows36wildcards. CIDR support varies by client; <local> has no portable equivalent.37Both HTTP_PROXY and HTTPS_PROXY use an http:// URL for the HTTP proxy endpoint.38#>3940[CmdletBinding()]41param(42 [switch]$Disable,4344 [ValidateScript({45 $endpoint = $null46 if ($_ -notmatch '^(?:[A-Za-z0-9._-]+|\[[0-9A-Fa-f:.%]+\]):[0-9]{1,5}$' -or47 -not [Uri]::TryCreate(('http://' + $_), [UriKind]::Absolute, [ref]$endpoint) -or48 $endpoint.Port -lt 1 -or $endpoint.Port -gt 65535) {49 throw 'ProxyAddress must be host:port (port 1-65535), e.g. 127.0.0.1:10808 or [::1]:10808. Do not include a URL scheme.'50 }51 $true52 })]53 [string]$ProxyAddress = '127.0.0.1:10808'54)5556$ErrorActionPreference = 'Stop'5758if (-not $IsWindows) {59 throw 'This script requires Windows.'60}6162function Initialize-LanProxyApi {63 if ('PublicRepo.LanProxySettings' -as [type]) {64 return65 }6667 # WinINet controls all three LAN proxy modes, including automatic detection.68 Add-Type -TypeDefinition @'69using System;70using System.ComponentModel;71using System.Runtime.InteropServices;7273namespace PublicRepo74{75 public static class LanProxySettings76 {77 private const uint INTERNET_OPTION_PER_CONNECTION_OPTION = 75;78 private const uint INTERNET_OPTION_SETTINGS_CHANGED = 39;79 private const uint INTERNET_OPTION_REFRESH = 37;80 private const uint INTERNET_PER_CONN_FLAGS = 1;81 private const uint INTERNET_PER_CONN_AUTOCONFIG_URL = 4;82 private const uint PROXY_TYPE_DIRECT = 1;8384 [StructLayout(LayoutKind.Explicit)]85 private struct OptionValue86 {87 [FieldOffset(0)] public uint Flags;88 [FieldOffset(0)] public IntPtr Text;89 [FieldOffset(0)] public System.Runtime.InteropServices.ComTypes.FILETIME FileTime;90 }9192 [StructLayout(LayoutKind.Sequential)]93 private struct ConnectionOption94 {95 public uint Option;96 public OptionValue Value;97 }9899 [StructLayout(LayoutKind.Sequential)]100 private struct ConnectionOptionList101 {102 public uint Size;103 public IntPtr Connection;104 public uint Count;105 public uint Error;106 public IntPtr Options;107 }108109 [DllImport("wininet.dll", EntryPoint = "InternetSetOptionW", ExactSpelling = true, SetLastError = true)]110 [return: MarshalAs(UnmanagedType.Bool)]111 private static extern bool InternetSetOptionW(IntPtr handle, uint option, IntPtr buffer, uint size);112113 private static void SetOption(uint option, IntPtr buffer, uint size)114 {115 if (!InternetSetOptionW(IntPtr.Zero, option, buffer, size))116 throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to update Windows proxy settings (option " + option + ").");117 }118119 public static void Disable()120 {121 IntPtr options = IntPtr.Zero;122 IntPtr listBuffer = IntPtr.Zero;123 IntPtr emptyUrl = IntPtr.Zero;124 try125 {126 int optionSize = Marshal.SizeOf(typeof(ConnectionOption));127 options = Marshal.AllocHGlobal(checked(optionSize * 2));128 emptyUrl = Marshal.StringToHGlobalUni(string.Empty);129 // DIRECT only: no PROXY, AUTO_PROXY_URL or AUTO_DETECT flags.130 var flags = new ConnectionOption {131 Option = INTERNET_PER_CONN_FLAGS,132 Value = new OptionValue { Flags = PROXY_TYPE_DIRECT }133 };134 var pac = new ConnectionOption {135 Option = INTERNET_PER_CONN_AUTOCONFIG_URL,136 Value = new OptionValue { Text = emptyUrl }137 };138 Marshal.StructureToPtr(flags, options, false);139 Marshal.StructureToPtr(pac, IntPtr.Add(options, optionSize), false);140 var list = new ConnectionOptionList {141 Size = (uint)Marshal.SizeOf(typeof(ConnectionOptionList)),142 Connection = IntPtr.Zero, // NULL selects LAN; VPN connections are separate.143 Count = 2,144 Options = options145 };146 listBuffer = Marshal.AllocHGlobal((int)list.Size);147 Marshal.StructureToPtr(list, listBuffer, false);148 SetOption(INTERNET_OPTION_PER_CONNECTION_OPTION, listBuffer, list.Size);149 SetOption(INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);150 SetOption(INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);151 }152 finally153 {154 if (listBuffer != IntPtr.Zero) Marshal.FreeHGlobal(listBuffer);155 if (options != IntPtr.Zero) Marshal.FreeHGlobal(options);156 if (emptyUrl != IntPtr.Zero) Marshal.FreeHGlobal(emptyUrl);157 }158 }159 }160}161'@162}163164function Set-ManualProxy {165 param(166 [string]$RegistryPath,167 [string]$Address,168 [string]$BypassList169 )170171 New-ItemProperty -Path $RegistryPath -Name ProxyServer -PropertyType String -Value $Address -Force | Out-Null172 New-ItemProperty -Path $RegistryPath -Name ProxyOverride -PropertyType String -Value $BypassList -Force | Out-Null173 New-ItemProperty -Path $RegistryPath -Name ProxyEnable -PropertyType DWord -Value 1 -Force | Out-Null174}175176function Set-ProxyEnvironment {177 param(178 [string]$ProxyUrl,179 [string]$NoProxy,180 [switch]$Disable181 )182183 $variables = [ordered]@{184 HTTP_PROXY = $ProxyUrl185 HTTPS_PROXY = $ProxyUrl186 ALL_PROXY = $ProxyUrl187 NO_PROXY = $NoProxy188 }189190 foreach ($name in @($variables.Keys)) {191 if ($Disable) {192 $variables[$name] = $null193 }194195 foreach ($scope in @('User', 'Process')) {196 if ($Disable) {197 # A true .NET null deletes the variable on PowerShell 7.5+ too.198 [Environment]::SetEnvironmentVariable($name, [NullString]::Value, $scope)199 }200 else {201 [Environment]::SetEnvironmentVariable($name, $variables[$name], $scope)202 }203 }204 }205206 [pscustomobject]$variables207}208209# Keep Windows bypass rules separate from the NO_PROXY format used by CLI tools.210$registryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings'211$manualBypass = @(212 'localhost'213 '127.*'214 '10.*'215 '172.16.*'216 '172.17.*'217 '172.18.*'218 '172.19.*'219 '172.20.*'220 '172.21.*'221 '172.22.*'222 '172.23.*'223 '172.24.*'224 '172.25.*'225 '172.26.*'226 '172.27.*'227 '172.28.*'228 '172.29.*'229 '172.30.*'230 '172.31.*'231 '192.168.*'232 'hzboiler.com'233 '<local>'234) -join ';'235236$noProxy = @(237 'localhost'238 '127.0.0.1'239 '::1'240 '127.0.0.0/8'241 '10.0.0.0/8'242 '172.16.0.0/12'243 '192.168.0.0/16'244 'hzboiler.com'245 '.hzboiler.com'246) -join ','247248if ($Disable) {249 Initialize-LanProxyApi250 [PublicRepo.LanProxySettings]::Disable()251}252else {253 Set-ManualProxy -RegistryPath $registryPath -Address $ProxyAddress -BypassList $manualBypass254}255256$environmentState = Set-ProxyEnvironment -ProxyUrl ('http://' + $ProxyAddress) -NoProxy $noProxy -Disable:$Disable257258Get-ItemProperty -Path $registryPath |259 Select-Object ProxyEnable, ProxyServer, ProxyOverride, AutoConfigURL260261$environmentState262263
点击行号可定位并分享该行。预览按文本显示文件内容,原文件可随时下载。