تنظیمات پروکسی در PowerShell: Invoke-WebRequest با پروکسی

تاریخ انتشار:

15 دقیقه مطالعه

Acar Diveroli
نویسنده: Acar Diveroli
خط ⁦Invoke-WebRequest -Proxy⁩ با مکان‌نمای آبی، رد درخواست از میان پروکسی، ⁦StatusCode : 200⁩ و نشان آی‌پی خروجی
فهرست مطالب

اسکریپتی که روی لپ‌تاپ شما بی‌مشکل اجرا می‌شد به سرور منتقل می‌شود، یا حالا باید فهرست قیمتی را از دید بازدیدکننده‌ای از کشور دیگر بخواند، و هر فراخوانی Invoke-WebRequest باید از پروکسی خارج شود. PowerShell پارامترهای این کار را دارد. فقط در ⁦Windows PowerShell 5.1⁩ و ⁦PowerShell 7⁩ متفاوت رفتار می‌کنند، و رایج‌ترین میان‌بر، یعنی نوشتن user:pass@ درون آدرس پروکسی، در 5.1 با خطای 407 شکست می‌خورد بی‌آنکه بگوید چرا.

این نوشته -Proxy و -ProxyCredential، اطلاعات ورود بدون پرسش تعاملی، پروکسی برای همه فراخوانی‌ها، متغیرهای محیطی و پروکسی سیستم ویندوز، SOCKS5، یک اسکریپت دانلود با تلاش دوباره و متن دقیق خطاها را پوشش می‌دهد. همه نمونه‌های 5.1 روی ⁦Windows PowerShell 5.1⁩ (بیلد 26100) در برابر یک پروکسی محلی که نام کاربری و رمز می‌خواهد اجرا شدند. ⁦PowerShell 7⁩ روی ماشین آزمایش نصب نبود، پس رفتار آن از مستندات مایکروسافت آمده و همین‌طور هم علامت‌گذاری شده است.

⁦Windows PowerShell 5.1⁩ یا ⁦PowerShell 7⁩: چرا مهم است؟

این دو نسخه درخواست‌های وب را از دو پشته HTTP متفاوت می‌فرستند، پس یک تنظیم پروکسی ممکن است در یکی کار کند و در دیگری نادیده گرفته شود. ⁦Windows PowerShell 5.1⁩ همراه ویندوز عرضه می‌شود و کلاس HttpWebRequest از ⁦.NET Framework⁩ را به کار می‌برد؛ ⁦PowerShell 7⁩ جداگانه دانلود می‌شود و HttpClient را به کار می‌برد. $PSVersionTable.PSVersion می‌گوید اسکریپت زیر کدام‌یک اجرا می‌شود.

رفتار⁦Windows PowerShell 5.1⁩⁦PowerShell 7.x⁩
-Proxy، -ProxyCredentialبلهبله
HTTP_PROXY، HTTPS_PROXY، NO_PROXYنادیده گرفته می‌شوداز 7.0 خوانده می‌شود
پروکسی وقتی هیچ‌کدام داده نشدهInternet Options کاربرمتغیرها، سپس تنظیمات کاربر
سوئیچ -NoProxyندارداز 6.0
آدرس SOCKS5ندارد7.2 به بعد
نام‌های مستعار curl و wgetبه Invoke-WebRequest اشاره می‌کنندحذف شده
تلاش دوباره درون‌ساختندارد-MaximumRetryCount

ستون 5.1 همان چیزی است که ما مشاهده کردیم؛ ستون ⁦7.x⁩ از مرجع Invoke-WebRequest برای ⁦PowerShell 7.5⁩ پیروی می‌کند.

