← 返回文件列表

Set-WindowsProxy.ps1

PowerShell · 9,030 B · 263 行

下载原文件
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

点击行号可定位并分享该行。预览按文本显示文件内容,原文件可随时下载。