Utiliser des proxies en PowerShell avec Invoke-WebRequest et Invoke-RestMethod

Guide pratique pour configurer des proxies résidentiels dans PowerShell : paramètres intégrés, géo-ciblage, sessions persistantes, rotation d'IP, retry/backoff et bonnes pratiques de production.

Using Proxies in PowerShell: A Code-First Guide to Invoke-WebRequest & Invoke-RestMethod

Les administrateurs Windows et les ingénieurs d'automatisation utilisent PowerShell pour tout, de l'appel d'API REST au web scraping en passant par la surveillance de prix. Mais dès qu'un endpoint détecte une IP datacenter — Azure, AWS, OVH — il renvoie un 403 ou déclenche un CAPTCHA. Savoir utiliser des proxies en PowerShell devient alors indispensable pour maintenir vos scripts fiables. Ce guide montre comment configurer un proxy avec Invoke-WebRequest et Invoke-RestMethod, encoder le géo-ciblage et les sessions collantes dans le nom d'utilisateur, gérer les cookies, implémenter des retries, et déployer en production avec ProxyHat.

Pourquoi utiliser des proxies en PowerShell

PowerShell s'appuie sur System.Net.Http.HttpClient sous le capot pour Invoke-WebRequest et Invoke-RestMethod. Par défaut, ces cmdlets utilisent les paramètres proxy du système (WinINET / netsh winhttp set proxy). En environnement cloud — Azure Automation, AWS Lambda, conteneurs Docker — ces paramètres sont souvent absents ou mal configurés, et l'IP sortante appartient à une plage datacenter facilement identifiable.

De nombreux sites bloquent les plages d'IP datacenter. D'après une analyse de Mozilla Developer Network, les serveurs renvoient fréquemment 429 Too Many Requests ou 403 Forbidden avec un en-tête Retry-After. Les proxies résidentiels acheminent votre trafic via des IP attribuées à de vrais FAI, réduisant le risque de blocage de plus de 90% sur les endpoints agressivement protégés.

Les cas d'usage typiques en PowerShell :

  • Scraping SERP pour du suivi de positionnement SEO
  • Surveillance de prix e-commerce multi-pays
  • Collecte de données publiques pour l'entraînement de modèles IA
  • Tests QA d'API géo-restreintes

Paramètres intégrés de Invoke-WebRequest et Invoke-RestMethod

Les cmdlets PowerShell exposent trois paramètres proxy natifs :

ParamètreRôleExemple
-ProxyURL du proxy (HTTP ou HTTPS)'http://gate.proxyhat.com:8080'
-ProxyCredentialObjet PSCredential (user + pass)(Get-Credential)
-ProxyUseDefaultCredentialsUtilise les creds Windows courants$true

Appel simple avec authentification proxy

# Demande interactive des credentials proxy
$proxyCred = Get-Credential -UserName 'user-country-US' -Message 'Proxy ProxyHat'

$response = Invoke-WebRequest `
    -Uri 'https://httpbin.org/ip' `
    -Proxy 'http://gate.proxyhat.com:8080' `
    -ProxyCredential $proxyCred `
    -Method Get

$response.Content
# { "origin": "198.51.100.42" }  -- IP résidentielle US

Invoke-RestMethod avec proxy et parsing JSON

$proxyCred = Get-Credential -UserName 'user-country-DE-city-berlin' -Message 'Proxy ProxyHat'

$data = Invoke-RestMethod `
    -Uri 'https://api.example.com/v1/products?page=1' `
    -Proxy 'http://gate.proxyhat.com:8080' `
    -ProxyCredential $proxyCred `
    -Headers @{ 'Accept' = 'application/json' }

$data.products | Select-Object id, name, price

Encoder le géo-ciblage et les sessions collantes

ProxyHat encode les options de routage directement dans le nom d'utilisateur. Vous pouvez spécifier un pays (user-country-US), une ville (user-country-DE-city-berlin), et une session collante (user-session-abc123) pour conserver la même IP sur plusieurs requêtes.

Construction d'un PSCredential programmatique

