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:
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.
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:
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.
Struggled with this because of the -type parameter I left out. Thanks for the post