Invoke-WebRequest چگونه درخواست را از طریق پروکسی می‌فرستد؟

  1. PowerShell نام میزبان پروکسی را به آی‌پی تبدیل می‌کند، نه نام مقصد را، و یک اتصال TCP به پورت پروکسی باز می‌کند.
  2. برای مقصد http:// کل URL را به پروکسی می‌فرستد (GET http://httpbin.org/ip HTTP/1.1). پروکسی صفحه را می‌گیرد و بازمی‌گرداند، پس می‌تواند درخواست را بخواند.
  3. برای مقصد https:// درخواست CONNECT httpbin.org:443 را می‌فرستد. پس از آنکه پروکسی با 200 Connection Established پاسخ داد، دست‌دهی TLS با سایت درون همین تونل انجام می‌شود؛ پروکسی فقط نام میزبان و پورت را می‌بیند.
  4. اطلاعات ورود فقط پس از یک چالش فرستاده می‌شود. تلاش اول هیچ هدر Proxy-Authorization ندارد، پروکسی با 407 و Proxy-Authenticate: Basic پاسخ می‌دهد و ⁦.NET⁩ درخواست را با این هدر تکرار می‌کند. کد وضعیت 407 و این چالش در ⁦RFC 9110⁩ تعریف شده‌اند؛ 5.1 از پیش احراز هویت نمی‌کند، پس پروکسی آزمایشی ما هر فراخوانی موفق را به شکل این جفت سطر ثبت کرد:
text
11:02:56 407 GET http://httpbin.org/ip (no Proxy-Authorization)
11:02:56 GET http://httpbin.org/ip user=user
  1. مقصد به آی‌پی خروجی پروکسی پاسخ می‌دهد. cmdlet شیئی با StatusCode، Headers و Content برمی‌گرداند؛ در 5.1 وضعیت غیر از 2xx به جای آن به یک خطای پایان‌دهنده (terminating error) تبدیل می‌شود.

چگونه از Invoke-WebRequest با پروکسی استفاده کنیم؟

یک شیء اطلاعات ورود بسازید، سپس آدرس پروکسی و آن شیء را به cmdlet بدهید:

powershell
$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.Content
text
StatusCode        : 200
StatusDescription : OK

{
  "origin": "203.0.113.42"
}

نشانی httpbin.org/ip آدرسی را برمی‌گرداند که درخواست از آن آمده است، پس پروکسی سالم به جای آی‌پی شما آی‌پی خروجی خودش را آنجا نشان می‌دهد. مقدار -Proxy یک URI است و حتی برای مقصدهای HTTPS طرح http:// را نگه می‌دارد: این مقدار اتصال به پروکسی را توصیف می‌کند، در حالی که صفحه درون تونل CONNECT رمزگذاری‌شده می‌ماند. هر دو پارامتر در صفحه Invoke-WebRequest برای ⁦Windows PowerShell 5.1⁩ مستند شده‌اند.

در 5.1 همیشه -UseBasicParsing را اضافه کنید. بدون آن cmdlet متن HTML را با موتور Internet Explorer تجزیه می‌کند و از به‌روزرسانی امنیتی دسامبر 2025 مایکروسافت برای ⁦CVE-2025-54100⁩ به بعد، اول تأیید می‌خواهد؛ چیزی که اسکریپت زمان‌بندی‌شده نمی‌تواند پاسخ دهد. در اجرای ما فراخوانی بدون این سوئیچ با Object reference not set to an instance of an object. شکست خورد. ⁦PowerShell 7⁩ فقط تجزیه پایه انجام می‌دهد و این سوئیچ را نادیده می‌گیرد.

Invoke-RestMethod همان پارامترهای پروکسی را می‌گیرد و به جای شیء پاسخ، JSON تجزیه‌شده برمی‌گرداند:

