2

Create Free Lets Encrypt SSL Certificates Using Powershell

Create Free Lets Encrypt SSL Certificates Using Powershell-Post

In this day and age the use of SSL certificates are an excellent method for connecting to anything securely. The majority of sites you browse have that ‘lock’ icon enabled, meaning that you’ve successfully created an encrypted tunnel between yourself and the site you’re currently browsing. Great! One thing to note though is that not all public SSL certificates are created equal. They all provide the same functionality, yes, but some can cost hundreds of dollars year and/or the time for each cert to expire varies between who you decide to get your public SSL cert from. In this article I’m going to go over a method I use to create free Lets Encrypt SSL Certificates using Powershell

 
As a Systems Administrator, probably the most common use case for implementing a Public SSL cert would from the example above. Setting up your org’s website to connect over HTTPS is the standard. As a matter of fact, Google mentioned they will lower your SEO (Search Engine Optimization) for websites that don’t use SSL because it provides a poorer user experience. But, websites are not the only use case for using SSL certs. Microsoft Exchange and Microsoft ADFS are some other platforms that require the use of an SSL connection. Also, I’m the type of admin that loves to practice, practice and practice some more. So when I’m getting myself familiar with onprem exchange or setting up ADFS in my lab I love that I can generate some public SSL certs for free. The only thing you’ll need is the script below to make sure everything is automated as well as the POSH-Acme module for Powershell

Watch how I create free Lets Encrypt SSL Certificate for Exchange Server

After watching how it’s done, the next step would be to see if it works for you and your environment. Whether that be your lab or your actual production network. The tools are there and it’s up to you to determine what works best.

Below are the 2 scripts that are used in the video to be able to create a Lets Encrypt SSL Cert and to be able to update your Lets Encrypt SSL cert.

Create Free Lets Encrypt SSL Certificates Using Powershell


#requires -Module Posh-ACME
#requires -RunAsAdministrator

#region Information Gathering
    Set-PAServer LE_PROD

    $CFAuthEmail = '[email protected]'
    $CFAuthKey = 'xxxxxxxxYourCloudFlareAPIKeyxxxxxxxxxx'
    $FriendlyName = "LetsEncrypt_$((Get-Date).AddDays(90).ToString('yyyy-MM-dd'))"
    $CFParams = @{CFAuthEmail=$CFAuthEmail; CFAuthKey=$CFAuthKey}
    $PFXPass = 'StrongPFXPasswordGoesHere'
    $Domains = "*.thesysadminchannel.com","*.ad.thesysadminchannel.com","thesysadminchannel.com"

    $DownloadPath = "\\PAC-FS01\Apps\_LetsEncryptCerts$((Get-Date).ToString('yyyyMM'))"
    $ContactEmail = '[email protected]'
#endregion 


#region Create Lets Encrypt SSL Cert
    $NewCertificate = New-PACertificate $Domains -AcceptTOS -Contact $ContactEmail -DnsPlugin Cloudflare -PluginArgs $CFParams -DNSSleep 180 -PfxPass $PFXPass -Force
    $NewCertificate
#endregion


