当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 在代理服务器后面使用 PowerShell

作者:精品下载站 日期:2024-12-14 23:27:42 浏览:13 分类:玩电脑

在代理服务器后面使用 PowerShell


如果您的计算机位于代理服务器后面的公司网络上,默认情况下您将无法从 PowerShell CLI 访问外部 Web 资源。例如,您将无法使用 Invoke-WebRequest cmdlet 获取外部网页的内容、使用 Update-Help 更新帮助、连接到 Azure/Microsoft 365 租户(Exchange Online PowerShell 模块)、从 PSGallery 或 RSAT 功能安装模块、从外部包存储库下载应用程序包(使用 WinGet 包管理器)。在本文中,我们将向您展示如何配置 PowerShell 以通过具有身份验证的代理服务器访问 Web。

让我们尝试在公司代理服务器后面的计算机上更新 PowerShell 帮助:

Update-Help

或者参考外部网页:

Invoke-WebRequest https://a-d.site

如果您的计算机只能通过代理访问 Web,而不能通过直接连接,则该命令将返回错误:

Update-help : Failed to update Help for the module(s) ‘DhcpServer, DirectAccessClientComponents….’  with UI culture(s) {en-US} : Unable to connect to Help content. The server on which Help content is stored might not be available. Verify that the server is available, or wait until the server is back online, and then try the command again.
Invoke-WebRequest: Unable to connect to the remote server.
InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest).
Find-Module modulename 
Unable to resolve package source 'https://www.powershellgallery.com/api/v2'

[玩转系统] 在代理服务器后面使用 PowerShell

事实上,Powershell(或者更确切地说,.NET 类 System.Net.WebClient,这些 cmdlet 用于通过 HTTP/HTTPS 访问外部资源)不使用用户设置中指定的代理服务器设置。让我们看一下如何配置代理服务器设置并从 PowerShell 控制台执行身份验证。

设置 PowerShell 的 WinHTTP 代理服务器设置

从 PowerShell 检查当前系统代理设置:

netsh winhttp show proxy

如您所见,未指定代理设置:

Current WinHTTP proxy settings:
Direct access (no proxy server).

[玩转系统] 在代理服务器后面使用 PowerShell

您可以从 Windows 设置 (Internet Explorer) 导入代理服务器配置:

netsh winhttp import proxy source=ie

或手动设置它们:

netsh winhttp set proxy "192.168.0.14:3128"

[玩转系统] 在代理服务器后面使用 PowerShell

您可以指定不需要使用代理服务器连接的 IP 地址或站点名称列表(绕过列表):

netsh winhttp set proxy "192.168.1.100:3128" bypass-list= "10.*,172.*,192.168.*,*.corp.a-d.site"

您可以使用 GPO 在域计算机上集中配置 Winnhttp 代理设置。

您可以检查到特定 URL 的连接是否通过代理:

([System.Net.WebRequest]::GetSystemWebproxy()).IsBypassed("https://a-d.site")

[玩转系统] 在代理服务器后面使用 PowerShell

如果命令返回

False

,将通过 PowerShell 会话中配置的代理建立与此 URL 的连接。

如果代理服务器需要身份验证,则当您尝试运行 PowerShell 命令时,会出现类似“(407) Proxy Authentication Needed”的错误。例如,当尝试使用 AzureAD 模块连接到 Azure 租户时:

Connect-AzureAD

出现错误:

The remote server returned an error: (407) Proxy Authentication Required.

接下来,让我们看看如何从 PowerShell 向代理服务器进行身份验证。

使用 PowerShell 进行代理身份验证

让我们看一下对代理服务器进行身份验证的两种方法:您可以使用 Windows SSO 身份验证或手动指定用户凭据进行身份验证。

如果您在计算机上获得域帐户授权,并且您的代理服务器支持 Active Directory Kerberos 或 NTLM 身份验证(如果您尚未禁用它),则您可以使用当前用户凭据在代理服务器上进行身份验证(无需重新输入用户名和密码):

