Using PowerShell to Create Self-Signed Certificate

16,978

Solution 1

It might not help for your specific use, but there is a new Powershell CmdLet installed in Windows 8.1 and Server 2012 that is pretty quick and easy to use:

New-SelfSignedCertificate [-CertStoreLocation <String> ] [-CloneCert <Certificate> ] [-DnsName <String> ] [-Confirm] [-WhatIf] [ <CommonParameters>]

More details can be found here: https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps

In my usage, the friendly name of the cert has always been set as the first DnsName specified in the CmdLet.

Example that places the certificate in your Local Computer's Personal store:

New-SelfSignedCertificate -CertStoreLocation cert:\LocalMachine\My -DnsName www.example.com

Note: Powershell has to be started with admin rights for this to work.

Solution 2

You can set the CertificateFriendlyName directly in you code, you just need to know where to do it:

$enrollment.InitializeFromRequest($cert)
$enrollment.CertificateFriendlyName = 'whatever'
$certdata = $enrollment.CreateRequest(0)

$key has a FriendlyName but I don't see that showing up anywhere so I don't think it helps you.

Share:
16,978
roderickprince
Author by

roderickprince

Updated on June 10, 2022

Comments

  • roderickprince
    roderickprince almost 2 years

    I'm using code similar to that found here to create a self-signed certificate for use in IIS: http://blogs.technet.com/b/vishalagarwal/archive/2009/08/22/generating-a-certificate-self-signed-using-powershell-and-certenroll-interfaces.aspx

    Works fine except I want to give it a friendly name to make locating it easier when I want to assign the certificate to a dynamically created site.

    Anyone know how to change the above to set the friendly name (I've tried what seemed obvious to no avail).

    Got a better way to create a cert via PowerShell that does not prompt the user for information?

    Followup on the script I am using - based on the url above but turned into a cmdlet:

    function Add-SelfSignedCertificate
    {
        [CmdletBinding()]
        param
        (
                [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True)]
                [Alias('cn')]
                [string]$CommonName
        )
    
        $name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
        $name.Encode("CN=$CommonName", 0)
    
        $key = new-object -com "X509Enrollment.CX509PrivateKey.1"
        $key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
        $key.KeySpec = 1
        $key.Length = 1024
        $key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
        $key.MachineContext = 1
        $key.Create()
    
        $serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
        $serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1")
        $ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
        $ekuoids.add($serverauthoid)
        $ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
        $ekuext.InitializeEncode($ekuoids)
    
        $cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
        $cert.InitializeFromPrivateKey(2, $key, "")
        $cert.Subject = $name
        $cert.Issuer = $cert.Subject
        $cert.NotBefore = get-date
        $cert.NotAfter = $cert.NotBefore.AddDays(90)
        $cert.X509Extensions.Add($ekuext)
        $cert.Encode()
    
        $enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
        $enrollment.InitializeFromRequest($cert)
        $certdata = $enrollment.CreateRequest(0)
        $enrollment.InstallResponse(2, $certdata, 0, "")
    }