SSMS可用性组中网络驱动器PowerShell脚本无法执行:未数字签名
问题情况
通过SSMS作业执行网络驱动器(如\\qaappdata\SQL\***\SimpleTest.ps1)上的PowerShell脚本时,持续出现未数字签名报错:
File \qaappdata\SQL***\SimpleTest.ps1 cannot be loaded...is not digitally signed. You cannot run this script on the current system. The error information returned by PowerShell is: + CategoryInfo : SecurityError: (:) [], PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
脚本放在本地D盘可正常运行,已尝试将执行策略设为Bypass、Unrestricted、RemoteSigned,甚至在脚本中添加命令:
Invoke-Command -ComputerName Server01 -ScriptBlock { Get-ExecutionPolicy } | Set-ExecutionPolicy Bypass -Force -Scope CurrentUser
服务器当前执行策略如下:
Scope ExecutionPolicy ----- --------------- MachinePolicy Undefined UserPolicy Undefined Process Undefined CurrentUser Undefined LocalMachine Unrestricted
核心原因
PowerShell默认将网络共享文件判定为「远程文件」,即便映射成本地盘符也不会改变这个属性。RemoteSigned策略要求远程脚本必须签名,Unrestricted虽允许未签名脚本,但无交互的SSMS作业环境会直接触发报错而非弹出警告。另外,SSMS作业的执行上下文可能和手动设置策略的上下文不一致,导致配置不生效。
解决办法
1. 在SSMS作业步骤中直接指定进程级执行策略
不在脚本内部设置策略,而是在调用脚本的命令开头添加参数,确保当前PowerShell进程生效:
如果是调用外部PowerShell进程:
powershell.exe -ExecutionPolicy Bypass -File "\\qaappdata\SQL\***\SimpleTest.ps1"
如果是SSMS的「PowerShell类型作业步骤」,在脚本开头添加:
Set-ExecutionPolicy Bypass -Scope Process -Force & "\\qaappdata\SQL\***\SimpleTest.ps1"
-Scope Process仅对当前进程生效,不会修改系统全局策略,安全且直接。
2. 将网络共享添加到PowerShell受信任路径
通过组策略配置,把目标网络共享加入受信任脚本路径:
- 打开组策略编辑器(
gpedit.msc),导航至「计算机配置→管理模板→Windows组件→Windows PowerShell」 - 启用「脚本执行」策略,选择「允许本地脚本和远程签名脚本」,在「受信任的脚本路径」中添加网络共享UNC路径(如
\\qaappdata\SQL\***) - 执行
gpupdate /force刷新组策略后,重启SSMS作业代理
3. 对脚本进行数字签名(合规方案)
若企业有严格安全要求,给脚本添加数字签名是长期解决方案:
- 获取代码签名证书(企业内部CA或第三方证书)
- 使用命令给脚本签名:
Set-AuthenticodeSignature -FilePath "\\qaappdata\SQL\***\SimpleTest.ps1" -Certificate (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert)
签名后,即使执行策略为RemoteSigned也可正常运行。
内容的提问来源于stack exchange,提问作者KW1

