外观
PowerShell 请求不走 Clash 的排查指南
约 2817 字大约 9 分钟
ClashPowerShellWindows网络排障
2026-10-06
浏览器已经能打开网页,PowerShell 中的请求却超时,最容易让人误判为节点突然坏了。先别更新订阅、重装客户端或给整个系统改代理:同一台电脑上的浏览器和命令行请求,可能读取了不同的代理设置。
反过来,“命令行一定不走系统代理”也不准确。PowerShell 的版本、当前进程的环境变量、命令中的参数,以及底层网络接管方式,都可能改变请求路径。下面把问题缩小到 Windows 上的 Invoke-WebRequest,用一次请求一个变量的方式排查。Git、下载器和其他命令行程序需要检查各自的设置,不能直接套用这条命令的结论。
先确认 PowerShell 版本和测试范围
在普通权限的 PowerShell 窗口运行下面的只读查询,不需要为了查看版本先切到管理员模式:
$PSVersionTable.PSVersion
$PSVersionTable.PSEdition
Get-Command Invoke-WebRequest -Syntax先记下版本,再核对这个窗口实际支持的参数。Windows PowerShell 5.1 和 PowerShell 7 不是同一套运行环境;在较新版本中可用的参数,不一定能直接复制到旧窗口。
PowerShell 7 在 Windows 上的默认请求会考虑代理环境变量;没有这些变量时,还会读取用户的代理设置。这也是浏览器正常、某个旧终端却异常时,值得先检查环境变量的原因。相关规则见 Microsoft Learn 的默认代理说明。不要把它推广为所有命令行软件的共同规则。
接下来只测试公开网页,不使用含账号令牌的订阅地址,也不运行下载后立即执行的脚本。先保持当前节点、规则和 TUN 开关不变,避免一次改变多个条件后无法判断是哪一步起作用。
检查本地入口而不是先测远端节点
在 Clash 设置中找到当前的 HTTP 或 Mixed 端口。它是应用把请求交给本机客户端的入口,不是节点端口、订阅网址或控制面板端口。下面的 7890 只是示例,必须换成你实际看到的数值:
$proxyPort = 7890
Test-NetConnection -ComputerName 127.0.0.1 -Port $proxyPortWindows 的 Test-NetConnection 文档 展示了 TCP 检查和 TcpTestSucceeded 结果。如果这个命令在当前环境中不存在,可以回到客户端监听设置核对,不必为排障执行来历不明的安装脚本。
结果为 False 时,先确认客户端核心正在运行、端口没有改动,再检查是否填错入口。结果为 True 只说明这个 TCP 入口能建立连接:它既不能证明监听者一定是 Clash,也不能证明所选节点或目标网站可用。结合客户端日志确认请求去向,才能继续往下判断。
HTTP 代理应使用 HTTP 或混合入口,不能把 SOCKS 专用入口直接当成 HTTP 入口。Mihomo 的 代理端口文档 区分了这些字段;需要了解通用填写方式,可看站内代理端口说明。这里不需要开启局域网共享,也不要把控制接口当作测试地址。
用同一个网页做两次对照请求
首先在当前窗口定义一个公开的测试目标。下面使用微软文档页,不下载程序、不携带登录凭据。诊断自己的故障时,可以换成你确认可信的公开目标,但两次请求必须使用同一个地址。
$probeUri = 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.5'
Invoke-WebRequest -Uri $probeUri -UseBasicParsing -TimeoutSec 20 |
Select-Object StatusCode这次是默认代理行为,不是“强制直连”。它可能使用环境变量或用户代理,也可能被 TUN、网关等更底层的路径接管。记下成功状态或错误类别,再做第二次请求。
第二次只给这一个请求明确指定本机 HTTP 代理,不修改系统设置,也不写入永久环境变量:
$proxyUri = [System.UriBuilder]::new('http', '127.0.0.1', $proxyPort).Uri
try {
$probeResponse = Invoke-WebRequest -Uri $probeUri -Proxy $proxyUri -UseBasicParsing -TimeoutSec 20
$probeResponse.StatusCode
} catch {
$_.Exception.Message
}UriBuilder 用协议、主机和端口组成代理入口,构造方式见 微软的类库说明。这里的 http 描述本机代理入口的协议,不是把测试网页降级为明文 HTTP;目标地址仍然使用 HTTPS。
微软的 Invoke-WebRequest 文档 说明 -Proxy 用来指定请求的网络代理。若显式请求成功、默认请求失败,就把重点转向默认代理配置,而不是据此宣布某个订阅过期。若两次都失败,则继续看本地监听、规则命中和具体错误,不能仅凭这个现象认定服务商出了问题。
核对环境变量时不要把凭据贴出去
下面只显示代理变量是否有非空值,不把可能包含用户名、密码的完整地址打印出来:
Get-ChildItem Env: |
Where-Object { $_.Name -in @('HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY', 'NO_PROXY') } |
Select-Object Name, @{Name='Configured'; Expression={-not [string]::IsNullOrWhiteSpace($_.Value)}}没有输出表示这些变量在当前进程中没有设置,不代表系统层面不存在代理。出现变量也不等于它们有问题:在自己的电脑上核对是否仍指向当前端口,是否遗留了已经停用的工具,或是否把目标域名列入了不使用代理的范围。不要为了“清干净”一次删除全部网络变量,尤其是受管理的工作电脑。
HTTP_PROXY、HTTPS_PROXY 分别对应 HTTP 和 HTTPS 请求;ALL_PROXY 是相关专用变量未定义时的后备设置;NO_PROXY 指定不使用代理的主机。具体适用规则仍以当前程序为准。对于 PowerShell 7,可对照前面的默认代理说明核查。
为什么一个窗口能用、另一个不行?进程环境通常继承自启动它的父进程。微软的 环境变量说明 区分了 Process、User 和 Machine 范围。两个终端若来自不同启动入口,就值得比较各自的进程环境;不能只看设置面板就假定它们拥有相同配置。
如果确认只是某个旧窗口保留了过时环境,重新打开终端后再测试,比立刻写入整台电脑的永久设置更容易控制影响范围。若需要修改用户或系统变量,先记下原值和修改原因,再按管理要求处理。
可选的无代理对照并不等于绕过 TUN
PowerShell 7 可用 -NoProxy 做一次额外对照:
Invoke-WebRequest -Uri $probeUri -NoProxy -UseBasicParsing -TimeoutSec 20 |
Select-Object StatusCode这个参数在旧版 Windows PowerShell 5.1 中不适用,不要遇到“找不到参数”就认为网络出了故障。它让该请求不使用命令层面的代理,但无法据此证明数据没有经过 TUN、路由器网关或其他底层接管。需要确定真实出口时,仍应结合当前接管方式与客户端连接记录。
也不要用这个参数去绕过组织要求的网络控制。在企业或校园受管理环境中,先确认允许的访问方式,再做诊断。
把错误分成不同层次
错误文字往往比“能不能访问”这个二选一更有帮助。先保存不含敏感地址的错误类别,再按层次处理:
| 观察到的现象 | 优先检查的方向 |
|---|---|
| 本机 TCP 入口不通 | 核心是否运行、实际端口、监听者与本机限制 |
| 显式代理成功,默认请求失败 | 当前进程的默认代理来源与例外设置 |
| 返回 HTTP 407 | 代理端的认证要求,不是目标网站登录状态 |
| 返回 HTTP 401、403 或 404 | 响应方的认证、访问策略或资源路径,不能等同于本地端口断开 |
| TLS 或证书验证错误 | 系统时间、证书信任与可能的 HTTPS 检查,不关闭证书验证 |
| 两次请求都超时 | 结合日志继续区分入口、规则、出口和目标响应 |
HTTP 状态码含义可查 MDN 的状态码参考。读到状态码,说明某个响应方返回了 HTTP 响应,但仍要确认它是否来自预期目标;中间代理或网关也可能生成错误页。
不要为了让测试变成绿色而安装陌生根证书、跳过证书验证、把订阅网址改成明文,或关闭整台电脑的防火墙。遇到证书问题,应保留错误并按证书排障流程处理;本文的命令没有提供绕过验证的开关。
测试后保留什么结果
一份有用的排障记录不需要整段订阅配置。记下 PowerShell 版本、测试目标的公开域名、本机入口检查结果、默认与显式请求的差别,以及相关日志的规则和错误类别即可。截图前删除订阅令牌、代理凭据、控制密钥及不必要的设备信息。
使用 FlyBit 这类节点订阅配合 Clash 时,也应先区分本地请求路径与远端节点问题。向服务商求助前给出这份脱敏记录,比只说“终端打不开”更有助于定位;默认代理错误并不会因为重新购买套餐自动消失。
完成测试后,命令中临时指定的 -Proxy 不会变成整个系统的默认代理。若你额外改过端口、变量或接管模式,则需要按原先记录恢复,并用正常业务重新确认。本文不要求保存 PowerShell 配置文件、不改执行策略,也不把测试请求写成后台常驻任务。
真正要确定的不是“终端需不需要代理”这一句笼统判断,而是:这个版本的这条请求,此刻从哪里读取代理,又实际经过了哪条路径。 把同一目标的默认请求与显式请求放在一起比较,再核对当前进程环境,就能缩小问题范围,同时保留系统原有的安全边界。