function New-ProxyHatCredential {
    param(
        [string]$Country = 'US',
        [string]$City   = '',
        [string]$Session = ''
    )

    $user = 'user-country-' + $Country
    if ($City)   { $user += '-city-' + $City.ToLower() }
    if ($Session) { $user += '-session-' + $Session }

    # Mot de passe stocké en variable d'environnement
    $pass = $env:PROXYHAT_PASS
    $securePass = ConvertTo-SecureString $pass -AsPlainText -Force

    return New-Object System.Management.Automation.PSCredential($user, $securePass)
}

# Session collante : la même IP pour toutes les requêtes
$cred = New-ProxyHatCredential -Country 'FR' -City 'paris' -Session 'order-flow-42'

Invoke-WebRequest -Uri 'https://httpbin.org/ip' `
    -Proxy 'http://gate.proxyhat.com:8080' `
    -ProxyCredential $cred

Contrôle fin avec System.Net.WebProxy

Pour des scénarios avancés — par exemple avec HttpClient directement ou des bibliothèques .NET tierces — vous pouvez construire un objet WebProxy explicite :

Add-Type -AssemblyName System.Net.Http

$proxy = New-Object System.Net.WebProxy('http://gate.proxyhat.com:8080', $true)
$proxy.Credentials = New-Object System.Net.NetworkCredential('user-country-US-session-rpt7', $env:PROXYHAT_PASS)

$handler = New-Object System.Net.Http.HttpClientHandler
$handler.Proxy = $proxy
$handler.UseProxy = $true

$client = New-Object System.Net.Http.HttpClient($handler)
$client.Timeout = [TimeSpan]::FromSeconds(30)

$response = $client.GetAsync('https://httpbin.org/headers').Result
$body = $response.Content.ReadAsStringAsync().Result
Write-Host $body

Cette approche est utile quand vous souhaitez réutiliser un HttpClient à travers plusieurs appels dans un module PowerShell custom, ou intégrer le proxy dans un code C# embarqué via Add-Type.

Persister cookies et en-têtes avec WebRequestSession

De nombreux sites nécessitent un enchaînement de requêtes — login, récupération d'un token CSRF, puis appel authentifié. Le paramètre -SessionVariable crée un objet WebRequestSession qui persiste les cookies et certains en-têtes entre les appels.

# Étape 1 : GET initial pour récupérer les cookies
$proxyCred = New-ProxyHatCredential -Country 'GB' -Session 'login-flow-1'

$resp1 = Invoke-WebRequest -Uri 'https://example.com/login' `
    -Proxy 'http://gate.proxyhat.com:8080' `
    -ProxyCredential $proxyCred `
    -SessionVariable session `
    -UserAgent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' `
    -Headers @{ 'Accept-Language' = 'en-GB,en;q=0.9' }

# Extraire le token CSRF depuis le HTML
$csrfToken = ($resp1.InputFields | Where-Object { $_.name -eq 'csrf_token' }).value

# Étape 2 : POST de login en réutilisant la session
$resp2 = Invoke-WebRequest -Uri 'https://example.com/login' `
    -Proxy 'http://gate.proxyhat.com:8080' `
    -ProxyCredential $proxyCred `
    -WebSession $session `
    -Method Post `
    -Body @{ csrf_token = $csrfToken; username = 'myuser'; password = 'mypass' }

# Étape 3 : Appel authentifié
$resp3 = Invoke-RestMethod -Uri 'https://example.com/api/dashboard' `
    -Proxy 'http://gate.proxyhat.com:8080' `
    -ProxyCredential $proxyCred `
    -WebSession $session

$resp3.stats

Le paramètre -UserAgent est crucial : un User-Agent par défaut Mozilla/5.0 (Windows NT; ...) PowerShell/7.4 est un signal immédiat de bot. Utilisez un UA de navigateur réaliste et cohérent avec vos en-têtes Accept-Language et Accept-Encoding.

Proxy résidentiel pour endpoints bloquant les datacenters

Les API et sites e-commerce détectent les IP datacenter via des bases de données comme les numéros de système autonome (ASN) publiées par les registres régionaux (RIPE, ARIN). Si votre PowerShell tourne sur une VM Azure, l'ASN AS8075 (Microsoft) est flaggué instantanément. Les proxies résidentiels de ProxyHat utilisent des IP attribuées par des FAI grand public (Comcast, Orange, Deutsche Telekom), indiscernables d'un vrai navigateur.

