PowerShell 脚本数字签名错误

PowerShell Script digitally signed error

我在 运行 PowerShell 脚本时遇到错误:

File test_new.ps1 cannot be loaded. The file test_new.ps1 is not digitally signed.

我创建了一个 CA 和一个证书,并使用 here.

中描述的过程对该文件进行了签名

这是我在 MY 目录上执行 dir 时的情况:

EF76B3D7D8D2406E1F2EE60CC40644B122267F18  CN=PowerShell User

我可以看到附加在 test_new.ps1 文件末尾的签名块。

这是执行政策和范围:

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       AllSigned
   UserPolicy       Undefined
      Process          Bypass
  CurrentUser       AllSigned
 LocalMachine       Undefined

机器策略应优先设置为AllSigned。一切似乎都很好,为什么我仍然收到数字签名错误。

Powershell 执行策略设置为仅 Allsigned 运行 仅由受信任的发布者签名的脚本。您可以在下面找到 -ExecutionPolicy 参数的可能值:

Restricted:默认设置不加载配置文件或 运行 脚本。

AllSigned:要求所有脚本和配置文件都由受信任的发布者签名,包括您在本地计算机上编写的脚本。

RemoteSigned:要求从 Internet 下载的所有脚本和配置文件都必须由受信任的远程发布者签名。

无限制:加载所有配置文件和运行所有脚本。如果您 运行 从 Internet 下载的未签名脚本,系统会在 运行 之前提示您获得许可。

绕过: 什么都没有被阻止,也没有警告或提示。

未定义:从当前作用域中移除当前分配的执行策略,将会话返回到默认值。此参数不会删除在 Active Directory 组策略中设置的执行策略。

您可以通过以下命令设置 PowerShell 执行策略:

Set-ExecutionPolicy unrestricted

如果您想 运行 域网络上的脚本,那么您可能会使用组策略来确保用于对脚本进行签名的代码签名证书是您域中受信任的发布者。为此,有两个步骤:

  1. 导出代码签名证书。

  2. 创建策略并将代码签名证书导入受信任的发布者。

在您的域网络中更新策略后,受信任的发布者证书应列在证书管理单元下的 'Trusted Publisher' 中。

终于找到了解决办法:

$cert=Get-ChildItem cert:\CurrentUser\MY
$store = New-Object 
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store ("TrustedPublisher" , "LocalMachine")
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()

它必须在 TrustedPublisher 商店中发布才能工作。

编辑 -- 添加了一些信息

一种可能的方法完全规避安全并像这样启动你的脚本(要绕过强加的 GPO,请参阅此 post 的底部):

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\path_to_file\test_new.ps1""'}"

在 Windows 2003 域和受限 powershell 中测试。

First Edit - 由于评论说这是不可能的,所以我展示了生产系统的屏幕截图,其中我有 运行 脚本:

启动 powershell 并启用旁路并执行脚本:

在没有绕过的情况下启动 powershell 并执行脚本:

系统信息:

第二次编辑 - 由于评论@AnsgarWiechers。 (因为我们谈论的是 Microsoft,通常有一种方法可以绕过强加的安全措施。)

引用评论:

...The OP has the execution policy enforced with a GROUP POLICY (scopes MachinePolicy and/or UserPolicy). Which CANNOT BE BYPASSED...'

由位于注册表配置单元的组策略对象推送的 ExecutionPolicy 密钥:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell

当您更改任何值时,请参阅 Possible values for execution policies) to bypass. Then you can circumvent the GPO imposed. I'm sure there are other ways how to do it. For more ideas you can check good resource。我相信更有创意的人可以找到其他方法来绕过 GPO。

也就是说,对于永久解决方案,最好重复使用。据推测,使用密钥可能更安全,即使这也取决于其他因素。

第三次编辑 - 证明可以规避 GPO 策略(如果您有足够的权限这样做)

我终于抽出一些时间来探索各种可能性。对于 Windows 2003,无法通过编辑组策略 gpedit.msc 来更改本地策略,必须在域级别完成(Windows MS 不支持 2003,目前 EOL)

Windows 2008 上是不同的故事。

如果您更改本地策略,您可以轻松地将策略更改为 AllSigned,如下所示:

PS C:\Windows\system32> Get-ExecutionPolicy -List

                                  Scope                         ExecutionPolicy
                                  -----                         ---------------
                          MachinePolicy                               AllSigned
                             UserPolicy                               AllSigned
                                Process                                  Bypass
                            CurrentUser                               Undefined
                           LocalMachine                               AllSigned

如果您随后通过上述参数执行脚本:-NoProfile -ExecutionPolicy Bypass 您将收到以下消息,因此您的 GPO 策略要求对脚本进行签名:

File E:\t\powershell\get_local_admins_computer.ps1 cannot be loaded. The file E
:\t\powershell\get_local_admins_computer.ps1 is not digitally signed. The scrip
t will not execute on the system. Please see "get-help about_signing" for more
details..
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordE
   xception
    + FullyQualifiedErrorId : RuntimeException

您还可以检查注册表设置以确保(也将显示您想要 return 运行 脚本后的值的值:

C:\Windows\system32>REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Win
dows\PowerShell

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell
    EnableScripts    REG_DWORD    0x1
    ExecutionPolicy    REG_SZ    AllSigned

这很容易被规避,如果您有正确的权限(这会将 ExecutionPolicy 设置为 "bypass"):

   reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell" /f /v "ExecutionPolicy" /t REG_SZ /d "bypass"
    /v ... ValueName
    /t ... type
    /d ... data
    /f ... force (overwrites current value)

然后如果你检查执行策略,你会发现确实有一个变化:

PS C:\Windows\system32> Get-ExecutionPolicy -List

                              Scope                         ExecutionPolicy
                              -----                         ---------------
                      MachinePolicy                                  Bypass
                         UserPolicy                               AllSigned
                            Process                                  Bypass
                        CurrentUser                               Undefined
                       LocalMachine                               AllSigned

如果你然后 运行 脚本它将 运行 就好了。

完成后,您可以通过以下方式return返回之前的值:

reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell" /f /v "ExecutionPolicy" /t REG_SZ /d "AllSigned"

第四次编辑 - 结论

我想 crystal 清楚所以我添加了结论,因为下面的评论可能会导致错误的假设。

这是参数 '-NoProfile -ExecutionPolicy Bypass 将使用的最大安全性:

PS C:\> Get-ExecutionPolicy -List

                                                      Scope                                             ExecutionPolicy
                                                      -----                                             ---------------
                                              MachinePolicy                                                RemoteSigned
                                                 UserPolicy                                                   AllSigned
                                                    Process                                                   AllSigned
                                                CurrentUser                                                   AllSigned
                                               LocalMachine                                                   AllSigned

只有 的情况你需要一些方法来绕过它或者有一个签名的密钥是当 MachinePolicy 设置为 AllSigned。最佳解决方案是使用密钥。如果由于某种原因您不能,您可以使用上述步骤更改注册表中的值或尝试其中一个 15 ways to bypass the powershell execution policy 已在上面链接。

显然和PowerShell的策略有关,有3个选项,可以改变pass from this error和所有同类型的策略。

1 Set-ExecutionPolicy Bypass -Scope CurrentUser -Force

2 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force.(推荐)

3 Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force。 (不推荐,因为您的计算机环境对恶意软件或任何有害软件的抵抗力变弱...)

要修复它,您必须 运行 下面的命令 运行 Set-ExecutionPolicy 并更改执行策略设置。

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass