Использование PowerShell для программной настройки параметров прокси-сервера Internet Explorer для работы до его открытия

Многие командлеты PowerShell (такие как командлеты AWS) относятся к настройкам прокси-сервера Internet Explorer, чтобы найти, какие списки прокси и байпаса использовать.

Я пытаюсь настроить прокси-сервер и списки обхода, которые будут использоваться как часть сценариев userdata, которые выполняются в новых экземплярах 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

Это хорошо работает, но, к сожалению, многие командлеты не ссылаются на него.

Также это выглядело потенциально полезным:

& C:\windows\System32\bitsadmin.exe /Util /SetIEProxy LOCALSYSTEM Manual_proxy $proxy $bypassList

Но это устанавливает только прокси-сервер для учетных записей LOCALSYSTEM, NETWORKSERVICE или LOCALSERVICE. Я думаю, что userdata script работает как администратор, поэтому это не кажется таким же полезным, как и в начале.

Итак, я попытался взломать реестр, например:

$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]

содержащий ключи "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? Должны быть ключи реестра, которые меняются, что помогает этому процессу? Я пытался сравнить ключи реестра до и после, но ничего не видел.

Еще одна вещь, которую я пробовал, - это программное создание файла 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 из script не сделает этого.

Все это кажется чрезмерно сложным. Я могу настроить прокси-сервер в Linux-сервере в двух строках. Я, конечно, пропустил простое решение где-то. Что это?

Ответ 1

Я понял это.

Недостатком ключевой части был шестнадцатеричный байт, указывающий длину прокси-адреса.

Итак, я изменил строку, которая объединяет шестую строку:

$regString="46,00,00,00,00,00,00,00,0b,00,00,00,"+(%{[System.Convert]::ToString($proxy.length,16)})+",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"

И это работает успешно.

Итак, для подхода с поясом и фигурными скобками: Netsh

netsh winhttp set proxy $proxy bypass-list=$bypassList

Internet Explorer для системных учетных записей:

foreach ($account in "LOCALSYSTEM","NETWORKSERVICE","LOCALSERVICE") {
    & C:\windows\System32\bitsadmin.exe /Util /SetIEProxy $account Manual_proxy $proxy $bypassList
}

Internet Explorer для текущих учетных записей:

$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  + ","
    }
}
$regString="46,00,00,00,00,00,00,00,0b,00,00,00,"+(%{[System.Convert]::ToString($proxy.length,16)})+",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"
$regstringAsArray = ("0x"+$regString.replace(",",",0x")).Split(",")
$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
$reg = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"
Set-ItemProperty -Path $reg -Name DefaultConnectionSettings -Type Binary -Value $regstringAsArray
Set-ItemProperty -Path $reg -Name SavedLegacySettings -Type Binary -Value $regstringAsArray