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
如果您想 运行 域网络上的脚本,那么您可能会使用组策略来确保用于对脚本进行签名的代码签名证书是您域中受信任的发布者。为此,有两个步骤:
导出代码签名证书。
创建策略并将代码签名证书导入受信任的发布者。
在您的域网络中更新策略后,受信任的发布者证书应列在证书管理单元下的 '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
我在 运行 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
如果您想 运行 域网络上的脚本,那么您可能会使用组策略来确保用于对脚本进行签名的代码签名证书是您域中受信任的发布者。为此,有两个步骤:
导出代码签名证书。
创建策略并将代码签名证书导入受信任的发布者。
在您的域网络中更新策略后,受信任的发布者证书应列在证书管理单元下的 '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