首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
PowerShell执行策略详解:从“禁止运行脚本”报错到实战配置
📅 2026/10/10 18:48:40
✍️ 爱科研究院
👁 阅读 3,247
如果你第一次在 PowerShell 窗口里把一个 .ps1 文件拖进去回车大概率会看到一段红底白字的报错“无法加载文件 xxx.ps1因为在此系统上禁止运行脚本。有关详细信息请参阅 about_Execution_Policies。” 第一次遇到这个提示的人十有八九以为是自己权限不够或者文件坏了其实都不是——拦住你的是 PowerShell 的执行策略Execution Policy。执行策略是 PowerShell 世界里最基础但又最常被误解的安全机制。我见过很多开发者、运维同事甚至一些写了多年脚本的老手都被它拦到怀疑人生。有人直接告诉我“我把策略改成 Unrestricted 就行了”但过两天又跑来找我说某个远程下载的脚本还是跑不了或者公司里的机器根本不让改。这篇文章就把执行策略这件事彻底讲透它到底在防什么六个级别之间有什么区别怎么按场景改才不会给自己留坑以及改完之后为什么还会遇到“明明设置了却不生效”的诡异情况。文章主要适合两类人看一类是本地开发机或个人电脑上装软件、跑脚本总被拦的新手另一类是要在团队或企业环境里统一管理 PowerShell 脚本策略的运维同学。我会把判断顺序、命令行、注册表、组策略这几个层面全部走一遍。1. “禁止运行脚本”这个报错到底是怎么冒出来的1.1 先还原一次真实报错现场很多人的第一个 PowerShell 脚本长这样Write-Host Hello, World把它存成hello.ps1然后在终端里执行.\hello.ps1然后 PowerShell 直接给你来一句无法加载文件 C:\Users\admin\Desktop\hello.ps1因为在此系统上禁止运行脚本。 有关详细信息请参阅 about_Execution_Policies。 所在位置 行:1 字符: 1 .\hello.ps1 ~~~~~~~~~~~~ CategoryInfo : SecurityError: 403 13 FullyQualifiedErrorId : UnauthorizedAccess这个报错里的SecurityError和UnauthorizedAccess会让人产生一种误解——是不是我当前用户没有权限其实不是。这句话翻译过来是“执行策略当前不允许这个脚本运行。” 它跟你是管理员、这个文件是不是你亲手写的都没有直接关系。同一个文件放到一台 Windows Server 上可能直接就能跑放到另一台 Windows 11 上可能又被拦。差别不在文件而在执行策略。1.2 执行策略是“信任”闸门不是用户权限执行策略在 PowerShell 里的地位可以理解成一道“脚本入境检查”闸门。它不是操作系统 ACL 那种“谁能访问文件”的权限而是“引擎愿意加载并执行什么来源的脚本”的规则。PowerShell 的远景是好的脚本比普通命令行功能强太多能调用几乎所有系统 API所以必须有一个机制防止恶意脚本被无脑执行。执行策略就是这个机制的一部分它被设计成默认保守普通 Windows 桌面系统默认不允许任何脚本运行你只能手敲命令。你可以把执行策略想象成机场安检。你人到了登机口文件权限没问题但行李没过安检照样上不了飞机。Restricted策略就是“任何行李都要托运随身携带一律禁止”。管理员即使拥有最高权限也得遵守安检规则所以管理员用户被拦简直太常见了。注意执行策略限制的是“脚本运行”这个行为不是“读取文件”“复制文件”这些操作。你完全可以用Get-Content打开.ps1文件看内容但用. \script.ps1执行就会被拦。1.3 改动之前先看清楚当前状态任何调整之前先查自己当前的策略值。最直接的命令Get-ExecutionPolicy返回Restricted、RemoteSigned、Bypass这些值。如果只看一个值还不够用-List参数看所有作用域Get-ExecutionPolicy -List执行结果会按优先级从上到下排列。这一步非常关键后面排查“改了没用”的问题时全靠这张清单定位。2. 六个策略级别和四个作用域动手前先读懂优先级2.1 六档策略分别代表什么信任程度执行策略一共六个值Restricted、AllSigned、RemoteSigned、Unrestricted、Bypass、Undefined。很多人只知道其中一两个但每个含义其实差别很大。策略本地无签名脚本本地有签名脚本网络下载脚本实际用途Restricted禁止禁止禁止默认安全态裸系统常见AllSigned禁止允许允许需签名严格合规环境RemoteSigned允许允许允许需签名或解除标记开发机最常见Unrestricted允许允许允许运行前提示不想管安全但需要提示Bypass允许允许允许一次性临时放行Undefined未设置未设置未设置继承上一层或默认值先解释Restricted。在这个策略下任何.ps1脚本都不能运行包括你本地纯手工编写的脚本。它非常适合公共电脑、展示机这种“不该跑脚本”的环境但对开发者来说非常难受。AllSigned要求所有脚本都必须带有效数字签名不管这个脚本是你自己写的还是微软发的。好处是审计严格坏处是你每次改完脚本都得重新签名很烦。一般只有安全要求极高的内网才会用。RemoteSigned是我个人最推荐的值。本地创建的脚本可以直接运行从互联网下载的脚本必须带有可信数字签名或者用户手动“解除锁定”。它相当于“熟悉的人直接放行陌生人要验一下身份证”。Unrestricted会放行所有脚本但从互联网下载的脚本在运行前会弹一次确认提示。这个策略在较老版本的 Windows PowerShell 里很常见但它的安全模型其实很粗糙而且某些系统上它还会影响非 Windows 桌面应用的 Appx 包执行。Bypass是“什么都不拦”的意思甚至比Unrestricted更彻底连提示都不弹。它不是拿来当长期策略用的而是“临时绕过”工具。比如安装一个来自 GitHub 的部署脚本你不想动全局配置那就临时用 Bypass 跑一次。Undefined表示当前作用域没有设置策略。如果所有作用域都是UndefinedPowerShell 最终按Restricted处理。所以“我没设置过策略”和“策略是 Restricted”在实际效果上是一样的。2.2 四个作用域和它们的优先级策略不是全局只有一份它分作用域。从高到低依次是MachinePolicy UserPolicy Process CurrentUser LocalMachineMachinePolicy和UserPolicy通常由组策略注入企业域环境常见普通个人电脑一般是Undefined。Process是只对当前 PowerShell 进程生效的临时策略进程一关就消失。CurrentUser存在当前用户的注册表配置里是个人电脑上最常用的设置点。LocalMachine存在本机注册表里对这台机器的所有用户生效。注意优先级。如果MachinePolicy被设置为AllSigned那么即使你在CurrentUser里改成Bypass最终生效的仍然是AllSigned。这是“改完没用”的头号原因。查看命令Get-ExecutionPolicy -List输出中每个作用域一行顺序就是优先级顺序。哪个不是Undefined哪个就在“管事”。2.3 为什么有时候同一个机器两个窗口结果不一样有人曾经截图给我看左边窗口Get-ExecutionPolicy返回RemoteSigned右边窗口返回Restricted。他一度以为是系统抽风。其实原因无非几种左边窗口是管理员开的右边是普通用户开的或者两个窗口一个是 64 位 PowerShell另一个是 32 位 PowerShell又或者一个跑在CurrentUser作用域另一个被进程级参数覆盖了。后面我会针对这些情况逐个给排查方法这里先有个概念执行策略不是一个“全局单一开关”而是一套分层叠加上下文。3. 改执行策略的几种落地姿势别只盯着 Set-ExecutionPolicy3.1 自己开发机上最推荐CurrentUser 加 RemoteSigned自己用的电脑只想让本地脚本顺利跑起来推荐在CurrentUser作用域设置RemoteSignedSet-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser这个命令不需要管理员权限。执行完以后再验证一下Get-ExecutionPolicy -Scope CurrentUser返回RemoteSigned就说明当前用户级别的策略已经生效。为什么是RemoteSigned而不是Unrestricted因为RemoteSigned能防止你双击一个刚从浏览器下载的恶意脚本时被无脑执行同时又不会妨碍你写脚本。这个平衡点对开发者来说非常合适。如果某台机器是 Team 里共用的测试机可以考虑用LocalMachine作用域让所有账号都生效但需要管理员权限。提示Set-ExecutionPolicy在不指定-Scope的时候默认尝试写入LocalMachine。普通用户权限下会报“访问被拒绝”这也是一个常见的失败现场。3.2 想全局生效管理员身份改 LocalMachine在管理员 PowerShell 窗口里执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine这条命令会写入HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell对整台机器的所有用户生效。公司统一分配的电脑如果允许也可以用它替代组策略。但是请注意LocalMachine作用域优先级低于CurrentUser。如果一个普通用户在CurrentUser里把自己设置成了Bypass而你机器级是RemoteSigned最终实际生效的是Bypass。这就有点反直觉了——机器级并不总是压过用户级。3.3 单次临时放行Process 作用域或启动参数有时候你只想跑一个安装脚本不想改动系统任何配置。这时候最适合用Process作用域Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process然后再执行目标脚本。这个策略只活在当前这个 PowerShell 进程里窗口关掉就恢复原状不写注册表不影响下次会话。更常见的做法是直接在启动 PowerShell 的时候通过参数指定powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Tools\install.ps1或者你想先改策略再执行脚本powershell.exe -NoProfile -Command Set-ExecutionPolicy -Scope Process Bypass; .\install.ps1-ExecutionPolicy可以简写为-EP-NoProfile是指不加载用户配置文件。很多 CI/CD 流水线里调用 PowerShell 脚本时都会带上这两个参数目的就是排除配置文件的干扰同时用一个确定性的策略执行脚本。我自己的习惯是线上环境也好本地临时装工具也好能用-ExecutionPolicy Bypass这种一次性方式解决的就不要永久改策略。毕竟“临时放行”和“长期裸奔”是两码事。3.4 企业环境组策略统一管如果你们公司用组策略管理终端那么上面的注册表级设置可能会被直接无视。组策略管理模板里有一项计算机配置 - 管理模板 - Windows 组件 - Windows PowerShell - 打开脚本执行它对应的是MachinePolicy作用域。企业管理员可以设置成“仅允许签名脚本”“仅允许本地脚本”“允许所有脚本”。开起来以后终端上无论CurrentUser还是LocalMachine的设置都会被它压住。域环境里你基本不用想在个人层面绕过因为MachinePolicy优先级最高。个人电脑如果被某次组策略误伤可以打开本地组策略编辑器gpedit.msc把“打开脚本执行”改成“未配置”然后清理注册表策略项Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell -Name ExecutionPolicy -ErrorAction SilentlyContinue gpupdate /force再执行Get-ExecutionPolicy -List确认MachinePolicy是否已经变为Undefined。这一步经常被忽略因为很多人只改了组策略 UI却没刷新策略导致第一次查看时还残留旧值。4. 执行策略明明改了脚本还是被拦六个高频现场4.1 背着管理员身份却写入失败有次一个朋友跟我抱怨“我明明是管理员运行 Set-ExecutionPolicy 还是被拒绝。” 他给我的报错是Set-ExecutionPolicy : 对注册表项“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell”的访问被拒绝。原因很简单他运行 PowerShell 时没有“以管理员身份运行”只是登录账号属于 Administrators 组而已。Windows 的 UAC 会把进程令牌分成高权限和低权限两种普通双击永远是低权限写入 HKLM 自然被拒。解决方式有两种一是用管理员身份重新打开 PowerShell再执行带-Scope LocalMachine的命令二是干脆别碰LocalMachine改为-Scope CurrentUser普通权限也能改。4.2 组策略级别压住了所有手动设置如果你执行Get-ExecutionPolicy -List以后看到输出第一行是MachinePolicy RemoteSigned那后面手动改什么都白搭。组策略作用域优先级最高注册表里手动写的CurrentUser完全没有话语权。这种情况多半出现在公司电脑或者你以前用gpedit.msc设置过策略但忘了改回来。本地电脑可以按我上面说的gpedit.msc方法改回“未配置”并且删掉HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell下的ExecutionPolicy项。删完以后记得gpupdate /force再查一下策略列表确认MachinePolicy不再是某个具体值。4.3 32 位和 64 位 PowerShell 各改各的这个坑是我自己踩过的。有一次我在 64 位 PowerShell 里把策略改成了RemoteSigned然后关掉窗口用 VS Code 的集成终端去跑脚本居然还是提示禁止运行。查了半天才发现VS Code 里的终端调用的是 32 位 PowerShell。Windows 自带两套 PowerShellC:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe # 64 位 C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe # 32 位执行策略分别存在 64 位和 32 位两套注册表视图中互不相通。你改了一边另一边还是老配置。解决办法是在两个版本里分别设置。64 位窗口里执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser再手动启动 32 位版C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -Command Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser如果你经常用到 VS Code、其他编辑器内置终端请留意它们默认调用的是哪个版本的 PowerShell。这个坑的排查方法很简单在疑似出问题的终端里运行$PSHOME或者直接看窗口标题就能区分版本。4.4 文件来自互联网被标记了和策略无关RemoteSigned策略下本地脚本可以运行但“从互联网下载的脚本”不行。Windows 会给从浏览器、网盘下载的文件打上一个隐藏的 Zone.Identifier 标记也就是大家在文件属性“安全”里看到的“此文件来自其他计算机可能被阻止以帮助保护该计算机”。所以你在RemoteSigned下运行刚下载的install.ps1一样会报“禁止运行脚本”。这跟策略没改错纯粹是文件来源需要解锁。查看文件是否带网络标记Get-Item .\install.ps1 -Stream Zone.Identifier如果输出了内容说明它来自网络。两种处理方式第一种右键文件 - 属性 - 勾选“解除锁定” - 确定。第二种用命令解除Unblock-File -Path .\install.ps1执行完以后再跑这个脚本就正常了。现在我下载任何脚本后第一件事就是Unblock-File已经养成肌肉记忆了。4.5 WSL、第三方安装器调用 PowerShell 时的隐藏差异现在很多新工具都会在安装过程中自动调用 PowerShell。例如用uv安装specify-cli某一步可能触发 PowerShell 执行内联脚本一些 AI 工具链比如围绕 WSL 环境的初始化脚本也会提示你“在 PowerShell 中运行wsl --status”之类的命令。这类工具表面上是“一条命令安装”实际背后是一套安装逻辑而它调用的 PowerShell 不一定加载了你的用户配置也不一定沿用交互窗口里的策略。遇到这种安装器报“无法加载文件因为在此系统上禁止运行脚本”的时候不要只想着改CurrentUser。先手动验证一下安装器实际看到的策略powershell.exe -NoProfile -Command Get-ExecutionPolicy -List在 WSL 里调用 Windows 工具时更明显因为 WSL 里执行powershell.exe加载的是 Windows 那边的环境但外层 shell 是 Linux。如果安装脚本硬编码了某个需要管理员权限的操作或者依赖一个不存在的用户配置文件就会冒出各种奇怪的提示。我处理这类问题的方法是在工具文档建议的命令前面显式指定一次性策略而不是依赖默认环境。比如powershell.exe -NoProfile -ExecutionPolicy Bypass -Command wsl --status或者在 WSL 内部调用时直接写powershell.exe -NoProfile -ExecutionPolicy Bypass -File ./setup.ps1这样既不动系统全局策略又能让安装器顺利跑过去。很多第三方工具其实自身也推荐这么干只是文档里往往写得不够显眼。4.6 商店版 PowerShell 和系统自带版本并存Windows 上可能同时存在两个 PowerShellpowershell.exe # Windows PowerShell 5.1系统自带 pwsh.exe # PowerShell 7.x商店版或手动安装这两个版本的配置文件路径、默认行为、甚至对某些兼容特性的支持都不一样。商店版安装的pwsh会优先使用独立的配置文件目录在 Windows 上往往位于$HOME\Documents\PowerShell而 Windows PowerShell 5.1 用的路径是$HOME\Documents\WindowsPowerShell如果你在pwsh里设置了执行策略powershell.exe未必认。反过来也一样。最稳妥的做法是分别打开两个终端各自执行Get-ExecutionPolicy -List确认两个环境都符合预期。另外提一个容易混淆的场景某些老软件的安装程序提示“需要安装 Windows PowerShell 2.0”比如 Win11 装 SQL Server 2012 的时候经常看到。这是因为它需要旧版引擎运行时属于“Windows 功能”层面的东西跟执行策略不是一回事。不要为了装它去把系统默认 PowerShell 改成某个奇怪的策略。5. 执行策略放行之后脚本还是跑不顺三件配套事5.1 脚本中文乱码先别怪策略先看编码策略解决的是“能不能跑”编码解决的是“跑出来对不对”。很多时候你把执行策略调通满心欢喜地运行脚本结果中文注释全变成乱码或者输出到控制台的中文变成一团方块。Windows PowerShell 5.1 默认情况下读取无 BOM 的 UTF-8 文件时会按 ANSI 去解析中文自然就乱了。解决办法有两个方向。第一用记事本或者任何编辑器把.ps1文件另存为“UTF-8 with BOM”。注意不是“UTF-8 无 BOM”而是带 BOM 的版本。第二如果在脚本内部输出中文乱码可以尝试在脚本开头设置控制台编码[Console]::OutputEncoding [System.Text.Encoding]::UTF8 $OutputEncoding [System.Text.Encoding]::UTF8如果是在 PowerShell 7 里默认就是 UTF-8基本不会出现这个毛病。所以长远看新项目直接切到pwsh能省不少心。5.2 开机自启脚本被拦的通用解法执行策略的坑不只出现在你手动敲命令的时候还特别喜欢在开机自启场景里冒头。你写好了一个startup.ps1放到启动文件夹里或者建了任务计划程序结果开机后发现它根本没跑。日志里一看又是策略拦截。原因很简单不管是启动文件夹还是任务计划程序操作系统并不会像你打开终端那样先加载完整 PowerShell 用户环境它只是拉起一个进程执行脚本这个进程同样受执行策略限制。任务计划程序里的标准做法是程序填powershell.exe参数填-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\startup.ps1启动文件夹如果放的是.ps1文件双击默认不会执行。保险做法是在启动文件夹里放一个.cmd或者.bat文件里面写powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\startup.ps1这样既绕开了双击关联的问题也给脚本指定了明确策略。需要注意-WindowStyle Hidden可以让启动时少弹一个窗口但如果脚本里有交互输入或者报错隐藏窗口会让问题更难发现。排障阶段建议别加这个参数。5.3 顺手解决“在终端里点选复制”的小事既然聊到了在终端里跑脚本就多说一个大家经常问的操作。好多人在 PowerShell 窗口里面对一大堆日志想复制其中一段结果按 CtrlC 没反应按 CtrlV 也黏不上。经典 Windows 控制台窗口里选中文字后直接单击右键就是复制再单击右键就是粘贴。Windows Terminal 里更简单选中即自动复制右键即粘贴。老式控制台想用鼠标画一个选区可以在标题栏右键 - 编辑 - 标记然后拖选文字。这个小技巧不算什么高深技术但每次在真实机房里折腾脚本时能快速复制报错信息去搜效率提升真的不是一点点。最后聊一下我自己的习惯。个人开发机上我把CurrentUser级别的执行策略设置成了RemoteSigned日常脚本随便跑碰到从网上下载的一次性安装脚本绝不急着改全局而是先Unblock-File再执行或者直接用-ExecutionPolicy Bypass临时跑一趟。公司电脑上遇到被组策略锁死的情况我就找管理员协调策略项而不是想方设法跟组策略对抗。执行策略这个东西本质上是个“信任开关”你把它理解成一个可以精细调节的阀门而不是一个一关了之的堵头后面所有报错都会变得好查很多。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/10 18:48:40
iPhone iCloud ID解锁工具:激活锁绕过与官方移除全指南
2026/10/10 18:48:40
2026加密算法选型指南:从安全强度到后量子迁移
2026/10/10 18:48:40
KLJN协议遭遇统计随机数攻击:物理层安全如何被随机源偏差攻破
2026/10/10 20:13:51
Python深度学习实现高分辨率城市遥感图像水体提取系统
2026/10/10 20:13:51
Hadoop+SSH框架实现HDFS网盘:从环境搭建到Java API实战
2026/10/10 20:13:51
ST-GCN骨骼动作识别实战:从图卷积原理到源码部署与调参
2026/10/10 20:13:51
YOLOv5实战:垃圾桶满溢检测从数据标注到部署全指南
2026/10/10 20:13:51
自定义工具开发避坑指南:部署、依赖与性能优化实战
2026/10/10 20:08:50
2026 年九江濂溪区汽车贴膜本地综合实力榜:贴车衣、窗膜、改色膜哪家更适合更靠谱?认准锦波量子汽车贴膜!
2026/10/10 0:03:38
工业软件标准化路线图:国产替代的落地施工图
2026/10/10 0:03:38
VCMI安卓版实操指南:原生运行英雄无敌3的3步技术落地
2026/10/10 0:03:38
稀疏多通道盲反褶积的MATLAB算法实现与参数调优
2026/10/10 3:42:06
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/10 3:42:01
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/10 3:41:58
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/10 3:41:56
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/10 3:41:54
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/9 11:36:17
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)