#region Copy to fileserver
#ProdPath = "$env:LOCALAPPDATA\Posh-ACME\acme-v02.api.letsencrypt.org"
    mkdir $DownloadPath
    $Path = Get-PACertificate | select -ExpandProperty CertFile
    $Path = $Path.Substring(0,$Path.LastIndexOf('\'))
    Copy-Item "$Path\cert.cer" $DownloadPath -Force
    Copy-Item "$Path\cert.key" $DownloadPath -Force
    Copy-Item "$Path\cert.pfx" $DownloadPath -Force
#endregion


#region Import PFXPassword, ComputerList and Thumbprint
    $PFXPassword = $PFXPass | ConvertTo-SecureString -AsPlainText -Force

    #Enter the array of computers needing the cert
    $ComputerList = "PAC-EXCH01"#, "PAC-WIN1002"
    $Thumbprint = $NewCertificate.Thumbprint
#endregion


#region Deploy to remote machines
    foreach ($Computer in $ComputerList) {
        Copy-Item "$DownloadPath\Cert.pfx" "\$Computer\c$"
    }

    Invoke-Command -ComputerName $ComputerList -ScriptBlock {
        Import-PfxCertificate -FilePath "C:\cert.pfx" -CertStoreLocation Cert:\LocalMachine\My\ -Exportable:$false -Password $Using:PFXPassword
        $Cert = Get-ChildItem Cert:\LocalMachine\My$($Using:Thumbprint)
        $Cert.FriendlyName = $Using:FriendlyName
    }

    foreach ($Computer in $ComputerList) {
        Remove-Item "\$Computer\c$\cert.pfx"
    }
#endregion


#region Install SSL Cert on Exchange Server
    $Exchange = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://pac-exch01.ad.thesysadminchannel.com/powershell
    Import-PSSession $Exchange

    Enable-ExchangeCertificate -Services 'SMTP,IIS' -Thumbprint $Thumbprint -Confirm:$false -Force
#endregion


#region Cleanup
    Invoke-Command -ComputerName $ComputerList -ScriptBlock {
        Get-ChildItem Cert:\LocalMachine\My\ | Where-Object {($_.Subject -eq 'CN=*.thesysadminchannel.com') -and ($_.ThumbPrint -ne $Using:Thumbprint)} | Remove-Item -Force
    }
#endregion

 

Update Lets Encrypt SSL Certificates Using Powershell


#requires -Module Posh-ACME
#requires -RunAsAdministrator

#region Information Gathering
    Set-PAServer LE_PROD

    $Path = Get-PACertificate | select -ExpandProperty CertFile
    $Path = $Path.Substring(0,$Path.LastIndexOf('\'))

    $PFXPass = 'StrongPFXPasswordGoesHere'

    $FriendlyName = "LetsEncrypt_$((Get-Date).AddDays(90).ToString('yyyy-MM-dd'))"    
    $DownloadPath = "\\PAC-FS01\Apps\_LetsEncryptCerts$((Get-Date).ToString('yyyyMM'))"
#endregion


#region Create Lets Encrypt SSL Cert
    $NewCertificate = Submit-Renewal -Force
    $NewCertificate
#endregion


#region Copy to fileserver
    mkdir $DownloadPath -Force
    Copy-Item "$Path\cert.cer" $DownloadPath -Force
    Copy-Item "$Path\cert.key" $DownloadPath -Force
    Copy-Item "$Path\cert.pfx" $DownloadPath -Force
#endregion


#region Import PFXPassword, ComputerList and Thumbprint
    $PFXPassword = $PFXPass | ConvertTo-SecureString -AsPlainText -Force

    #Enter the array of computers needing the cert
    $ComputerList = "PAC-EXCH01"#, "PAC-WIN1002"
    $Thumbprint = $NewCertificate.Thumbprint
#endregion


#region Deploy to remote machines
    foreach ($Computer in $ComputerList) {
        Copy-Item "$DownloadPath\Cert.pfx" "\$Computer\c$"
    }

    Invoke-Command -ComputerName $ComputerList -ScriptBlock {
        Import-PfxCertificate -FilePath "C:\cert.pfx" -CertStoreLocation Cert:\LocalMachine\My\ -Exportable:$false -Password $Using:PFXPassword
        $Cert = Get-ChildItem Cert:\LocalMachine\My$($Using:Thumbprint)
        $Cert.FriendlyName = $Using:FriendlyName
    }

    foreach ($Computer in $ComputerList) {
        Remove-Item "\$Computer\c$\cert.pfx"
    }
#endregion


#region Install SSL Cert on Exchange Server
    $Exchange = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://pac-exch01.ad.thesysadminchannel.com/powershell
    Import-PSSession $Exchange

    Enable-ExchangeCertificate -Services 'SMTP,IIS' -Thumbprint $Thumbprint -Confirm:$false -Force
#endregion


#region Cleanup
    Get-ChildItem $Path *.bak | Remove-Item
    Invoke-Command -ComputerName $ComputerList -ScriptBlock {
        Get-ChildItem Cert:\LocalMachine\My\ | Where-Object {($_.Subject -eq 'CN=*.thesysadminchannel.com') -and ($_.ThumbPrint -ne $Using:Thumbprint)} | Remove-Item -Force
    }
#endregion

Hopefully going forward you can decide if you want to spend the money for longer expiration times or get public SSL certificates for free using Lets Encrypt.

4.7/5 - (10 votes)

Paul Contreras

Hi, my name is Paul and I am a Sysadmin who enjoys working on various technologies from Microsoft, VMWare, Cisco and many others. Join me as I document my trials and tribulations of the daily grind of System Administration.

2 Comments

  1. How can we use the powershell script if you only share the command script while you hide the custom functions used by the command script?

  2. So I get the error
    mkdir : The network path was not found
    At line:2 char:5
    + mkdir $DownloadPath
    + ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [New-Item], IOException
    + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.NewItemCommand

Leave a Reply

Your email address will not be published.