---
title: "تنظیمات پروکسی در PowerShell: Invoke-WebRequest با پروکسی"
description: "⁦-Proxy⁩ و ⁦-ProxyCredential⁩ را به Invoke-WebRequest بدهید یا در ⁦$PSDefaultParameterValues⁩ تنظیم کنید؛ به‌علاوه تفاوت 5.1 و 7، متغیرهای محیطی، 407 و SOCKS5."
url: https://proxynet.io/fa/blog/powershell-proxy
date: 2026-11-07
author: "Acar Diveroli"
category: "آموزش‌ها, یکپارچه‌سازی"
lang: fa
---

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

اسکریپتی که روی لپ‌تاپ شما بی‌مشکل اجرا می‌شد به سرور منتقل می‌شود، یا حالا باید فهرست قیمتی را از دید بازدیدکننده‌ای از کشور دیگر بخواند، و هر فراخوانی `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⁩ روی ماشین آزمایش نصب نبود، پس رفتار آن از مستندات مایکروسافت آمده و همین‌طور هم علامت‌گذاری شده است.

> **نکته: پاسخ کوتاه**
>
> `-Proxy "http://pr.proxynet.io:8000"` و `-ProxyCredential $cred` را به `Invoke-WebRequest` یا `Invoke-RestMethod` اضافه کنید؛ `$cred` یک شیء `PSCredential` است که از نام کاربری و رمز پروکسی ساخته می‌شود. برای اعمال پروکسی بر همه فراخوانی‌های یک نشست، همین دو مقدار را در `$PSDefaultParameterValues` بگذارید. ⁦Windows PowerShell 5.1⁩ متغیرهای `HTTP_PROXY` و `HTTPS_PROXY` را نادیده می‌گیرد، `user:pass@` درون آدرس پروکسی را نادیده می‌گیرد و SOCKS5 بلد نیست؛ ⁦PowerShell 7⁩ متغیرها را می‌خواند و از 7.2 به بعد `socks5://` را می‌پذیرد.

## ⁦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⁩](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=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](https://www.rfc-editor.org/rfc/rfc9110.html#section-15.5.8) و این چالش در ⁦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
```

5. **مقصد به آی‌پی خروجی پروکسی پاسخ می‌دهد.** 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⁩](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=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 کاربر را. اسکریپتی که ناگهان از پروکسی غیرمنتظره‌ای خارج می‌شود معمولاً دنبال همین تنظیم می‌رود؛ [تنظیم پروکسی در ویندوز و کروم](/fa/blog/windows-chrome-proxy-settings) نشان می‌دهد این تنظیم کجاست.

ویندوز یک مخزن پروکسی دوم برای 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⁩](https://devblogs.microsoft.com/dotnet/dotnet-6-networking-improvements/) مایکروسافت پشتیبانی 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 با پروکسی](/fa/blog/curl-proxy) توضیح داده شده‌اند؛ به جای 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` اتصال خودش را به پروکسی باز می‌کند، پس گیت‌وی چرخشی به هر فراخوانی آی‌پی خروجی متفاوتی می‌دهد. ورود به حساب و سپس چند صفحه عکس این را می‌خواهد: نشست ثابت در نام کاربری روی [پروکسی مسکونی](https://proxynet.io/fa/residential-proxy) یک آی‌پی را 1 تا 60 دقیقه نگه می‌دارد، در حالی که `-SessionVariable` کوکی‌ها را در سمت شما نگه می‌دارد.

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

وظایف زمان‌بندی‌شده خانه معمول آن‌ها هستند: یک کار شبانه قیمت و موجودی آگهی‌های خودتان را آن‌طور که خریداری از کشور دیگر می‌بیند بررسی می‌کند، یک اسکریپت پایش سایت شما را از چند منطقه درخواست می‌کند و روی ارز یا زبان اشتباه هشدار می‌دهد، یک عامل بیلد (build agent) پشت پروکسی سازمانی ماژول‌ها را از طریق آن نصب می‌کند. API شریکی که فقط یک آدرس را مجاز کرده از کاری فراخوانی می‌شود که خروجی‌اش هرگز عوض نمی‌شود؛ [پروکسی ISP](https://proxynet.io/fa/static-isp-residential-proxy) به آن کار یک آی‌پی اختصاصی می‌دهد که پس از راه‌اندازی مجدد هم می‌ماند.

## خطاهای رایج پروکسی در 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⁩](/fa/blog/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 Update | `netsh 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](/fa/proxy) هستند.
