You can sign PowerShell certificates with New-SelfSignedCertificate and without MakeCert

 

For those who can’t wait, here is the solution right away.
Next two lines actually work – without using MakeCert.exe:


New-SelfSignedCertificate -DnsName STA07 -Type CodeSigning

Set-AuthenticodeSignature C:\T\add-signature.ps1 @(gci Cert:\LocalMachine\My -DnsName STA07 -codesigning)[0]

First command creates a certificate in both Current User and Local Computer  Intermediate Certification Authorities.
 Second command signs the script.  Wow!  Innocent error in documentation from our Seattle friends (https://technet.microsoft.com/en-us/library/hh847874.aspx) probably due to luck of testing.  But a very satisfying result in the end.

Now the whole story.

On Monday, 2016-02-22 I converted last PC to Windows 10.  A got a nice clean and crispy install.  Everything is working well.  Everything is in place.  I do not want to install any ad hoc software that will muddy up the waters.  I want to keep this instance clean.

Dreams are good, but within minutes I needed to install some obscure SDK to get a single EXE off of it – MakeCert.exe to generate self-signed certificate.  But I do not want to do that.   All I want is to run a one-line script to change a PowerShell prompt every time I start it.  No. No. No.  Let me do this without any additional software. Windows only, baby.

And Microsoft promised that they have now a command –  New-SelfSignedCertificate – that will take care of this. OK. I am following the documentation.  I am discovering new things, but no, it doesn’t work. One error, many errors. I have a certificate, but it is not working to sign the scripts.  I am stuck.  I spent hour and a half (from 00:48 to 02:22) trying to create a certificate that would work.  That was a threshold for me.  If I am fighting with this, someone else will be fighting with this after me.  That screams an article.  Article!  Article!

Attention reader! The reason for my troubles was a mistake in Microsoft documentation.  The way they describe the process of generating certificate to sign script can’t work – https://technet.microsoft.com/en-us/library/hh847874.aspx

As a result, the solution found felt more like a scientific breakthrough, rather than a routine technical procedure.  All the help links on Internet would talk about utilizing MakeCert.exe, so I could not use any of those. But then, I found a hint of the solution at the very end of this long thread: http://powershell.org/wp/forums/topic/new-selfsignedcertificate-cmdlet/

Three month ago to the date, on November 22, 2015 Malcolm Gilbert posted a finding:

With a little experimentation I found that to use New-SelfSignedCertificate to generate a Codesigning certificate you need to use the -Type parameter.

That was the key – use parameter Type.  Somehow Malcolm Gilbert found the right option to use with New-SelfSignedCertificate.  Now with this hint, the scripts will get a digital signature at the end, but one more obstacle still remained: if you try to run a script signed this way, you will get this new error:

_10 Certificate is not trusted

For search engines pleasure, the error massage reads:

File C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1 cannot be loaded. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

Luckily, I already dealt with these type of messages, when configuring my remote access via VPN. To fix this error
01 I found my newly created certificate in Intermediate CA folder
02 copied it with right-mouse click and
03 pasted it Trusted Root CA with another right-mouse click.

In the picture below please notice that
01 to open this console I just pressed Windows key, typed “cert” and opened Manage Computer Certificates
02 type of new certificate is “CodeSigning” and
03 I found certificate in Intermediate and pasted it into Trusted Root.

_20 Code Signing Certificate

But the erroneous thing was that without contribution from Malcolm Gilbert, I would not have known what to do.  How people lived before?  How knowledge got proliferated without Internet?

And when I stared PowerShell next time, I was presented with four choices (image below).  I selected “A” to Always run, and all my problems were solved:

_30 Good Certificate

 

 

Conclusion

In Windows 10 you can’t run scripts in default configuration.  They are restricted.
Here are the steps that will allow you to run digitally signed scripts with your PowerShell.


*01* to check script execution policy (see help about_Execution_Policies):
Get-ExecutionPolicy
*02* to change script execution policy from restricted to signed:
Set-ExecutionPolicy AllSigned
*03* to create a self-signed certificate (see about_Signing)
Warning: documentation is wrong – you must use option -Type CodeSigning:
New-SelfSignedCertificate -DnsName STA07 -Type CodeSigning
*04* to make certificate trusted on this machine:
copy and paste your newly created certificate from Intermidite CA to Trusted Root CA
*05* to create a profile script (see about_Profiles):
if (!(test-path $profile.AllUsersAllHosts)) {new-item -type file -path $profile -force}
*06* to edit a profile script:
notepad $profile.AllUsersAllHosts
*07* to set your prompt to a display only folder (see about_Prompts):
function prompt {“$PWD>”}
*08* to sign a profile script (see about_Signing):
Set-AuthenticodeSignature $profile.AllUsersAllHosts @(gci Cert:\LocalMachine\My -DnsName STA07 -codesigning)[0]
`

Enjoy!
[written 2016-02-23 16:23]

[2018-01-01 MO 12:11]

When your certificate expires you will get this message:

File C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1 cannot be loaded. A required certificate is not within
its validity period when verifying against the current system clock or the timestamp in the signed file.
At line:1 char:3
+ . ‘C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1’
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess

– Generate your new certificate again () – it is generated for one year.
– Copy your new certificate to Local Machine Trusted Root Certification Authorities.

However, none of this actually worked.

To fix the error, I simply renamed profile.ps1 to something else, and PowerShell started to work without any errors.

(Visited 1,849 times, 1 visits today)

1 Comment

  1. Struggled with this because of the -type parameter I left out. Thanks for the post

Your question, correction or clarification Ваш вопрос, поправка или уточнение