new-SelfsignedCertificate cmdlet

Hi

I recently watched the MVA Powershell 3.0 Jump start with Jeffrey Snover and Jason Helmick. Brilliantly informative as was the follow up sessions on advanced PS tools. There was one section in the presentation where Jeffrey went into detail about using self-signed certificates for signing scripts. Although he brushed over the use of the cmdlet new-SelfsignedCertificate for generating his codesigning certificates. Frustratingly this was the part I wanted to understand as I have previously used makecert.exe to generate the correct type of certificates. I did some research using help and looking online but there’s not much out there at the moment.
I ended up running the following to create a certificate …
$cert = New-SelfSignedCertificate -DnsName localhost, $env:COMPUTERNAME -CertStoreLocation Cert:\LocalMachine\My

But this does not seem to generate a codesigning certificate, as when I then run…

dir Cert:\LocalMachine\My -Recurse -CodeSigningCert

nothing shows up.
It does appear as without the -CodeSigningCert switch.

How did Jeffery create codesigning certificates?

Cheers
Tony

Hi Tony!

Glad the MVA was helpful. Take a look at the help file About_Signing. The entire process is listed step-by-step, and if you get stuck, I’ll be happy to help. One question I wasn’t clear on, do you want to use a real code signing certificate or self signed one? The About_Signing demonstrates creating a self signed one (NEw-SelfSignedCertificate) but if you need a real code signing certificate you will need to purchase and install one before the command to sign a script will work. You can also create one using ADCS.

Take a look at that help file and let me know if you get stuck.

Cheers!

Jason

Hi Jason!
Thanks for getting back.
I pretty much used the about signing help file originally when using makecert and my current updated help file still shows makecert.exe with reference to new-selfsignedcertificate. It doesn’t tell you much about the new cmdlet though just refers to the help new-selfsignedcertificate.
From what I can gather new-selfsignedcertificate will let me clone a certificate (I don’t have one to clone) or create an ssl certificate with a default set of values. Not the type I’m after.
Just to confirm I want to use the new-self-signed-certificate cmdlet to generate my own codesigning certificates on my local machine only. I can go back to makecert but in your presentation Jeffrey did say he created his using this cmdlet.

Cheers
Tony

Hi Tony!

I would use the Makecert – I don’t think that New-SelfSignedCertificate creates a certificate suitable for code signing, although it would seem to clone an existing one. The one it creates works fine for SSL testing. Perhaps someone on the forums can correct me. AS an example, this DOES NOT produce the intended result of a code signing certificate.

New-SelfSignedCertificate -DnsName www.company.com -CertStoreLocation cert:\LocalMachine\My
$cert=Get-ChildItem -Path cert:\Localmachine\My | Where{$_.Subject -like “company”}
Set-AuthenticodeSignature -FilePath C:\scripts\test.ps1 -Certificate $cert

I’ve used MakeCert very successfully, and of course ADCS. Perhaps consider making a code signing cert with MAkeCert or ADCS, then cloning it when needed?

Does that help?

Thanks Jason,
I’m glad you found it behaved the same way. I’ll continue with makecert for now and wait for an update. Out of interest which type of codesigning certificates can be cloned for this? The ones bundled with the os or specific ca roots?

Hi,

I’m watching the same course on MVA and I enjoy it a LOT! You guys make those things so easy and fun to understand that it’s a pleasure to learn!
However, I’m running into the same problem, that is, I cannot create a self-signed cert.
I’ve checked out the about_signing help file, where it says:

“The New-SelfSignedCertificate cmdlet, introduced in the PKI module
in Windows PowerShell 3.0, creates a self-signed certificate that is
Appropriate for testing. For more information, see the help
topic for the New-SelfSignedCertificate cmdlet.”

and

"To create a self-signed certificate in use the New-SelfSignedCertificate
cmdlet in the PKI module. This module is introduced in Windows PowerShell
3.0 and is included in Windows 8 and Windows Server 2012. For more
information, see the help topic for the New-SelfSignedCertificate cmdlet.

To create a self-signed certificate in earlier versions of Windows, use
the Certificate Creation tool (MakeCert.exe). This tool is included in
the Microsoft .NET Framework SDK (versions 1.1 and later) and in the
Microsoft Windows SDK."

I tried to run makecert.exe in cmd and PS, but I get an error saying that makecert isn’t recognized as a command.
I also checked the help file for New-SelfSignedCertificate, but it couldn’t figure out anything.

I’m able to create a cert with this comnad, but when I try to sign the script, I get this error:

