Um script que rodava sem problemas no seu notebook vai para um servidor, ou agora precisa ler uma lista de preços como um visitante de outro país, e cada chamada de Invoke-WebRequest tem que sair por um proxy. O PowerShell tem os parâmetros para isso. Só que eles se comportam de forma diferente no Windows PowerShell 5.1 e no PowerShell 7, e o atalho mais comum, escrever user:pass@ dentro do endereço do proxy, falha com um 407 no 5.1 sem dizer por quê.
Este artigo cobre -Proxy e -ProxyCredential, credenciais sem janela de senha, um proxy para todas as chamadas, variáveis de ambiente e o proxy do sistema do Windows, SOCKS5, um script de download com novas tentativas e os textos exatos dos erros. Cada trecho para o 5.1 foi executado no Windows PowerShell 5.1 (build 26100) contra um proxy local que exige usuário e senha. O PowerShell 7 não estava instalado na máquina de teste, então o comportamento dele vem da documentação da Microsoft e está marcado como tal.
Windows PowerShell 5.1 ou PowerShell 7: por que isso importa?
As duas versões enviam requisições web por pilhas HTTP diferentes, então a mesma configuração de proxy pode funcionar em uma e ser ignorada na outra. O Windows PowerShell 5.1 vem com o Windows e usa a classe HttpWebRequest do .NET Framework; o PowerShell 7 é um download separado e usa HttpClient. $PSVersionTable.PSVersion diz em qual deles um script está rodando.
| Comportamento | Windows PowerShell 5.1 | PowerShell 7.x |
|---|---|---|
-Proxy, -ProxyCredential | Sim | Sim |
HTTP_PROXY, HTTPS_PROXY, NO_PROXY | Ignoradas | Lidas desde o 7.0 |
| Proxy quando nenhum é informado | Opções da Internet do usuário | Variáveis, depois as configurações do usuário |
Opção -NoProxy | Não | Desde o 6.0 |
| Endereço SOCKS5 | Não | 7.2 em diante |
Aliases curl e wget | Apontam para Invoke-WebRequest | Removidos |
| Novas tentativas integradas | Não | -MaximumRetryCount |
A coluna do 5.1 é o que observamos; a do 7.x segue a referência do Invoke-WebRequest para o PowerShell 7.5.
Como o Invoke-WebRequest envia uma requisição pelo proxy?
- O PowerShell resolve o nome do host do proxy, não o do destino, e abre uma conexão TCP com a porta do proxy.
- Para um destino
http://, ele envia a URL inteira ao proxy (GET http://httpbin.org/ip HTTP/1.1). O proxy busca a página e a repassa, então consegue ler a requisição. - Para um destino
https://, ele enviaCONNECT httpbin.org:443. Depois que o proxy responde200 Connection Established, o handshake TLS com o site acontece dentro desse túnel; o proxy vê apenas o nome do host e a porta. - As credenciais só saem depois de um desafio. A primeira tentativa não leva o cabeçalho
Proxy-Authorization, o proxy responde407comProxy-Authenticate: Basice o .NET repete a requisição com o cabeçalho. O código de status 407 e o desafio estão definidos na RFC 9110; o 5.1 não se autentica de antemão, por isso o nosso proxy de teste registrou cada chamada bem-sucedida como este par:
11:02:56 407 GET http://httpbin.org/ip (no Proxy-Authorization)
11:02:56 GET http://httpbin.org/ip user=user- O destino responde ao IP de saída do proxy. O cmdlet devolve um objeto com
StatusCode,HeaderseContent; no 5.1, um status fora de 2xx vira um erro de encerramento.
Como usar o Invoke-WebRequest com proxy?
Crie um objeto de credenciais e passe ao cmdlet o endereço do proxy e o objeto:
$pass = ConvertTo-SecureString "pass" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("user", $pass)
$r = Invoke-WebRequest -UseBasicParsing -Uri "https://httpbin.org/ip" `
-Proxy "http://pr.proxynet.io:8000" -ProxyCredential $cred
$r | Select-Object StatusCode, StatusDescription | Format-List
$r.ContentStatusCode : 200
StatusDescription : OK
{
"origin": "203.0.113.42"
}O httpbin.org/ip devolve o endereço de onde a requisição veio, então um proxy que funciona mostra ali o IP de saída dele, e não o seu. O valor de -Proxy é um URI e mantém o esquema http:// mesmo com destinos HTTPS: ele descreve a conexão com o proxy, enquanto a página continua criptografada dentro do túnel CONNECT. Os dois parâmetros estão documentados na página do Invoke-WebRequest para o Windows PowerShell 5.1.
Sempre adicione -UseBasicParsing no 5.1. Sem ele, o cmdlet analisa o HTML com o motor do Internet Explorer e, desde a atualização de segurança da Microsoft de dezembro de 2025 para a CVE-2025-54100, pede confirmação antes, algo que um script agendado não consegue responder. Na nossa execução, uma chamada sem a opção falhou com Object reference not set to an instance of an object. O PowerShell 7 só faz análise básica e ignora a opção.
O Invoke-RestMethod aceita os mesmos parâmetros de proxy e devolve JSON já interpretado em vez de um objeto de resposta:
$ip = Invoke-RestMethod -Uri "https://api.ipify.org?format=json" `
-Proxy "http://pr.proxynet.io:8000" -ProxyCredential $cred
$ip.ipNos produtos residencial e móvel da Proxynet, o nome de usuário carrega o país, a cidade e a sessão escolhidos no Gerador de endpoints do painel, então o comando continua o mesmo seja qual for a saída que você escolher.
Como informar as credenciais do proxy?
A senha do proxy viaja em um objeto PSCredential, nunca dentro do endereço. O Get-Credential pede a senha de forma interativa; um script a monta a partir de uma string segura, como acima. A página da Microsoft sobre o ConvertTo-SecureString avisa que uma senha em texto puro na linha de comando vai parar nos logs de eventos e no histórico de comandos, então leia-a de uma variável de ambiente ou de um cofre de segredos:
$pass = ConvertTo-SecureString $env:PROXY_PASS -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($env:PROXY_USER, $pass)Três detalhes dos nossos testes:
user:pass@dentro de-Proxyé ignorado no 5.1.-Proxy "http://user:pass@pr.proxynet.io:8000"sem-ProxyCredentialterminou com(407) Proxy Authentication Required; o log do proxy não mostrou nenhuma credencial chegando.- Caracteres especiais não precisam de codificação. Uma senha
p@ss:w#rdpassou sem alterações peloPSCredential, enquanto a forma de URL precisaria de%40,%3Ae%23. - Uma sessão web mantém o proxy. Depois de
-Proxy ... -SessionVariable s, uma segunda chamada só com-WebSession $spassou de novo pelo proxy; o objeto de sessão guarda o proxy ao lado dos cookies.
O -ProxyUseDefaultCredentials envia, em vez disso, a conta do Windows do usuário atual, para proxies corporativos que autenticam contra o domínio; a documentação diz que ele não pode ser combinado com -ProxyCredential. Não testamos aqui: o nosso proxy só fala Basic.
A senha desaparece por completo quando o IP da máquina está autorizado no painel do proxy: -Proxy "http://pr.proxynet.io:8000" passa a ser a configuração inteira. A Proxynet aceita até 10 IPs na whitelist, o que combina com tarefas agendadas em um servidor de endereço fixo.
Como definir o proxy para todos os comandos?
$PSDefaultParameterValues é uma tabela hash de chaves Cmdlet:Parâmetro que o PowerShell aplica sempre que você omite o parâmetro. Duas entradas por cmdlet bastam:
$PSDefaultParameterValues["Invoke-WebRequest:Proxy"] = "http://pr.proxynet.io:8000"
$PSDefaultParameterValues["Invoke-WebRequest:ProxyCredential"] = $cred
$PSDefaultParameterValues["Invoke-RestMethod:Proxy"] = "http://pr.proxynet.io:8000"
$PSDefaultParameterValues["Invoke-RestMethod:ProxyCredential"] = $cred
Invoke-RestMethod -Uri "https://api.ipify.org?format=json" # passa pelo proxyAs chaves aceitam curingas, então "Invoke-*:Proxy" cobre os dois cmdlets em uma linha; as duas formas funcionaram no nosso teste. A tabela fica vazia em cada sessão nova, a menos que as linhas estejam no $PROFILE, e um script que roda com outra conta nunca vê o seu perfil, então deixe os parâmetros explícitos em tudo o que você entregar.
Sobrescrever com -Proxy $null em uma chamada direta falha com The cmdlet cannot run because the following parameter is missing: Proxy enquanto existir um padrão para ProxyCredential. Em vez disso, desative a tabela por um instante: $PSDefaultParameterValues["Disabled"] = $true, execute a chamada e volte o valor para $false. No nosso teste, a chamada com Disabled saiu direto e a seguinte passou de novo pelo proxy.
O PowerShell lê HTTP_PROXY e HTTPS_PROXY?
O Windows PowerShell 5.1 não lê. Com $env:HTTP_PROXY e $env:HTTPS_PROXY definidas e sem o parâmetro -Proxy, a nossa requisição foi direto ao destino; o proxy nunca a viu. O curl.exe, o git e o pip na mesma máquina seguem essas variáveis, daí a confusão.
O PowerShell 7 lê, segundo a documentação: desde o 7.0, os cmdlets pegam o proxy padrão do HttpClient.DefaultProxy do .NET, que no Windows lê primeiro HTTP_PROXY, HTTPS_PROXY, ALL_PROXY e a lista de exceções NO_PROXY e recorre às configurações de proxy do usuário quando as variáveis estão vazias.
# Apenas no PowerShell 7; o 5.1 ignora isso
$env:HTTPS_PROXY = "http://pr.proxynet.io:8000"
$env:NO_PROXY = "localhost,127.0.0.1,.internal.example"
Invoke-WebRequest -Uri "https://httpbin.org/ip" # pelo proxy
Invoke-WebRequest -Uri "https://httpbin.org/ip" -NoProxy # direto, apenas esta chamadaAs credenciais continuam em -ProxyCredential, por chamada ou por meio de $PSDefaultParameterValues, exatamente como no 5.1.
E o proxy do sistema do Windows e o netsh winhttp?
Sem -Proxy, o 5.1 recorre ao proxy das Opções da Internet do usuário atual, a configuração que o Windows mostra em Configurações, Rede e Internet, Proxy. A documentação do .NET Framework diz que o WebRequest.DefaultWebProxy lê primeiro o arquivo de configuração do aplicativo e, se ele não existir, o proxy das Opções da Internet do usuário. Um script que de repente sai por um proxy inesperado normalmente está seguindo essa configuração; Configuração de proxy no Windows e no Chrome mostra onde ela fica.
O Windows mantém um segundo registro de proxy para o WinHTTP, a biblioteca HTTP usada por serviços e componentes do sistema. Ele é gerenciado com netsh winhttp e não afeta os cmdlets do PowerShell, que usam o .NET. Os comandos abaixo vêm da referência do netsh da Microsoft e não foram executados aqui, porque mudam uma configuração da máquina inteira:
netsh winhttp show proxy
netsh winhttp set proxy proxy-server="pr.proxynet.io:8000" bypass-list="*.internal.example"
netsh winhttp import proxy source=ie
netsh winhttp reset proxyO set proxy aceita um servidor e uma lista de exceções separada por ponto e vírgula, e nada mais, então um proxy que pede usuário e senha é mais bem configurado por script com -ProxyCredential, ou deixado sem senha com uma whitelist de IP.
Como usar o proxy a partir de classes .NET em um script?
Scripts que chamam System.Net.WebClient ou HttpWebRequest diretamente não enxergam -Proxy; eles leem o WebRequest.DefaultWebProxy, que vale para o processo inteiro. Defini-lo uma vez faz essas classes e, no 5.1, cada Invoke-WebRequest sem o próprio -Proxy passarem pelo proxy:
$proxy = New-Object System.Net.WebProxy("http://pr.proxynet.io:8000")
$proxy.Credentials = New-Object System.Net.NetworkCredential("user", "pass")
$proxy.BypassList = @("^http://intranet\.example\.")
[System.Net.WebRequest]::DefaultWebProxy = $proxy
(New-Object System.Net.WebClient).DownloadString("https://api.ipify.org")A configuração vive só naquele processo do PowerShell. O BypassList guarda expressões regulares comparadas com a URL completa; no nosso teste, o padrão da intranet foi excluído do proxy e o host público não.
Uma regra do WebProxy nos custou uma hora: requisições para localhost ou 127.0.0.1 nunca usam proxy. O IsBypassed devolveu True para os dois mesmo com BypassProxyOnLocal em False, então todo teste contra um servidor web local saiu direto e parecia que o proxy funcionava. Teste contra um endereço público ou dê ao servidor local um nome de host com um ponto.
O Invoke-WebRequest aceita SOCKS5?
No Windows PowerShell 5.1, não. -Proxy "socks5://pr.proxynet.io:1080" para com The ServicePointManager does not support proxies with the socks5 scheme., e um endereço de proxy https:// falha do mesmo jeito, então o 5.1 só fala com proxies por HTTP simples.
O PowerShell 7.2 e versões mais novas rodam sobre o .NET 6 ou mais recente, e o anúncio de rede do .NET 6 da Microsoft documenta o suporte a SOCKS4, SOCKS4a e SOCKS5 no HttpClient por meio de um endereço de proxy socks5://. A referência do cmdlet não menciona SOCKS e não pudemos rodar o 7 aqui, então trate -Proxy "socks5://pr.proxynet.io:1080" como algo a verificar na sua versão.
No 5.1, o caminho prático é o cURL de verdade que vem com o Windows 10 e 11: curl.exe -x "socks5h://user:pass@pr.proxynet.io:1080" https://httpbin.org/ip, com socks5h para que o proxy resolva o nome do host. As opções estão explicadas em cURL com proxy; no lugar de 1080, use a porta SOCKS5 que o seu Gerador de endpoints mostra.
Exemplo: baixar uma lista de URLs pelo proxy com novas tentativas
O script baixa uma lista de URLs pelo proxy, tenta de novo as falhas temporárias com uma pausa crescente, para na hora diante de um 407 e imprime uma linha por URL. Ele só precisa do Windows PowerShell 5.1:
# fetch.ps1: cada URL da lista pelo proxy, com novas tentativas
$ErrorActionPreference = "Stop"
$ProxyUri = "http://pr.proxynet.io:8000"
$ProxyCred = New-Object System.Management.Automation.PSCredential (
"user", (ConvertTo-SecureString "pass" -AsPlainText -Force))
$urls = @(
"https://httpbin.org/ip",
"https://httpbin.org/status/503",
"https://httpbin.org/status/404",
"https://httpbin.org/headers"
)
$retryCodes = 408, 429, 500, 502, 503, 504
function Get-WithRetry {
param([string]$Url, [int]$Attempts = 4)
for ($i = 1; $i -le $Attempts; $i++) {
$sw = [System.Diagnostics.Stopwatch]::StartNew()
try {
$r = Invoke-WebRequest -UseBasicParsing -Uri $Url -Proxy $ProxyUri -ProxyCredential $ProxyCred -TimeoutSec 30
return [pscustomobject]@{ Url = $Url; Status = $r.StatusCode; Attempts = $i; Ms = $sw.ElapsedMilliseconds; Bytes = $r.RawContentLength }
} catch [System.Net.WebException] {
$code = 0
if ($_.Exception.Response) { $code = [int]$_.Exception.Response.StatusCode }
if ($code -eq 407) { throw "Proxy refused the credentials (407). Check user:pass or the IP whitelist." }
if (($code -in $retryCodes -or $code -eq 0) -and $i -lt $Attempts) {
$wait = [math]::Pow(2, $i - 1) # 1, 2, 4 segundos
Write-Warning "$Url -> $code ($($_.Exception.Status)); retry $i in $wait s"
Start-Sleep -Seconds $wait
continue
}
return [pscustomobject]@{ Url = $Url; Status = $code; Attempts = $i; Ms = $sw.ElapsedMilliseconds; Bytes = 0 }
}
}
}
$results = foreach ($u in $urls) { Get-WithRetry -Url $u }
$results | Format-Table -AutoSizeNa nossa execução, o endereço /status/503 respondeu 503 duas vezes, foi tentado de novo depois de 1 e 2 segundos e deu certo na terceira tentativa porque o servidor de teste se recupera; o 404 voltou sem nova tentativa:
WARNING: https://httpbin.org/status/503 -> 503 (ProtocolError); retry 1 in 1 s
WARNING: https://httpbin.org/status/503 -> 503 (ProtocolError); retry 2 in 2 s
Url Status Attempts Ms Bytes
--- ------ -------- -- -----
https://httpbin.org/ip 200 1 34 55
https://httpbin.org/status/503 200 3 11 65
https://httpbin.org/status/404 404 1 3 0
https://httpbin.org/headers 200 1 10 250Três escolhas importam. $_.Exception.Response.StatusCode é o único lugar em que o 5.1 expõe o status de uma requisição que falhou, porque um 4xx ou 5xx é lançado como erro em vez de devolvido. Um $code igual a 0 significa que não houve resposta nenhuma, como em um tempo limite esgotado, e também é tentado de novo. -TimeoutSec 30 limita cada tentativa; o padrão, 0, espera para sempre. O PowerShell 7 traz -MaximumRetryCount 3 -RetryIntervalSec 2 embutido, e a documentação diz que um 429 com Retry-After se sobrepõe a esse intervalo.
Cada Invoke-WebRequest abre a própria conexão com o proxy, então um gateway rotativo entrega a cada chamada um IP de saída diferente. Um login seguido de várias páginas precisa do contrário: uma sessão fixa no nome de usuário mantém o mesmo IP por 1 a 60 minutos nos Proxies residenciais, enquanto -SessionVariable mantém os cookies do seu lado.
Onde os scripts de proxy do PowerShell aparecem?
As tarefas agendadas são o lugar de sempre: uma tarefa noturna confere o preço e o estoque dos seus próprios anúncios como um comprador de outro país os vê, um script de monitoramento requisita o seu site de várias regiões e avisa quando a moeda ou o idioma estão errados, um agente de build atrás de um proxy corporativo instala módulos por ele. Uma API de parceiro que libera um único endereço é acessada de uma tarefa cuja saída nunca muda; os Proxies ISP dão a essa tarefa um IP dedicado que sobrevive a reinicializações.
Erros comuns de proxy no PowerShell e como corrigir
As mensagens aparecem como o Windows PowerShell 5.1 as imprime com a interface em inglês; em um Windows em português ou em alemão, a parte .NET do texto é traduzida.
The remote server returned an error: (407) Proxy Authentication Required.Falta-ProxyCredential, as credenciais estão dentro do endereço, a senha está errada ou o IP não está na whitelist.$_.Exception.Response.StatusCode.value__dá407em um blococatch; as causas estão reunidas em Como corrigir HTTP 407 Proxy Authentication Required.Unable to connect to the remote servercomStatus : ConnectFailure. Porta do proxy errada, um firewall no meio ou o proxy está fora do ar.The proxy name could not be resolved: 'pr.proxynet.io'. Um erro de digitação no nome do host ou DNS indisponível; a mensagem cita o proxy, não o destino.The operation has timed out.O-TimeoutSecé menor do que o proxy e o destino precisam; o nosso limite de 2 segundos contra uma página de 5 segundos produziu essa mensagem.The ServicePointManager does not support proxies with the socks5 scheme.Um endereço de proxysocks5://ouhttps://no 5.1; usehttp://, o PowerShell 7.2+ ou ocurl.exe.A parameter cannot be found that matches parameter name 'x'.Um comando do cURL digitado no 5.1, ondecurlé um alias doInvoke-WebRequest; escrevacurl.exe.Object reference not set to an instance of an object.Uma chamada do 5.1 sem-UseBasicParsingem um script.The cmdlet cannot run because the following parameter is missing: Proxy.-Proxy $nullenquanto o$PSDefaultParameterValuesainda guarda umProxyCredential; use a chaveDisabledno lugar.- O proxy é pulado em silêncio. O destino é
localhostou127.0.0.1, ou o script confia noHTTPS_PROXYno 5.1. Compare oapi.ipify.orgcom e sem-Proxy.
Guia de decisão
| Necessidade | Recomendação |
|---|---|
| Um comando pelo proxy | -Proxy mais -ProxyCredential |
| Todos os comandos de uma sessão | $PSDefaultParameterValues no $PROFILE |
| Nenhuma senha no script | Whitelist de IP no painel, só -Proxy |
| Proxy corporativo com login do Windows | -ProxyUseDefaultCredentials |
| Uma chamada sem o proxy | -NoProxy (7) ou a chave Disabled (5.1) |
| SOCKS5 | PowerShell 7.2+, ou curl.exe com socks5h:// |
Código com WebClient ou HttpWebRequest | [System.Net.WebRequest]::DefaultWebProxy |
| O mesmo IP de saída em um fluxo de login | Sessão fixa no nome de usuário |
| Serviços e Windows Update | netsh winhttp set proxy |
Perguntas frequentes
Como configurar um proxy para o Invoke-WebRequest?
Adicione -Proxy "http://host:port" e, se o proxy pedir senha, -ProxyCredential com um objeto PSCredential. Os mesmos dois parâmetros existem no Invoke-RestMethod e, segundo a documentação do PowerShellGet 2.x, no Install-Module.
Por que o Invoke-WebRequest devolve 407 Proxy Authentication Required?
Porque o proxy não recebeu credenciais utilizáveis. No 5.1, isso acontece quando o usuário e a senha são escritos no endereço em vez de em -ProxyCredential, quando a senha está errada ou quando o proxy espera o seu IP em uma whitelist e o endereço da máquina mudou.
O Invoke-WebRequest usa as configurações de proxy do Windows?
Sim, quando você não informa -Proxy. O Windows PowerShell 5.1 pega o proxy das Opções da Internet do usuário atual; o PowerShell 7 lê primeiro HTTP_PROXY e HTTPS_PROXY e recorre às configurações do usuário. O proxy do WinHTTP definido com netsh winhttp é um registro separado e nenhum dos dois o lê.
Como ignorar o proxy em uma única requisição no PowerShell?
No PowerShell 7, adicione -NoProxy a essa chamada. No 5.1, deixe o -Proxy de fora; se o $PSDefaultParameterValues o adicionar mesmo assim, coloque $PSDefaultParameterValues["Disabled"] = $true em volta da chamada. Para hosts inteiros, use NO_PROXY no 7 ou um BypassList em um objeto WebProxy no 5.1.
Dá para usar um proxy SOCKS5 com o Invoke-WebRequest?
No Windows PowerShell 5.1, não: ele rejeita o esquema socks5://. O PowerShell 7.2 e versões mais novas rodam sobre o .NET 6+, que suporta proxies SOCKS5 no HttpClient; verifique na sua versão. No 5.1, chame o curl.exe com socks5h:// no lugar.
Como verificar se o PowerShell está mesmo usando o proxy?
Requisite https://api.ipify.org uma vez sem e uma vez com -Proxy: dois endereços diferentes, o segundo no país do proxy, significam que o proxy está em uso. O mesmo endereço duas vezes significa que a chamada saiu direto, quase sempre porque o destino era localhost ou porque o 5.1 ignorou as variáveis que você definiu.
Em resumo
Passe o proxy ao Invoke-WebRequest e ao Invoke-RestMethod com -Proxy e um PSCredential em -ProxyCredential, nunca dentro do endereço; defina os dois uma vez em $PSDefaultParameterValues quando todas as chamadas devem usá-lo. O Windows PowerShell 5.1 ignora HTTP_PROXY, recorre às Opções da Internet, deixa os endereços de loopback fora do proxy e não fala SOCKS5; o PowerShell 7 lê as variáveis, acrescenta -NoProxy e novas tentativas e aceita SOCKS5 a partir do 7.2. Mantenha -UseBasicParsing e -TimeoutSec em todo script do 5.1 e teste contra um endereço público. Os endpoints que aceitam exatamente esses parâmetros estão na página de proxies da Proxynet.




