Implementing SSL with PowerShell for existing SharePoint 2013 farm – Part 2

In the previous post I have described the current SharePoint 2013 environment and the steps to be taken to implement SSL and get it all back working like charm. In this second part of the series I will describe how to deploy and install your certificates with PowerShell. If you have just one or 2 servers I can image the doing it all manually can be quicker then creating an script first and then use it. However, if you have lots of servers (including test, acceptance, etc,,) PowerShell scripts you’ll need.

Configuration File

I wanted to use a generic PowerShell script. All the variables are stored in a configuration file. I came up with something like this:

<configuration>

    <certificates>
        <certificate store="Root" name="AddTrustExternalCARoot" filename="AddTrustExternalCARoot.crt" />
        <certificate store="CA" name="TrustedSecureCertificateAuthority5" filename="TrustedSecureCertificateAuthority5.crt" />
        <certificate store="CA" name="USERTrustRSAAddTrustCA" filename="USERTrustRSAAddTrustCA.crt" />
        <certificate store="My" name="Wildcard Company" filename="wildcard_company_com.pfx" password="VerySecretOfCourse" />
        <certificate store="My" name="Wildcard SPApps" filename="wildcard_spapps_company_com.pfx" password="VerySecretOfCourse" />
    </certificates>

    <servers>
        <server name="NL1601" bindings="TRUE" certificatelocation="d$\Install\Certificates">
            <certificate name="AddTrustExternalCARoot" />
            <certificate name="TrustedSecureCertificateAuthority5" />
            <certificate name="USERTrustRSAAddTrustCA" />
            <certificate name="Wildcard Company" />
            <certificate name="Wildcard SPApps" />
        </server>
        <server name="NL1602" bindings="TRUE" certificatelocation="d$\Install\Certificates">
            <certificate name="AddTrustExternalCARoot" />
            <certificate name="TrustedSecureCertificateAuthority5" />
            <certificate name="USERTrustRSAAddTrustCA" />
            <certificate name="Wildcard Company" />
            <certificate name="Wildcard SPApps" />
        </server>
    </servers>
</configuration>

The Certificate elements describe the physical files you want the install. Although I will use the latter two for my SharePoint sites and Add-ins, the certificate must be valid all the way up in the chain. Therefor I also deploy the root certificate authority.

The Server elements describe the servers where the certificates will be deployed to. The attribute certificateLocation describes the location where the files are copied to. For each server element I configure which certificates I want to deploy and install.

Deployment Script

I will provide the complete script, but for the sake of readability I will describe the nifty bits.

First I am copying the files to all servers:

$config = Get-Content Deploy-Certificates.config
$config.Configuration.Servers.Server | % {

    $server = $_
    $serverName = $_.name
    
    Write-Host
    Write-Host -f Cyan Server: $servername

    # Create destination folder if not exists
    $destination = "\\$($serverName)\" + $server.certificateLocation
    Write-Host Ensuring install folder $destination... -NoNewline
    if(-not(Test-Path -path $destination))
    {
        $f = New-Item $destination -Type Directory -Force 
    }
    Write-Host -f Green " [Done]"
    
    # Copy certificate files to destination folder
    Write-Host Copying certificate files... -NoNewline
    $server.Certificate | % {
    
        $certificateName = $_.Name
        
        $certificate = $config.Configuration.Certificates.Certificate | ? { $_.name -eq $certificateName }
        $certificateFile = $certificate.fileName
        
        $f = Copy-Item -Path "$currentScriptLocation\Certificates\$certificateFile" -Destination $destination
        
    }
    Write-Host -f Green " [Done]"
}

Secondly I open a remote PowerShell session to that server. Within this session I will install the certificates into “local” certificate stores.

# Install each certificate
$session = New-PsSession –ComputerName $serverName

Write-Host -f White Installing certificates...
$server.Certificate | % {

    $certificateName = $_.Name
    Write-Host `t$certificateName -NoNewline
    
    $certificate = $config.Configuration.Certificates.Certificate | ? { $_.name -eq $certificateName }
    $certificateFile = $certificate.fileName
    $certificatePassword = $certificate.password
    $certificateStore = "cert:\LocalMachine\" + $certificate.store

    $certificateLocation = $server.certificateLocation.Replace("$", ":")
    $localCertificateFile = $certificateLocation + "\" + $certificateFile
    
    if( $certificateFile.EndsWith(".crt")) {

        Invoke-Command -Session $session -ScriptBlock {
            param( $localCertificateFile, $certificateStore)
                $crt = Import-Certificate -FilePath $localCertificateFile -CertStoreLocation $certificateStore -Confirm:$false
        } -ArgumentList $localCertificateFile, $certificateStore
    }
    else
    {

        Invoke-Command -Session $session -ScriptBlock {
            param( $localCertificateFile, $certificateStore, $certificatePassword)
        
            $securePwd = ConvertTo-SecureString -String $certificatePassword -Force –AsPlainText
            $pfx = Import-PfxCertificate -FilePath $localCertificateFile -CertStoreLocation $certificateStore -Exportable:$true -Password $securePwd -Confirm:$false
            
        } -ArgumentList $localCertificateFile, $certificateStore, $certificatePassword

    }
    Write-Host -f Green " [Done]"
}

In this script I use 2 interesting cmdlets, Import-Certificate and Import-PfxCertificate. Both are part of the module PKIClient, which is default available for Windows Server 2012 R2 systems.

With the Invoke-Command I use the session object to call the Import-Certificate cmdlets and the ArgumentList to pass any variables to the ScriptBlock.

How do you know what the PowerShell notation is for the correct Certificate Store? Well, I used the following cmdlets:

image

This gives you all certificate stores on the local machine.

Running the complete script

Create a folder to store your script and configuration file. Collect all your certificates and store them in the subfolder Certificates.

image

Start a PowerShell session, go to the folder where the script is and run it.

NOTE: You must be a local administrator on all the servers and Remote PowerShell must be enabled.

image

In next part I will describe how to change the SharePoint Web Applications to use SSL and HTTPS.

[Update: you can download the complete script here]

2 thoughts on “Implementing SSL with PowerShell for existing SharePoint 2013 farm – Part 2

  1. Pingback: Implementing SSL with PowerShell for existing SharePoint 2013 farm – Part 1 | SharePoint: Working on it…

  2. Pingback: Implementing SSL with PowerShell for existing SharePoint 2013 farm – Part 3 | SharePoint: Working on it…

Leave a Reply

Your email address will not be published. Required fields are marked *