"Set-AuthenticodeSignature : Cannot bind argument to parameter ‘Certificate’ because it is null.
At line:1 char:36

  • Set-AuthenticodeSignature test.ps1 $cert
  •                                ~~~~~
    
    • CategoryInfo : InvalidData: (:slight_smile: [Set-AuthenticodeSignature], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAuthenti
      codeSignatureCommand"

I’m stuck.

is it necessary to have AD to generate self signed-certificate ?

here is the error am getting

  • CategoryInfo : NotSpecified: (:slight_smile: [New-SelfSignedCertificate], InvalidStorePathException
  • FullyQualifiedErrorId : RuntimeException,Microsoft.CertificateServices.Commands.NewSelfSignedCertificateCommand

I think it’s not necessary. I can create self-signed certificates on my non-domain computer, the problem is, that I cannot sign a sript with them.

I realize that this is a little late but I had the same problem as the OP.

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

new-selfsigningcertificate -certstorelocation “cert:\CurrentUser\My” -DnsName… -Type CodeSigning

Then the dir -CodeSigning -outVariable etc. examples in the MVA video will work.

Unfortunately the generated certificate causes an error “is not trusted by the trust provider”. when added to the test.ps1 file

If anyone knows a solution to this I would be grateful.

[EDIT]
I have managed to create a valid codesigning certificate by following the steps in an article by Scott Hanselman at http://www.hanselman.com/blog/SigningPowerShellScripts.aspx
I would still like to be able to do it entirely in PowerShell if that’s possible though.
[/EDIT]

I know this is an old post, but I thought I’d post the solution I came up with in PowerShell 5.1 (should work for 3.0 & higher). When the self-signed code signing certificate is created, it’s not from a trusted CA (i.e. “Issued by”). When you look at the certificate in the Certificates mmc (Current User - Personal - Certificates), you see that it’s not trusted. At the top of the certificate it tells you what the problem is and how to fix it:

“This CA Root certificate is not trusted. To enable trust, install this certificate in the Trusted Root Certification Authorities store.”

I put together the following script to create the self-signed code signing certificate, export it out from the current user’s personal store (i.e. Cert:\CurrentUser\My), and re-import it into the Trusted Root Certification Authorities store of the current user (i.e. Cert:\CurrentUser\Root). To use it copy the below text into a text file and save the file as Create-CodeSigningCertificate.ps1. You will get a security warning when it tries to install the certificate into the Trusted Root Certificate Authorities store. This is expected. You have to click the Yes button to install it. Also, you can run Help .\Create-CodeSigningCertificate.ps1 -Full, just like you can for a powershell cmdlet, to see the comment-based help. Hopefully you will find it helpful.

I’ve been having trouble getting the entire script to post, so here is the first part.

<#
.Synopsis
This script creates a self-signed certificate, exports it, and re-imports it into the Trusted Root Certification Authorities store.
.Description
This script creates a self-signed code signing certificate, valid for one year from the date/time created, that can be used for testing purposes to sign scripts.  After the certificate is created, the issuer is untrusted.  So, the script then exports the certificate into a .cer file and re-imports it into the Trusted Root Certification Authorities store for the current user (i.e. Cert:\CurrentUser\Root).
.Parameter DnsName
Specify one, or more, DNS names to put into the subject alternative name (SAN) extension of the certificate. The first DNS name is also saved as the subject name, issuer name (i.e. Issued By), and common name (i.e. Issued To).  Default is the local computer name (i.e. $Env:ComputerName).  This parameter has aliases of SubjectAlternativeName and SAN.
.Parameter FileName
The .cer file you want to export the code signing certificate to.
.Example
Create-CodeSigningCertificate -FileName C:\cert.cer -DnsName Server1

OR

I know this is an old post, but I thought I’d post the solution I came up with in PowerShell 5.1 (should work for 3.0 & higher). When the self-signed code signing certificate is created, it’s not from a trusted CA (i.e. “Issued by”). When you look at the certificate in the Certificates mmc (Current User - Personal - Certificates), you see that it’s not trusted. At the top of the certificate it tells you what the problem is and how to fix it:

“This CA Root certificate is not trusted. To enable trust, install this certificate in the Trusted Root Certification Authorities store.”

I put together the following script to create the self-signed code signing certificate, export it out from the current user’s personal store (i.e. Cert:\CurrentUser\My), and re-import it into the Trusted Root Certification Authorities store of the current user (i.e. Cert:\CurrentUser\Root). To use it copy the below text into a text file and save the file as Create-CodeSigningCertificate.ps1. You will get a security warning when it tries to install the certificate into the Trusted Root Certificate Authorities store. This is expected. You have to click the Yes button to install it. Also, you can run Help .\Create-CodeSigningCertificate.ps1 -Full, just like you can for a powershell cmdlet, to see the comment-based help. Hopefully you will find it helpful.

Note: Ignore my previous posts as the code from my script was not getting fully posted.

https://gist.github.com/miracles1315/5536df69a25145e04b2aecbb2ddfc179

I changed the script file name. It’s not called New-CodeSigningCertificate.ps1 in order to use an approved verb (Get-Verb).