Exemple complet : pagination JSON avec rotation et retry

# --- Configuration ---
$proxyUrl = 'http://gate.proxyhat.com:8080'
$baseApi = 'https://api.target-site.com/v2/items'
$maxPages = 50
$delaySec = 2

# --- TLS 1.2+ obligatoire pour la plupart des APIs modernes ---
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13

# --- Fonction de récupération avec retry/backoff ---
function Get-PageWithRetry {
    param(
        [int]$Page,
        [string]$Country
    )

    # Rotation : nouvelle session à chaque page = nouvelle IP
    $sessionId = 'page-' + $Page + '-' + [Guid]::NewGuid().ToString('N').Substring(0,8)
    $cred = New-ProxyHatCredential -Country $Country -Session $sessionId

    $uri = "$baseApi?page=$Page&limit=100"

    try {
        $result = Invoke-RestMethod `
            -Uri $uri `
            -Proxy $proxyUrl `
            -ProxyCredential $cred `
            -Headers @{ 'Accept' = 'application/json' } `
            -UserAgent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' `
            -MaximumRetryCount 3 `
            -RetryIntervalSec 5 `
            -TimeoutSec 30

        return $result
    }
    catch [System.Net.WebException] {
        $statusCode = [int]$_.Exception.Response.StatusCode
        Write-Warning "Page $Page : HTTP $statusCode"
        if ($statusCode -eq 403) {
            Write-Warning 'IP potentiellement bloquée. Passage au pays suivant.'
            return $null
        }
        throw  # Relancer pour les autres erreurs
    }
    catch {
        Write-Warning "Page $Page : $($_.Exception.Message)"
        return $null
    }
}

# --- Boucle de pagination ---
$allItems = @()
$countries = @('US', 'GB', 'DE', 'FR', 'NL')

for ($page = 1; $page -le $maxPages; $page++) {
    $country = $countries[($page - 1) % $countries.Count]
    $data = Get-PageWithRetry -Page $page -Country $country

    if ($null -eq $data -or $data.items.Count -eq 0) {
        Write-Host "Fin de pagination à la page $page"
        break
    }

    $allItems += $data.items
    Write-Host "Page $page ($country) : $($data.items.Count) items récupérés"
    Start-Sleep -Seconds $delaySec
}

Write-Host "Total : $($allItems.Count) items"
$allItems | Export-Csv -Path 'items.csv' -NoTypeInformation -Encoding UTF8

Ce script illustre plusieurs patterns de production :

  • Rotation d'IP par page : chaque appel génère un nouvel identifiant de session, déclenchant une nouvelle IP résidentielle.
  • Rotation de pays : si un pays est bloqué, le suivant prend le relais.
  • Retry natif : -MaximumRetryCount 3 et -RetryIntervalSec 5 gèrent automatiquement les 429 et 503.
  • Backoff respectant Retry-After : PowerShell 7 lit l'en-tête Retry-After et attend en conséquence.

Astuces de production

Variable d'environnement HTTPS_PROXY pour les processus enfants

Les outils CLI invoqués depuis PowerShell — curl, git, dotnet, node — respectent les variables d'environnement standard :

# Variables d'environnement proxy pour les processus enfants
$env:HTTP_PROXY  = 'http://user-country-US:' + $env:PROXYHAT_PASS + '@gate.proxyhat.com:8080'
$env:HTTPS_PROXY = $env:HTTP_PROXY
$env:NO_PROXY    = 'localhost,127.0.0.1,.internal.corp'

# curl utilisera automatiquement le proxy
curl.exe https://httpbin.org/ip

# git aussi
git clone https://github.com/example/repo.git

Note : certains outils ne supportent pas l'authentification inline dans l'URL proxy. Dans ce cas, utilisez un fichier .netrc ou une variable séparée pour les credentials.

Configuration TLS

PowerShell 5.1 sur Windows Server 2012/2016 utilise TLS 1.0 par défaut, ce qui provoque des échecs de handshake sur la plupart des APIs modernes. Forcez TLS 1.2+ systématiquement :

