The majority of Windows administrators, who are familiar with PKI, know about the MakeCert.exe utility, which allows to create a self-signed certificate. This tool is included in the Microsoft .NET Framework SDK and Microsoft Windows SDK. In Windows 8 and Windows Server 2012, a self-signed certificate can be created using PowerShell 3.0 (or higher) without any special tools.
Using the New-SelfSignedCertificate Cmdlet to Create a Self-Signed Certificate
To create a self-signed certificate in PowerShell, it is recommended to use New-SelfSignedCertificate cmdlet, which is a part of PoSh PKI (Public Key Infrastructure) module:
To list all available cmdlets in the PKI module, run the command.
Get-Command -Module PKI
It is recommended to use a self-signed certificate for testing purposes or to provide certificates for Intranet services (IIS, Exchange, Web Application Proxy, LDAPS, ADRMS, DirectAccess etc.) if for some it is impossible to deploy a PKI/CA infrastructure or purchase a trusted certificate from an external provider.
To create a certificate, you have to specify the values of –DnsName (DNS name of a server, the name may be arbitrary and different from localhost name) and -CertStoreLocation (a local certificate store in which the generated certificate will be placed). You can use the cmdlet to create a self-signed certificate in Windows 10 (in our example), Windows 8/8.1 and Windows Server 2016/ 2012 R2 /2012.
To create a certificate for the DNS name test.contoso.com and place it to the list of personal certificates on a computer, run the following command:
New-SelfSignedCertificate -DnsName test.contoso.com -CertStoreLocation cert:\LocalMachine\My
This command creates a certificate and imports it in a personal store of the computer. Having opened certlm.msc snap-in, make sure that a new certificate has appeared in the Personal section of the certificate storage.
By default, a self-signed certificate is generated with the following settings:
- Cryptographic algorithm: RSA;
- Key length: 2048 bit;
- Acceptable key usage: Client Authentication and Server Authentication;
- The certificate can be used for: Digital Signature, Key Encipherment;
- Validity period: 1 year.
$todaydt = Get-Date
$3years = $todaydt.AddYears(3)
New-SelfSignedCertificate -dnsname test.contoso.com -notafter $3years -CertStoreLocation cert:\LocalMachine\My
In order to export the generated certificate with a private key to a password protected PFX file, you will need its thumbprint. It can be copied from the results of New-SelfSignedCertificate command:
$CertPassword = ConvertTo-SecureString -String “YourPassword” -Force –AsPlainText
Export-PfxCertificate -Cert cert:\LocalMachine\My\2779C7928D055B21AAA0Cfe2F6BE1A5C2CA83B30 -FilePath C:\test.pfx -Password $CertPassword
The certificate public key can be exported as follows:
Export-Certificate -Cert Cert:\LocalMachine\My\2779C7928D055B21AAA0Cfe2F6BE1A5C2CA83B30 -FilePath C:\tstcert.cer
This public key or the certificate file itself can be installed on a web-server or domain clients using GPO (How to install a certificate on a domain PCs using GPO).
One of the useful features of New-SelfSignedCertificate cmdlet is the opportunity to create a certificate with several different names Subject Alternative Names (SAN).
For example, let’s create a self-signed SAN certificate with the following names:
- Subject Name (CN): adfs1.contoso.com
- Subject Alternative Name (DNS): web_gw.contoso.com
- Subject Alternative Name (DNS): enterprise_reg.contoso.com
The command will look like this:
New-SelfSignedCertificate -DnsName adfs1.contoso.com,web_gw.contoso.com,enterprise_reg.contoso.com -CertStoreLocation cert:\LocalMachine\My
Also, you can issue a certificate for the entire namespace in the domain. To do it, specify *.contoso.com as a server name.
New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname *.contoso.com
Create a Self-Signed Certificate for Code Signing
In PoweShell 3.0, the New-SelfSifgnedCertificate cmdlet was generating only SSL certificates that couldn’t be used to sign the driver and application code (unlike certificates generated by the MakeCert utility). In PowerShell 5 the new version of the New-SelfSifgnedCertificate cmdlet can now be used to issue a Code Signing certificates.
To create a self-signed certificate for signing the application code, run the command:
$cert = New-SelfSignedCertificate -Subject "My Code Signing Certificate” -Type CodeSigningCert -CertStoreLocation cert:\LocalMachine\My
Set-AuthenticodeSignature -FilePath C:\PS\my_posh_script.ps1 -Certificate $cert
If you are receiving an UnknownError warning when executing the command, this means that the certificate is not trusted, because it is located in the user’s personal certificates store.
You need to move it to the trusted root certificates (don’t forget to periodically scan the Windows certificate root store for suspicious certificates and update the lists of trusted root certificates).
Move-Item -Path $cert.PSPath -Destination "Cert:\CurrentUser\Root"
After that, you can sign your PowerShell script with this self-signed certificate.