powershell
$ip = Invoke-RestMethod -Uri "https://api.ipify.org?format=json" `
    -Proxy "http://pr.proxynet.io:8000" -ProxyCredential $cred
$ip.ip

در محصولات مسکونی و موبایل Proxynet نام کاربری کشور، شهر و نشستی را که در سازنده نقطه اتصال (Endpoint Generator) پنل انتخاب کرده‌اید با خود دارد، پس هر خروجی را که برگزینید دستور یکسان می‌ماند.

اطلاعات ورود پروکسی را چگونه بدهیم؟

رمز پروکسی در یک شیء PSCredential جابه‌جا می‌شود، هرگز درون آدرس. Get-Credential آن را به‌صورت تعاملی می‌پرسد؛ اسکریپت آن را مانند بالا از یک رشته امن (secure string) می‌سازد. صفحه ConvertTo-SecureString مایکروسافت هشدار می‌دهد که رمز متنی در خط فرمان به گزارش رویدادها و تاریخچه دستورها راه می‌یابد، پس آن را از یک متغیر محیطی یا یک مخزن محرمانه (secret store) بخوانید:

powershell
$pass = ConvertTo-SecureString $env:PROXY_PASS -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($env:PROXY_USER, $pass)

سه نکته از آزمایش‌های ما:

  • user:pass@ درون -Proxy در 5.1 نادیده گرفته می‌شود. -Proxy "http://user:pass@pr.proxynet.io:8000" بدون -ProxyCredential به (407) Proxy Authentication Required ختم شد؛ گزارش پروکسی نشان داد هیچ اطلاعات ورودی نرسیده است.
  • نویسه‌های ویژه به کدگذاری نیاز ندارند. رمز p@ss:w#rd بدون تغییر از PSCredential عبور کرد، در حالی که شکل URL آن به %40، %3A و %23 نیاز داشت.
  • نشست وب پروکسی را نگه می‌دارد. پس از -Proxy ... -SessionVariable s، فراخوانی دوم فقط با -WebSession $s دوباره از پروکسی گذشت؛ شیء نشست پروکسی را کنار کوکی‌ها ذخیره می‌کند.

-ProxyUseDefaultCredentials به جای آن حساب ویندوزی کاربر فعلی را می‌فرستد، برای پروکسی‌های سازمانی که با دامنه احراز هویت می‌کنند؛ مستندات می‌گوید نمی‌توان آن را با -ProxyCredential ترکیب کرد. اینجا آزمایش نشده: پروکسی ما فقط Basic بلد است.

وقتی آی‌پی ماشین در پنل پروکسی مجاز شده باشد، رمز به‌کلی کنار می‌رود: آن وقت -Proxy "http://pr.proxynet.io:8000" کل تنظیم است. Proxynet تا 10 آی‌پی در لیست سفید می‌پذیرد، که برای کارهای زمان‌بندی‌شده روی سروری با آدرس ثابت مناسب است.

پروکسی را چگونه برای همه دستورها تنظیم کنیم؟

$PSDefaultParameterValues یک جدول هش با کلیدهای Cmdlet:Parameter است که PowerShell هر بار که پارامتر را ننویسید اعمال می‌کند. دو ورودی برای هر cmdlet کافی است:

powershell
$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"   # goes through the proxy

کلیدها نویسه عام (wildcard) می‌پذیرند، پس "Invoke-*:Proxy" هر دو cmdlet را در یک سطر پوشش می‌دهد؛ هر دو شکل در آزمایش ما کار کرد. این جدول در هر نشست تازه خالی است مگر آنکه سطرها در $PROFILE باشند، و اسکریپتی که زیر حساب دیگری اجرا می‌شود هرگز پروفایل شما را نمی‌بیند، پس در هر چیزی که تحویل می‌دهید پارامترها را صریح نگه دارید.

بازنویسی با -Proxy $null برای یک فراخوانی مستقیم، تا وقتی مقدار پیش‌فرضی برای ProxyCredential وجود دارد، با The cmdlet cannot run because the following parameter is missing: Proxy شکست می‌خورد. به جای آن جدول را برای لحظه‌ای غیرفعال کنید: $PSDefaultParameterValues["Disabled"] = $true، فراخوانی را اجرا کنید، آن را به $false برگردانید. در آزمایش ما فراخوانی Disabled مستقیم رفت و فراخوانی بعدی دوباره از پروکسی.

آیا PowerShell متغیرهای HTTP_PROXY و HTTPS_PROXY را می‌خواند؟

⁦Windows PowerShell 5.1⁩ نمی‌خواند. با تنظیم $env:HTTP_PROXY و $env:HTTPS_PROXY و بدون پارامتر -Proxy، درخواست ما یکراست به مقصد رفت؛ پروکسی هرگز آن را ندید. curl.exe، git و pip روی همان ماشین این متغیرها را رعایت می‌کنند و سردرگمی از همین‌جاست.

⁦PowerShell 7⁩ بر اساس مستنداتش می‌خواند: از 7.0 به بعد این دو cmdlet پروکسی پیش‌فرض را از HttpClient.DefaultProxy در ⁦.NET⁩ می‌گیرند که در ویندوز اول HTTP_PROXY، HTTPS_PROXY، ALL_PROXY و فهرست استثنای NO_PROXY را می‌خواند و وقتی متغیرها خالی باشند به تنظیمات پروکسی کاربر برمی‌گردد.

powershell
# PowerShell 7 only; 5.1 ignores these
$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"            # proxied
Invoke-WebRequest -Uri "https://httpbin.org/ip" -NoProxy   # direct, this call only

اطلاعات ورود همچنان جایش در -ProxyCredential است، برای هر فراخوانی یا از طریق $PSDefaultParameterValues، دقیقاً مانند 5.1.

تکلیف پروکسی سیستم ویندوز و netsh winhttp چیست؟

بدون -Proxy، نسخه 5.1 به پروکسی Internet Options (گزینه‌های اینترنت) کاربر فعلی برمی‌گردد؛ همان تنظیمی که ویندوز زیر Settings > Network & internet > Proxy نشان می‌دهد. مستندات ⁦.NET Framework⁩ می‌گوید WebRequest.DefaultWebProxy اول فایل پیکربندی برنامه را می‌خواند و در غیر این صورت پروکسی Internet Options کاربر را. اسکریپتی که ناگهان از پروکسی غیرمنتظره‌ای خارج می‌شود معمولاً دنبال همین تنظیم می‌رود؛ تنظیم پروکسی در ویندوز و کروم نشان می‌دهد این تنظیم کجاست.

ویندوز یک مخزن پروکسی دوم برای WinHTTP نگه می‌دارد؛ کتابخانه HTTP که سرویس‌ها و مؤلفه‌های سیستم به کار می‌برند. این مخزن با netsh winhttp مدیریت می‌شود و بر cmdletهای PowerShell که از ⁦.NET⁩ استفاده می‌کنند اثری ندارد. دستورهای زیر از مرجع netsh مایکروسافت آمده‌اند و اینجا اجرا نشدند، چون یک تنظیم سراسری ماشین را تغییر می‌دهند:

text
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 proxy

set proxy یک سرور و یک فهرست استثنای جداشده با نقطه‌ویرگول می‌گیرد و نه چیز دیگر، پس پروکسی‌ای که نام کاربری و رمز می‌خواهد بهتر است در هر اسکریپت با -ProxyCredential پیکربندی شود، یا با لیست سفید آی‌پی بی‌نیاز از رمز شود.

چگونه از کلاس‌های ⁦.NET⁩ در اسکریپت از پروکسی استفاده کنیم؟

اسکریپت‌هایی که مستقیم System.Net.WebClient یا HttpWebRequest را فراخوانی می‌کنند -Proxy را نمی‌بینند؛ آن‌ها WebRequest.DefaultWebProxy سراسری فرایند را می‌خوانند. یک بار تنظیم کردن آن، این کلاس‌ها و در 5.1 هر Invoke-WebRequest بدون -Proxy مخصوص به خود را از پروکسی عبور می‌دهد:

powershell
$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")

این تنظیم فقط در همان فرایند PowerShell زنده است. BypassList عبارت‌های باقاعده (regular expression) نگه می‌دارد که با URL کامل تطبیق داده می‌شوند؛ در آزمایش ما الگوی اینترانت از پروکسی معاف شد و میزبان عمومی نه.

یک قاعده WebProxy یک ساعت از ما گرفت: درخواست‌ها به localhost یا 127.0.0.1 هرگز از پروکسی استفاده نمی‌کنند. IsBypassed برای هر دو True برگرداند، حتی با BypassProxyOnLocal برابر False، پس هر آزمایش در برابر یک وب‌سرور محلی مستقیم رفت و طوری به نظر می‌رسید که انگار پروکسی کار می‌کند. در برابر یک آدرس عمومی آزمایش کنید، یا به سرور محلی نام میزبانی بدهید که یک نقطه در آن باشد.

آیا Invoke-WebRequest از SOCKS5 پشتیبانی می‌کند؟

در ⁦Windows PowerShell 5.1⁩ نه. -Proxy "socks5://pr.proxynet.io:1080" با The ServicePointManager does not support proxies with the socks5 scheme. متوقف می‌شود و آدرس پروکسی https:// هم به همین شکل شکست می‌خورد، پس 5.1 فقط از راه HTTP ساده با پروکسی‌ها حرف می‌زند.

⁦PowerShell 7.2⁩ و بعد از آن روی ⁦.NET 6⁩ یا جدیدتر اجرا می‌شوند و اعلامیه شبکه ⁦.NET 6⁩ مایکروسافت پشتیبانی SOCKS4، SOCKS4a و SOCKS5 را در HttpClient از طریق آدرس پروکسی socks5:// مستند می‌کند. مرجع cmdlet از SOCKS نامی نمی‌برد و ما نتوانستیم 7 را اینجا اجرا کنیم، پس -Proxy "socks5://pr.proxynet.io:1080" را چیزی بدانید که باید روی نسخه خودتان بررسی کنید.

در 5.1 راه عملی cURL واقعی است که همراه ویندوز 10 و 11 عرضه می‌شود: curl.exe -x "socks5h://user:pass@pr.proxynet.io:1080" https://httpbin.org/ip، با socks5h تا نام میزبان را خود پروکسی به آی‌پی تبدیل کند. گزینه‌ها در استفاده از cURL با پروکسی توضیح داده شده‌اند؛ به جای 1080 پورت SOCKS5 را بگذارید که سازنده نقطه اتصال شما نشان می‌دهد.

نمونه: دریافت فهرستی از URLها از طریق پروکسی با تلاش دوباره

این اسکریپت فهرستی از URLها را از طریق پروکسی دانلود می‌کند، خطاهای موقت را با مکثی فزاینده دوباره امتحان می‌کند، در 407 بی‌درنگ می‌ایستد و برای هر URL یک سطر چاپ می‌کند. فقط به ⁦Windows PowerShell 5.1⁩ نیاز دارد:

powershell
# fetch.ps1: every URL in the list through the proxy, with retries
$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 seconds
                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 -AutoSize

در اجرای ما آدرس /status/503 دو بار 503 پاسخ داد، پس از 1 و 2 ثانیه دوباره امتحان شد و در تلاش سوم موفق شد، چون سرور آزمایشی بازیابی می‌شود؛ 404 بدون تلاش دوباره برگشت:

text
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   250

سه انتخاب اهمیت دارد. $_.Exception.Response.StatusCode تنها جایی است که 5.1 وضعیت یک درخواست ناموفق را نشان می‌دهد، چون 4xx یا 5xx به جای بازگردانده شدن پرتاب می‌شود. $code برابر 0 یعنی اصلاً پاسخی نیامده، مثلاً مهلت تمام شده، و آن هم دوباره امتحان می‌شود. -TimeoutSec 30 یک تلاش را محدود می‌کند؛ پیش‌فرض 0 تا ابد صبر می‌کند. ⁦PowerShell 7⁩ گزینه -MaximumRetryCount 3 -RetryIntervalSec 2 را درون‌ساخت دارد و مستنداتش می‌گوید پاسخ 429 با Retry-After بر این فاصله مقدم است.

هر Invoke-WebRequest اتصال خودش را به پروکسی باز می‌کند، پس گیت‌وی چرخشی به هر فراخوانی آی‌پی خروجی متفاوتی می‌دهد. ورود به حساب و سپس چند صفحه عکس این را می‌خواهد: نشست ثابت در نام کاربری روی پروکسی مسکونی یک آی‌پی را 1 تا 60 دقیقه نگه می‌دارد، در حالی که -SessionVariable کوکی‌ها را در سمت شما نگه می‌دارد.

اسکریپت‌های پروکسی PowerShell کجا به کار می‌روند؟

وظایف زمان‌بندی‌شده خانه معمول آن‌ها هستند: یک کار شبانه قیمت و موجودی آگهی‌های خودتان را آن‌طور که خریداری از کشور دیگر می‌بیند بررسی می‌کند، یک اسکریپت پایش سایت شما را از چند منطقه درخواست می‌کند و روی ارز یا زبان اشتباه هشدار می‌دهد، یک عامل بیلد (build agent) پشت پروکسی سازمانی ماژول‌ها را از طریق آن نصب می‌کند. API شریکی که فقط یک آدرس را مجاز کرده از کاری فراخوانی می‌شود که خروجی‌اش هرگز عوض نمی‌شود؛ پروکسی ISP به آن کار یک آی‌پی اختصاصی می‌دهد که پس از راه‌اندازی مجدد هم می‌ماند.

خطاهای رایج پروکسی در PowerShell و راه رفع آن‌ها

پیام‌ها همان‌طور که ⁦Windows PowerShell 5.1⁩ با رابط انگلیسی چاپ می‌کند؛ در ویندوز با زبان رابط دیگری، مثلاً ترکی یا آلمانی، بخش ⁦.NET⁩ متن بومی‌سازی می‌شود.

  • The remote server returned an error: (407) Proxy Authentication Required. -ProxyCredential داده نشده، اطلاعات ورود درون آدرس نوشته شده، رمز اشتباه است یا آی‌پی در لیست سفید نیست. $_.Exception.Response.StatusCode.value__ در بلوک catch مقدار 407 می‌دهد؛ علت‌ها در رفع خطای ⁦HTTP 407 Proxy Authentication Required⁩ گرد آمده‌اند.
  • Unable to connect to the remote server با Status : ConnectFailure. پورت پروکسی اشتباه است، فایروالی در میان است یا پروکسی از کار افتاده.
  • The proxy name could not be resolved: 'pr.proxynet.io'. غلط املایی در نام میزبان یا نبود DNS؛ پیام نام پروکسی را می‌برد، نه مقصد را.
  • The operation has timed out. -TimeoutSec کوتاه‌تر از زمانی است که پروکسی و مقصد نیاز دارند؛ محدودیت 2 ثانیه‌ای ما در برابر صفحه‌ای 5 ثانیه‌ای همین را تولید کرد.
  • The ServicePointManager does not support proxies with the socks5 scheme. آدرس پروکسی socks5:// یا https:// در 5.1؛ از http://، ⁦PowerShell 7.2⁩ به بعد یا curl.exe استفاده کنید.
  • A parameter cannot be found that matches parameter name 'x'. یک دستور cURL در 5.1 تایپ شده، جایی که curl نام مستعار Invoke-WebRequest است؛ curl.exe بنویسید.
  • Object reference not set to an instance of an object. فراخوانی 5.1 بدون -UseBasicParsing در اسکریپت.
  • The cmdlet cannot run because the following parameter is missing: Proxy. -Proxy $null در حالی که $PSDefaultParameterValues هنوز یک ProxyCredential دارد؛ به جای آن کلید Disabled را به کار ببرید.
  • پروکسی بی‌صدا رد می‌شود. مقصد localhost یا 127.0.0.1 است، یا اسکریپت در 5.1 به HTTPS_PROXY تکیه کرده. api.ipify.org را با و بدون -Proxy مقایسه کنید.

راهنمای انتخاب

نیازپیشنهاد
یک دستور از طریق پروکسی-Proxy به‌علاوه -ProxyCredential
همه دستورهای یک نشست$PSDefaultParameterValues در $PROFILE
بدون رمز در اسکریپتلیست سفید آی‌پی در پنل، فقط -Proxy
پروکسی سازمانی با ورود ویندوز-ProxyUseDefaultCredentials
یک فراخوانی بدون پروکسی-NoProxy (نسخه 7) یا کلید Disabled (نسخه 5.1)
SOCKS5⁦PowerShell 7.2⁩ به بعد، یا curl.exe با socks5h://
کد WebClient یا HttpWebRequest[System.Net.WebRequest]::DefaultWebProxy
همان آی‌پی خروجی در طول فرایند ورودنشست ثابت در نام کاربری
سرویس‌ها و Windows Updatenetsh winhttp set proxy

پرسش‌های متداول

چگونه برای Invoke-WebRequest پروکسی تنظیم کنم؟

-Proxy "http://host:port" و، اگر پروکسی رمز می‌خواهد، -ProxyCredential را با یک شیء PSCredential اضافه کنید. همین دو پارامتر روی Invoke-RestMethod و، بر اساس مستندات ⁦PowerShellGet 2.x⁩، روی Install-Module هم وجود دارند.

چرا Invoke-WebRequest خطای ⁦407 Proxy Authentication Required⁩ برمی‌گرداند؟

چون پروکسی اطلاعات ورود قابل استفاده‌ای دریافت نکرده است. در 5.1 این وقتی پیش می‌آید که نام کاربری و رمز به جای -ProxyCredential درون آدرس نوشته شده باشند، رمز اشتباه باشد، یا پروکسی آی‌پی شما را در لیست سفید انتظار داشته باشد و آدرس ماشین عوض شده باشد.

آیا Invoke-WebRequest از تنظیمات پروکسی ویندوز استفاده می‌کند؟

بله، وقتی -Proxy ندهید. ⁦Windows PowerShell 5.1⁩ پروکسی Internet Options کاربر فعلی را می‌گیرد؛ ⁦PowerShell 7⁩ اول HTTP_PROXY و HTTPS_PROXY را می‌خواند و سپس به تنظیمات کاربر برمی‌گردد. پروکسی WinHTTP که با netsh winhttp تنظیم می‌شود مخزن جداگانه‌ای است و هیچ‌کدام آن را نمی‌خوانند.

چگونه در PowerShell برای یک درخواست پروکسی را کنار بگذارم؟

در ⁦PowerShell 7⁩ به همان فراخوانی -NoProxy بیفزایید. در 5.1 -Proxy را ننویسید؛ اگر $PSDefaultParameterValues باز هم آن را اضافه می‌کند، دور آن فراخوانی $PSDefaultParameterValues["Disabled"] = $true بگذارید. برای میزبان‌های کامل در 7 از NO_PROXY و در 5.1 از BypassList روی یک شیء WebProxy استفاده کنید.

آیا می‌توانم با Invoke-WebRequest از پروکسی SOCKS5 استفاده کنم؟

در ⁦Windows PowerShell 5.1⁩ نه؛ این نسخه طرح socks5:// را رد می‌کند. ⁦PowerShell 7.2⁩ و بعد از آن روی ⁦.NET 6⁩ یا جدیدتر اجرا می‌شوند که پروکسی SOCKS5 را در HttpClient پشتیبانی می‌کند؛ روی نسخه خودتان بررسی کنید. در 5.1 به جای آن curl.exe را با socks5h:// فراخوانی کنید.

چگونه مطمئن شوم PowerShell واقعاً از پروکسی استفاده می‌کند؟

https://api.ipify.org را یک بار بدون -Proxy و یک بار با آن درخواست کنید: دو آدرس متفاوت، که دومی در کشور پروکسی است، یعنی پروکسی در کار است. همان آدرس در هر دو بار یعنی فراخوانی مستقیم رفته، بیشتر وقت‌ها چون مقصد localhost بوده یا 5.1 متغیرهایی را که تنظیم کرده‌اید نادیده گرفته است.

خلاصه

پروکسی را با -Proxy و یک PSCredential در -ProxyCredential به Invoke-WebRequest و Invoke-RestMethod بدهید، هرگز درون آدرس؛ وقتی همه فراخوانی‌ها باید از آن بگذرند، هر دو را یک بار در $PSDefaultParameterValues تنظیم کنید. ⁦Windows PowerShell 5.1⁩ متغیر HTTP_PROXY را نادیده می‌گیرد، به Internet Options برمی‌گردد، آدرس‌های loopback را از پروکسی معاف می‌کند و SOCKS5 بلد نیست؛ ⁦PowerShell 7⁩ متغیرها را می‌خواند، -NoProxy و تلاش دوباره را اضافه می‌کند و از 7.2 به بعد SOCKS5 را می‌پذیرد. در هر اسکریپت 5.1 -UseBasicParsing و -TimeoutSec را نگه دارید و در برابر یک آدرس عمومی آزمایش کنید. نقاط اتصالی که دقیقاً همین پارامترها را می‌پذیرند در صفحه پروکسی Proxynet هستند.

پرسش از ChatGPTپرسش از Claude