解决 PowerShell 禁止运行 .ps1 脚本:ExecutionPolicy 完全指南
🌟 概述
在 Windows 上使用 Node.js、pnpm、rclone 部署脚本或运行自建的 deploy.ps1 时,几乎每个新手都会遇到这个报错:
无法加载文件 xxx.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https://go.microsoft.com/fwlink/?LinkID=135170中的 about_Execution_Policies。 + CategoryInfo : SecurityError: (:) [],PSSecurityException这不是软件有问题,而是 Windows PowerShell 的默认安全机制:默认执行策略 Restricted 会阻止所有 .ps1 脚本运行(包括你自己写的)。
本文分两部分:
- 快速修复(4 步):99% 的普通用户用这部分就够
- 进阶排查:改完还是不行?很可能是 MOTW(互联网标记)或多 Scope 覆盖导致
🚀 快速修复(4 步搞定)
第 1 步:以管理员身份打开 PowerShell
右键开始菜单 → 点击 终端(管理员) 或 PowerShell(管理员)。
如果只有普通权限,仅修改
CurrentUserScope 时也可以用普通 PowerShell(不一定要管理员,见下文原理)。
第 2 步:执行更改策略命令
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser第 3 步:确认更改
控制台会弹出:
是否要更改执行策略?[Y] 是(Y) [A] 全是(A) [N] 否(N) [L] 全否(L) [S] 暂停(S) [?] 帮助 (默认值为"N"):输入 Y 回车即可。(想对所有 Scope 一次性确认可输入 A)
第 4 步:重启终端
关闭所有已打开的终端窗口(包括 VSCode 内置终端、Windows Terminal、独立 PowerShell 窗口),重新打开即可生效。
此时再运行 deploy.ps1、npm.ps1、pnpm.ps1 等脚本均不再报错。
- 本地你自己创建的脚本:允许直接运行
- 从网上下载的脚本(浏览器/邮件/聊天软件写入了 Zone.Identifier 标记):必须有数字签名才能运行
这是个人开发兼顾安全与便利的最佳平衡点,不建议直接改成 Unrestricted / Bypass。
📖 执行策略原理速览
6 种策略对比
| 策略 | 本地脚本 | 下载脚本 | 安全性 | 适用场景 |
|---|---|---|---|---|
Restricted(默认) | ❌ 禁止 | ❌ 禁止 | ⭐⭐⭐⭐⭐ | 完全不用脚本的普通用户 |
RemoteSigned ✅ 推荐 | ✅ 允许 | ✅ 需签名 | ⭐⭐⭐⭐ | 个人开发 / 日常使用 |
AllSigned | ✅ 需签名 | ✅ 需签名 | ⭐⭐⭐⭐⭐ | 企业高安全环境 |
Unrestricted | ✅ 允许 | ⚠️ 警告提示后允许 | ⭐⭐ | 下载脚本较少的个人用户 |
Bypass | ✅ 允许 | ✅ 静默允许 | ⭐ | 特殊 CI/CD 场景(单次生效) |
Undefined | — | — | — | 清除本 Scope 配置,回落上一层 |
5 个 Scope 的生效范围
执行策略是分层叠加的,从上到下优先级递减(上面的会覆盖下面):
| 优先级 | Scope | 生效范围 | 是否要管理员 | 写入位置 |
|---|---|---|---|---|
| 1(最高) | MachinePolicy | 计算机所有用户(组策略下发) | 是 | GPO |
| 2 | UserPolicy | 当前用户(组策略下发) | 否 | GPO |
| 3 | Process | 当前终端进程(关闭终端即失效) | 否 | 内存 |
| 4 | CurrentUser ✅ 推荐 | 当前用户(永久) | 否 | 注册表 HKCU |
| 5(最低) | LocalMachine | 本机所有用户(永久) | 是 | 注册表 HKLM |
- 个人电脑自己用:改
CurrentUser(不需要管理员权限,不会影响别的账号) - 多人共用电脑、所有用户都要跑脚本:改
LocalMachine(需要管理员) - 只想临时让当前终端放行一次:
-Scope Process,关了就失效
查看当前所有 Scope 的实际生效值:
Get-ExecutionPolicy -List输出示例(我们想要 MachinePolicy / UserPolicy 都是 Undefined,CurrentUser 是 RemoteSigned):
Scope ExecutionPolicy ----- ---------------MachinePolicy Undefined UserPolicy Undefined Process Undefined CurrentUser RemoteSigned LocalMachine Undefined🔧 进阶:改完 RemoteSigned 还是不行?
如果你按上面 4 步做完仍报”禁止运行脚本”或”未签名”,90% 是下面两种情况之一。
问题一:文件被标记了”来自互联网”(MOTW)
这是最常见的隐蔽坑:即使你把策略改成 RemoteSigned,只要文件/压缩包是从浏览器、微信、QQ、邮箱下载的,Windows 会自动在 NTFS 备用数据流里加一个 Zone.Identifier(俗称 MOTW,Mark of the Web),RemoteSigned 会把它们当成”下载脚本”,要求签名。
典型场景
- 从 GitHub Release 下载的 zip 解压后里面的所有
.ps1 - Node.js / pnpm 安装包是官网下载的,里面的
npm.ps1/pnpm.ps1全部带标记 - 别人 QQ 发来的脚本
症状
无法加载文件 C:\Program Files\nodejs\npm.ps1。文件 C:\Program Files\nodejs\npm.ps1 没有数字签名。你无法在当前系统上运行该脚本。而你 Get-ExecutionPolicy 看到的明明已经是 RemoteSigned。
解决方法
对被拦截的单个文件解除标记:
Unblock-File "C:\Program Files\nodejs\npm.ps1"批量解除一个目录(含子目录)下所有 .ps1 的标记:
# 对 Node 安装目录(按需改成你自己的路径)Get-ChildItem "C:\Program Files\nodejs" -Filter *.ps1 -Recurse | Unblock-File
# 对整个 rclone 解压目录Get-ChildItem "C:\tools\rclone" -Filter *.ps1 -Recurse | Unblock-File右键文件 → 属性 → 底部勾选”解除锁定” → 确定,本质和
Unblock-File是同一个操作。
问题二:组策略覆盖了你的设置(公司电脑/域环境)
公司加入域的电脑,IT 部门可能通过 GPO 下发了 MachinePolicy 或 UserPolicy 的 Restricted / AllSigned。由于 GPO 优先级最高,你改 CurrentUser 会被静默忽略。
诊断
Get-ExecutionPolicy -List如果看到 MachinePolicy 或 UserPolicy 不是 Undefined,就是组策略在管。
解决方案(由易到难)
-
临时单次放行(当前终端生效,无需管理员):
Terminal window # 方案A:仅当前进程用 Bypass,关闭窗口就还原Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process# 方案B:启动 PowerShell 时直接带参数powershell.exe -ExecutionPolicy Bypass -File .\deploy.ps1 -
完全绕开 .ps1 入口(以 npm 为例):
Terminal window # 直接调用 .cmd 版本(不经过 PowerShell 执行策略)npm.cmd install# 或直接调用 node 跑 CLI(本质逻辑)node "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" install -
联系 IT:申请白名单或改 GPO(长期方案)。
问题三:PowerShell 5.1 vs PowerShell 7 配置是分开的
如果你同时装了:
- Windows PowerShell 5.1(系统自带,
powershell.exe,蓝色图标) - PowerShell 7+(自己装的,
pwsh.exe,黑色图标)
两者的 ExecutionPolicy 注册表位置不共用,在其中一个里设置了 RemoteSigned,另一个仍然是 Restricted。
分别对两种终端都执行一次:
# 分别在 powershell.exe 和 pwsh.exe 里都跑一次Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser✅ 验证修复是否成功
修改完成后,可以跑三个小测试逐一确认:
1. 确认策略值
Get-ExecutionPolicy# 应输出:RemoteSigned2. 创建一个本地测试脚本
# 创建 + 执行"Write-Host '✅ 本地脚本可以正常运行啦!'" > "$env:USERPROFILE\Desktop\test-script.ps1"& "$env:USERPROFILE\Desktop\test-script.ps1"正常就会输出绿色的成功信息。
3. 查看所有 Scope 详情
Get-ExecutionPolicy -List | Format-Table -AutoSize理想状态:
Scope ExecutionPolicy ----- ---------------MachinePolicy Undefined UserPolicy Undefined Process Undefined CurrentUser RemoteSigned ← 关键!这一行是 RemoteSigned LocalMachine Undefined📋 常见报错对应修复速查
| 报错内容 | 原因 | 修复 |
|---|---|---|
| ”在此系统上禁止运行脚本” + PSSecurityException | 默认 Restricted | Set-ExecutionPolicy RemoteSigned -Scope CurrentUser |
| ”xxx.ps1 没有数字签名” | 下载文件带 MOTW | Unblock-File 目标文件 |
| 自己写的 deploy.ps1 也提示未签名 | 文件目录是从压缩包解压出来的,整个目录继承了 Zone.Identifier | Get-ChildItem 目录 -Recurse | Unblock-File |
| 改了 CurrentUser 还是显示 Restricted | MachinePolicy / UserPolicy 组策略覆盖 | 用 Bypass -Scope Process 或联系 IT |
| 普通 PowerShell 正常,VSCode 终端还是不行 | VSCode 旧终端没重启,或者用的是 pwsh.exe 另一个配置 | 完全关闭 VSCode 重开,或在 pwsh 里也设置一次 |
🎉 总结
- 99% 场景的最简方案:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser→ 确认 Y → 重启终端 - 下载文件仍提示未签名:
Unblock-File批量清掉 MOTW - 公司电脑组策略锁死:单次用
-Scope Process Bypass或直接powershell.exe -ExecutionPolicy Bypass -File xxx.ps1 - 修改前后一定用
Get-ExecutionPolicy -List确认,避免以为改了但被上层 Scope 覆盖
建议收藏本文,Windows 重装后第一时间跑这两行就搞定 PowerShell 脚本运行权限问题。

文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!




