许多 PowerShell cmdlet(例如 AWS cmdlet)会引用 Internet Explorer 代理设置来查找要使用的代理和绕过列表。
我正在尝试配置代理服务器并绕过列表,以用作在新 AWS 实例上执行的用户数据脚本的一部分。
我尝试了多种方法来使其正常工作,但似乎无法使其可靠地工作。
首先,我们为代理服务器和旁路列表设置变量,请注意,这些地址根据实例所在的 VPC 的不同而有所不同:
$proxy = "security-elb-1111111111.us-east-2.elb.amazonaws.com:3128"
$bypassList = "169.254.169.254;octopus-769734587.us-east-2.elb.amazonaws.com;s3.dualstack.us-east-1.amazonaws.com"
其次,netsh:
netsh winhttp set proxy $proxy bypass-list=$bypassList
这很有效,但遗憾的是很多 cmdlet 都没有引用它。
这看起来也可能有用:
& C:\windows\System32\bitsadmin.exe /Util /SetIEProxy LOCALSYSTEM Manual_proxy $proxy $bypassList
但这仅为帐户 LOCALSYSTEM、NETWORKSERVICE 或 LOCALSERVICE 设置代理服务器。我认为 userdata 脚本以管理员身份运行,因此这似乎并不像第一次出现时那么有用。
所以我尝试破解注册表,如下所示:
$reg = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty -Path $reg -Name ProxyServer -Value $proxy
Set-ItemProperty -Path $reg -Name ProxyEnable -Value 1
Set-ItemProperty -Path $reg -Name ProxyOverride -Value $bypassList
这将打开代理并设置基本详细信息。但看起来好像缺少一个重要的部分,因为它不起作用。然后我发现
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections]
其中包含 key “DefaultConnectionSettings”和“SavedLegacySettings”。 这些似乎包含代理设置的十六进制版本。所以我创建了这个:
$proxyString = ""
for ($i = 0;$i -lt (([System.Text.Encoding]::Unicode.GetBytes($proxy)).length); $i++) {
if ($i % 2 -eq 0) {
$byte = (([System.Text.Encoding]::Unicode.GetBytes($proxy))[$i])
$convertedByte=%{[System.Convert]::ToString($byte,16)}
$proxyString = $proxystring + $convertedByte + ","
}
}
$bypassString = ""
for ($i = 0;$i -lt (([System.Text.Encoding]::Unicode.GetBytes($bypassList)).length); $i++) {
if ($i % 2 -eq 0) {
$byte = (([System.Text.Encoding]::Unicode.GetBytes($bypassList))[$i])
$convertedByte=%{[System.Convert]::ToString($byte,16)}
$bypassString = $bypassString + $convertedByte + ","
}
}
这将 $proxy 和 $bypass 转换为十六进制字符串,我将其组合成长字符串以在注册表中使用,如下所示:
$regString="46,00,00,00,00,00,00,00,0b,00,00,00,3c,00,00,00," + $proxystring + (%{[System.Convert]::ToString($bypassList.length,16)}) + ",00,00,00," + $bypassString + "00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00"
这会放入一些(看似)任意的十六进制行(这可能是我的问题所在),后面是代理字符串,后面是旁路列表长度的十六进制指示符,后面是旁路列表,最后是由另一个看似任意的十六进制值系列。
它适用于某些网络上的实例,但不适用于其他网络上的实例。故障网络上的代理地址比工作网络上的代理地址短一个字符。
但奇怪的是,如果我登录到计算机,打开 Internet Explorer 然后再次关闭,cmdlet 突然就能够成功使用代理了。
那么当我打开 Internet Explorer 时到底发生了什么?一定有正在更改的注册表项有助于此过程?我尝试比较前后的注册表项,但看不到任何内容。
我尝试的另一件事是以编程方式创建 PAC 文件来配置设置。我是这样做的:
'[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings]
"AutoConfigURL"="C:\\scripts\\proxyConfig.pac"'| out-file c:\proxyReg.reg
$proxy = "internal-sec-elb-937750220.us-east-1.elb.amazonaws.com:3128"
$bypassList = "169.254.169.254;internal-mgt-priv-adr-prod-man-lb-769734587.us-east-1.elb.amazonaws.com;" + "s3.dualstack.us-east-1.amazonaws.com"
$pacFileLocation = "c:\scripts\proxyConfig.pac"
if (!(test-path (split-path $pacFileLocation))) {New-Item -ItemType Directory -Path (Split-Path $pacFileLocation)}
$pacText = 'function FindProxyForURL(url, host) {
return "PROXY ' + $proxy + ';
DIRECT";
}
'
foreach ($localAddress in ($bypassList.Split(";"))) {
$pacText = $pacText + 'if (isPlainHostName(' + $localAddress+ '))
{
return "DIRECT";
}
'
}
$pacText = $pacText + "
if (isInNet(hostIP, '0.0.0.0', '255.0.0.0') ||
isInNet(hostIP, '10.0.0.0', '255.0.0.0') ||
isInNet(hostIP, '127.0.0.0', '255.0.0.0') ||
isInNet(hostIP, '169.254.0.0', '255.255.0.0') ||
isInNet(hostIP, '172.16.0.0', '255.240.0.0') ||
isInNet(hostIP, '192.0.2.0', '255.255.255.0') ||
isInNet(hostIP, '192.88.99.0', '255.255.255.0') ||
isInNet(hostIP, '192.168.0.0', '255.255.0.0') ||
isInNet(hostIP, '198.18.0.0', '255.254.0.0') ||
isInNet(hostIP, '224.0.0.0', '240.0.0.0') ||
isInNet(hostIP, '240.0.0.0', '240.0.0.0'))
{
return 'DIRECT';
}"
$pacText | out-file $pacFileLocation -Force
但是,情况似乎又是这样,这些设置只有在打开 Internet Explorer 时才会生效。
不幸的是,我无法打开 Internet Explorer,因为代理需要在用户登录到计算机之前工作,而从脚本中运行 iexplore.exe 则无法做到这一点。
这一切看起来真的过于复杂。我可以在两行内配置 Linux 服务器内的代理。我肯定在某个地方错过了简单的解决方案。它是什么?
最佳答案
在为 Server Core 2016 设置代理时,我得到了与 Richard 相同的结果(稍短)。可怕的是,这是必要的!
function Set-Proxy($proxy, $bypassUrls){
$proxyBytes = [system.Text.Encoding]::ASCII.GetBytes($proxy)
$bypassBytes = [system.Text.Encoding]::ASCII.GetBytes($bypassUrls)
$defaultConnectionSettings = [byte[]]@(@(70,0,0,0,0,0,0,0,11,0,0,0,$proxyBytes.Length,0,0,0)+$proxyBytes+@($bypassBytes.Length,0,0,0)+$bypassBytes+ @(1..36 | % {0}))
$registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty -Path $registryPath -Name ProxyServer -Value $proxy
Set-ItemProperty -Path $registryPath -Name ProxyEnable -Value 1
Set-ItemProperty -Path "$registryPath\Connections" -Name DefaultConnectionSettings -Value $defaultConnectionSettings
netsh winhttp set proxy $proxy bypass-list=$bypassUrls
}
Set-Proxy "someproxy:1234" "*.example.com;<local>"
关于powershell - 使用 PowerShell 以编程方式配置 Internet Explorer 代理设置,使其在打开之前起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48166882/