# En haut de chaque script
[Net.ServicePointManager]::SecurityProtocol = `
    [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13

# En PowerShell 7+, préférez la propriété par HttpClientHandler :
# TLS est géré par SChannel avec les paramètres OS par défaut

Parallélisme avec ForEach-Object -Parallel (PowerShell 7+)

$urls = 1..100 | ForEach-Object { "https://api.target-site.com/v2/items?page=$_&limit=100" }

$results = $urls | ForEach-Object -Parallel {
    $page = $_ -replace '.*page=(\d+).*', '$1'
    $sessionId = 'par-' + $page + '-' + [Guid]::NewGuid().ToString('N').Substring(0,8)
    $user = 'user-country-US-session-' + $sessionId
    $securePass = ConvertTo-SecureString $using:env:PROXYHAT_PASS -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential($user, $securePass)

    try {
        $data = Invoke-RestMethod -Uri $_ `
            -Proxy 'http://gate.proxyhat.com:8080' `
            -ProxyCredential $cred `
            -TimeoutSec 30 `
            -MaximumRetryCount 2 `
            -RetryIntervalSec 3
        return [PSCustomObject]@{ Page = $page; Count = $data.items.Count }
    }
    catch {
        return [PSCustomObject]@{ Page = $page; Count = 0; Error = $_.Exception.Message }
    }
} -ThrottleLimit 10

$results | Format-Table

Avec -ThrottleLimit 10, vous lancez 10 requêtes simultanées, chacune avec sa propre IP résidentielle via un identifiant de session unique. C'est idéal pour le web scraping à grande échelle ou le suivi de SERP sur des milliers de mots-clés.

SOCKS5 : quand HTTP ne suffit pas

PowerShell 7 supporte nativement les proxies SOCKS5 via -Proxy 'socks5://gate.proxyhat.com:1080'. SOCKS5 est utile pour le tunneling TCP pur (websockets, connexions non-HTTP) :

$cred = New-ProxyHatCredential -Country 'JP' -Session 'socks-test'

Invoke-WebRequest -Uri 'https://httpbin.org/ip' `
    -Proxy 'socks5://gate.proxyhat.com:1080' `
    -ProxyCredential $cred

Éthique et cadre légal

L'utilisation de proxies ne vous exempt pas des obligations légales. Respectez systématiquement ces principes :

  • Données publiques uniquement : ne scrapez pas de contenu derrière un login sans autorisation explicite.
  • robots.txt : vérifiez le fichier robots.txt du site cible et honorez les directives Disallow.
  • Conditions d'utilisation : la lecture des ToS peut interdire l'accès automatisé, même pour des données publiques.
  • CFAA (États-Unis) : le Computer Fraud and Abuse Act peut s'appliquer en cas d'accès non autorisé à un système protégé.
  • RGPD (Union européenne) : les données personnelles collectées doivent avoir une base légale et respecter les droits des personnes concernées.
  • API officielle d'abord : si une API publique existe, utilisez-la en priorité plutôt que de scraper le HTML.

Pour approfondir le cadre légal du scraping, consultez les informations sur le CFAA et les guidelines officiels du RGPD.

Points clés à retenir

  • Utilisez -Proxy, -ProxyCredential et -SessionVariable pour configurer un proxy résidentiel en une ligne.
  • Encodez le géo-ciblage et les sessions directement dans le nom d'utilisateur : user-country-FR-city-paris-session-abc123.
  • Les proxies résidentiels sont indispensables pour les endpoints bloquant les plages datacenter Azure/AWS.
  • Activez TLS 1.2+ et utilisez -MaximumRetryCount/-RetryIntervalSec pour la résilience.
  • En PowerShell 7, ForEach-Object -Parallel avec -ThrottleLimit permet une parallélisation massive avec rotation d'IP.
  • Respectez toujours robots.txt, les ToS, le CFAA et le RGPD.

ProxyHat fournit des proxies résidentiels, mobiles et datacenter accessibles via gate.proxyhat.com:8080 (HTTP) et gate.proxyhat.com:1080 (SOCKS5). Le SDK ProxyHat partage les mêmes endpoints et formats d'authentification. Consultez notre tarification et la liste des localisations disponibles pour démarrer.

Prêt à commencer ?

Accédez à plus de 50M d'IPs résidentielles dans plus de 148 pays avec filtrage IA.

Voir les tarifsProxies résidentiels
← Retour au Blog