PowerShell Script digitally signed error

无人久伴 提交于 2019-12-24 06:29:13

问题


I'm getting an error when I run a PowerShell script:

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

I created a CA and a certificate and signed this file using the procedure described here.

Here is when I do a dir on the MY directory:

EF76B3D7D8D2406E1F2EE60CC40644B122267F18  CN=PowerShell User

I can see the signature block appended at the end of the test_new.ps1 file.

Here is the execution policy and scope:

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

The machinepolicy should take priority which is set as AllSigned. Everything seems allright, why am I still getting the digitally signed error.


回答1:


Finally found a solution to this:

$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()

It had to be published in the TrustedPublisher store for it to work.




回答2:


Powershell execution policy set to Allsigned only run scripts which are signed by trusted publisher only. You can find the possible values for -ExecutionPolicy parameter below:

Restricted: The default setting which does not load configuration files or run scripts.

AllSigned: Requires that all scripts and configuration files be signed by a trusted publisher, including scripts that you write on the local computer.

RemoteSigned: Requires that all scripts and configuration files downloaded from the Internet be signed by a trusted remote publisher.

Unrestricted: Loads all configuration files and runs all scripts. If you run an unsigned script that was downloaded from the Internet, you are prompted for permission before it runs.

Bypass: Nothing is blocked and there are no warnings or prompts.

Undefined: Removes the currently assigned execution policy from the current scope, returning the session to the default. This parameter will not remove an execution policy that is set in an Active Directory Group Policy.

You can set PowerShell execution policy by a command like:

Set-ExecutionPolicy unrestricted

If you want to run the script on the domain network, then you would probably use Group Policy to make sure the code signing certificate used to sign the script is a trusted publisher in your domain. To do this there are two steps:

  1. Export the code signing certificate.

  2. Create a policy and import the code signing certificate into trusted publishers.

Once the policy is updated in your domain network then the Trusted Publisher certificate should list in 'Trusted Publisher' under Certificates snap-in.




回答3:


Edit -- added some information

One of the possible approaches circumvent the security altogether and start your script like this (for getting around imposed GPOs see bottom of this post):

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

Tested on Windows 2003 in domain and restricted powershell.

First Edit - Due to the comment that it is not possible I'm showing screenshot from the production system where I have run the script:

Started powershell with Bypass on and executed the script:

Started powershell without Bypass on and executed the script:

System information:

Second Edit - due to comment @AnsgarWiechers. (As it is Microsoft we are talking about there is usually a way to get around imposed security measures.)

To quote the comment:

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

The ExecutionPolicy key that is being pushed by the Group Policy object located at registry's hive: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell.

When you change the value from any, see more at 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. I'm sure somebody more creative can find some other ways how to get around GPO.

That said for permanent solution it is better your repeated use. It can, presumably, be more secure to use keys, even thou that will depend also on other factors.

Third edit - proving the GPO policies can be circumvented (if you have enough rights to do so)

I have finally found some time to explore the possibilities. For Windows 2003 it is not possible to change the local policy via editing the group policies gpedit.msc, it must be done on domain level (Windows 2003 are not supported by MS and are currently EOL)

On Windows 2008 it is different story.

If you change the local policies you can easily change the policies to AllSigned as shown below:

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

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

If you then execute script via the above mentioned parameters: -NoProfile -ExecutionPolicy Bypass you will get the following message so your GPO policies require to have the scripts signed:

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

You can check also the registry settings to be sure (also will show the value to which you want to return the value after running the script):

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

This can easily be circumvented via, if you are having the correct rights to do so (this will set the ExecutionPolicy to "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)

Then if you check the execution policy you will find out there is, indeed, a change:

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

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

If you then run the script it will run just fine.

When you are finished you can return the previous value back via:

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

Forth Edit - Conclusion

I want to be crystal clear so I'm adding the conclusion, since the comments below can lead to false assumptions.

This is the maximum security the parameters '-NoProfile -ExecutionPolicy Bypass will work with:

PS C:\> Get-ExecutionPolicy -List

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

The only case you need some way around it or having a signed key is when the MachinePolicy is set to AllSigned. The optimal solution is to use keys. If you can not for some reason you can use the above steps to change the values in the registry or try one of these 15 ways to bypass the powershell execution policy which is already linked above.



来源:https://stackoverflow.com/questions/46727899/powershell-script-digitally-signed-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!