$Wcl = new-object System.Net.WebClient
$Wcl.Headers.Add(“user-agent”, “PowerShell Script”)
$Wcl.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials

如果您需要在代理服务器上手动进行身份验证,请运行以下命令并在 Windows 安全凭据请求窗口中指定用户名和密码。

$Wcl=New-Object System.Net.WebClient
$Creds=Get-Credential
$Wcl.Proxy.Credentials=$Creds

[玩转系统] 在代理服务器后面使用 PowerShell

现在您可以尝试访问外部网站或使用以下命令更新帮助

Update-Help

命令。

[玩转系统] 在代理服务器后面使用 PowerShell

或者,如果您在 PowerShell 会话中配置了代理连接,则该命令应返回代理服务器的外部 IP 地址:

(Invoke-WebRequest -uri "http://ifconfig.me/ip").Content

正如您所看到的,Invoke-Web Request cmdlet 从外部站点网页返回了数据!

如果您不想在整个 PowerShell 会话中使用代理设置,则可以使用 Invoke-WebRequest cmdlet 的特殊参数以当前用户身份向代理进行身份验证:

Invoke-WebRequest https://a-d.site -ProxyUseDefaultCredentials -Proxy http://192.168.1.100:3128

或者您可以交互式请求用户凭据:


$ProxyCreds = Get-Credential
Invoke-WebRequest https://a-d.site -Proxy "http://192.168.1.100:3128" -ProxyCredential $ProxyCreds

上述方法允许您配置代理服务器设置并在经典 Windows PowerShell 5.1 中进行身份验证(如何检查安装的 PowerShell 版本?)。

为 PowerShell Core 配置代理连接

在新版本的 PowerShell Core(6.x、7.x)中,使用 System.Net.HttpClient 类而不是 System.Net.WebRequest 类在 Invoke-WebRequest、Find-Module、Install-Module 等 cmdlet 中执行 Web 请求。

因此,要在 PowerShell Core 中设置代理服务器设置,您需要使用以下命令:

[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy('http://your-proxy:3128')

要在当前 Windows 用户下的代理上进行身份验证:

[System.Net.Http.HttpClient]::DefaultProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials

要以交互方式请求用户凭据以进行代理身份验证:

[System.Net.Http.HttpClient]::DefaultProxy.Credentials = Get-Credential

PowerShell Core 还支持特殊的 Windows 环境变量,您可以使用它来启用代理设置:

  • HTTP_PROXY - HTTP 请求的代理

  • HTTPS_PROXY — HTTPS 请求的代理

  • ALL_PROXY - HTTP 和 HTTPS 的代理

  • NO_PROXY - 代理排除地址列表

您可以使用以下 PowerShell 命令设置环境变量:

$proxy='http://192.168.1.100:8080'
$ENV:HTTP_PROXY=$proxy
$ENV:HTTPS_PROXY=$proxy

您可以将用于在代理服务器上进行身份验证的用户名和密码保存在环境变量中(不安全):

$proxy='http://username:password@IP:PORT'

检查代理环境变量是否已设置:

Dir env:

[玩转系统] 在代理服务器后面使用 PowerShell

在 Linux 上的 PowerShell Core 中,您可以使用以下命令从环境变量中导出系统代理设置:

export HTTP_PROXY=http://192.168.1.100:3128
export HTTPS_PROXY=http://192.168.1.100:3128

使用 PowerShell 配置文件应用代理服务器设置

您可以创建 PowerShell 配置文件,以便在 PowerShell 启动时自动导入代理设置。

为此,请运行将创建 PowerShell 配置文件的命令 (C:\Users\username\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1):

notepad $PROFILE

(或者

notepad $PROFILE.AllUsersCurrentHost

-如果您需要将 PowerShell 配置文件应用到计算机的所有用户)。

PowerShell 配置文件是一个简单的 PS 脚本,在您打开 PowerShell.exe 控制台时始终运行。

将 PowerShell 代码复制到记事本窗口中。例如,您使用代理自动配置 (PAC) 文件自动配置用户计算机上的代理服务器设置。您可以指定 PAC 文件的 URL 地址,并使用以下 PowerShell 配置文件脚本在当前用户下的代理服务器上进行身份验证。

# Force PowerShell to use TLS 1.2 for connections
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[system.net.webrequest]::DefaultWebProxy = new-object system.net.webproxy('http://10.1.15.5:80')
# If you need to import proxy settings from Internet Explorer, you can replace the previous line with the: "netsh winhttp import proxy source=ie"
[system.net.webrequest]::DefaultWebProxy.credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
# You can request user credentials:
# System.Net.WebRequest]::DefaultWebProxy.Credentials = Get-Credential
# Also, you can get the user password from a saved XML file (see the article “Using saved credentials in PowerShell scripts”):
# System.Net.WebRequest]::DefaultWebProxy= Import-Clixml -Path C:\PS\user_creds.xml
[system.net.webrequest]::DefaultWebProxy.BypassProxyOnLocal = $true

默认情况下,PowerShell 脚本执行策略不允许 PS 脚本运行,即使来自 PowerShell 配置文件也是如此。要允许 PS1 脚本运行,您需要更改 PowerShell 执行策略设置。运行命令:

Set-ExecutionPolicy RemoteSigned

保存 Microsoft.PowerShell_profile.ps1 文件并重新启动 PowerShell 控制台。现在,当您打开新的 PowerShell 会话时,将执行配置文件中的代码,并将代理设置导入到您的会话中。

使用 PowerShell 显示当前代理服务器设置

您可以使用 PowerShell 命令从注册表获取 Windows 中的当前代理设置:

Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' | Select-Object ProxyServer, ProxyEnable

在我的示例中,代理服务器的地址和端口为:192.168.1.100:3128
代理服务器已启用:ProxyEnable =1

[玩转系统] 在代理服务器后面使用 PowerShell

您还可以像这样获取 WebProxy 设置:

[System.Net.WebProxy]::GetDefaultProxy()

[玩转系统] 在代理服务器后面使用 PowerShell

如有必要,您可以使用以下命令启用代理:

Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable -value 1

禁用代理:

Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable -value 0

如何使用 PowerShell 更改 Windows 中的代理设置?

您可以使用 PowerShell 设置代理设置。例如,以下 PowerShell 函数允许您更改代理设置,但首先,它使用 Test-NetConnection cmdlet 检查代理服务器的可用性及其端口响应

function Set-Proxy ( $server,$port)
{
If ((Test-NetConnection -ComputerName $server -Port $port).TcpTestSucceeded) {
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyServer -Value "$($server):$($port)"
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyEnable -Value 1
}
Else {
Write-Error -Message "Invalid proxy server address or port:  $($server):$($port)"
}
}
Set-Proxy 192.168.1.100 3128

您可以将其他地址添加到代理排除列表中:

$ProxyExceptionList = ";*.a-d.site;*.contoso.com"
$ProxyProperty = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
If ($ProxyProperty.ProxyOverride) {
$OldValue = $ProxyProperty.ProxyOverride
$NewValue = $OldValue+$ProxyExceptionList
$ProxyProperty | Set-ItemProperty -Name ProxyOverride -Value $NewValue
} else {
Write-Warning "List of proxy overrides is empty!"
}

此外,您可以在注册表中保存用于在代理服务器上进行身份验证的登录名和密码:

Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyUser -Value "proxy_username"
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyPass -Value "proxy_password"

请注意,旧版本的 Windows 10、Windows Server 2016 和旧版本的 Windows 默认使用过时且不安全的 TLS 1.0 协议进行 PowerShell 连接。这就是为什么您在尝试在 PSGallery 中搜索模块时可能会收到以下错误:

WARNING: Unable to resolve package source 'https://www.powershellgallery.com/api/v2'.

要在与端点的 PowerShell 连接中使用 TLS 1.2,请运行以下命令

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

“安装 PowerShell 模块时无法解析包源”一文更详细地描述了该问题。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