Archive

Archive for the ‘PowerShell’ Category

PowerShell script to install SharePoint Root certificate to Trusted Root store

June 18, 2013 3 comments

Now this post is not really about why and how certificates are used by SharePoint. But in order to understand why we are doing what we are going to do shortly, let me start with a brief 2-minute (hopefully) primer on what this is about.

The public key infrastructure allows messages between users, applications and servers that host the applications to happen in a secure manner using digital certificates. The same happens within SharePoint when a message between entities needs to be secured. Now in order for the sender and receiver of messages secured through certificates to work, a trust needs to be established between the parties. The way this works is that both parties trust a third party which is the issuer of the certificate using which the message is signed. Bear in mind that this is a very high level overview of how this works and there are several variations that we shall not get into here. Having said the above, now in order for the receiver of a message to trust the certificate that is presented with it, it will need to be verified. Not only that certificate but its issuer’s certificate and that certificate’s issuer and so forth until we can trace back to a trusted root certificate. This is referred to as certificate chaining.

Within SharePoint, one instance where this happens is when the Security Token Service issues a token and signs it with a certificate. This certificate will need to be verified as mentioned above through building a chain back to a trusted root certificate. Also, a Certificate Revocation List (CRL) needs to be verified to ensure the certificate has not been revoked. This last is yet another topic requiring much detailed explanation that I shall try to address in a future post. But the idea here is that each certificate in the chain needs to be verified and one needs to lead to a trusted root CA store. If this doesn’t happen, certificate validation errors will occur and cause delays in response time to the users. To avoid this, we need to ensure that the SharePoint Root Authority certificate is installed to the Trusted Root Certification Authorities certificate store on each server in the SharePoint farm. The link above provides steps to do this but involves several manual steps. What I have included below, is a¬†PowerShell script that does it all end to end.

The following are prerequisites to running the script.

  • To be run locally on each machine.
  • To be run as a user with Shell_Admin_Access role on the farm databases [If this is not available run Add-SPShellAdmin before proceeding].
  • To be run as a user with local administrator privileges on the server.

Another thing worth verifying before executing the script is the execution policy on the server. You can determine this by running the Get-ExecutionPolicy cmdlet. This typically shouldn’t be a problem unless you are running the script from a remote share. If you do have a problem though, you can work around it by using the Set-ExecutionPolicy cmdlet.

function CopySharePointRootCertToLocalTrustedCertStore {

    # Add the SharePoint PowerShell snap-in
    if (-not (Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)) {
	    Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
    }

    # Get the SharePoint root certificate
    $rootCert = (Get-SPCertificateAuthority).RootCertificate

    # Store current location
    $location = Get-Location

    # Go to trusted root certificate store on local machine
    cd Cert:\LocalMachine\Root

    # Check if the certificate already exists
    # If it does, report and end
    if ((dir | ? { $_.Thumbprint -eq $rootCert.Thumbprint })) {
        Write-Host -f Green "SharePoint Root Authority already exists in local machine trusted root certificate store."
        cd $location
        return
    }

    # Get the certificate store for "Trusted Root Certification Authorities" (Cert:\LocalMachine\Root)
    $certStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store Root, LocalMachine

    # Open the store with maximum allowed privileges
    $certStore.Open("MaxAllowed")

    # Add the certificate to the store
    $certStore.Add($rootCert)

    # Close the store
    $certStore.Close()

    # Get the certificate if it exists
    if ((dir | ? { $_.Thumbprint -eq $rootCert.Thumbprint })) {
	    Write-Host -f Green "Certificate was successfully added to the Trusted Root store."
    }
    else {
	    Write-Host -f Red "The certificate could not be added to the Trusted Root store."
    }

    # Set location back to where it was
    cd $location
}

CopySharePointRootCertToLocalTrustedCertStore

You can save the script as a .ps1 file and run on each of the servers where the SharePoint root certificate needs to be copied. The way to verify that this has actually worked is to pull up a management console and add the Certificates snap-in as described in the Microsoft Support KB Article referenced above. If however, your objective is to just export the certificate from SharePoint, you may want to use the script provided below. Just make sure you set the $certPath to where you would actually like to export the certificate and by what name.

# Set the certificate file path
$certPath = "C:\SharePointRootAuthority.cer"

# Add the SharePoint PowerShell snap-in
if (-not (Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)) {
	Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
}

# Get the SharePoint root certificate
$rootCert = (Get-SPCertificateAuthority).RootCertificate

# Export the certificate to disk as a certificate file
$rootCert.Export("Cert") | Set-Content $certPath -Encoding byte

Once you have exported the certificate, you can manually add it to the certificate store by using the Management Console or by using the second half of the first script presented above. The only difference is that you will need to construct an X509 certificate object from the certificate file as shown in the script snippet below.

# Set the certificate file path
$certPath = "C:\SharePointRootAuthority.cer"

# Get the certificate store for "Trusted Root Certification Authorities" (Cert:\LocalMachine\Root)
$certStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store Root, LocalMachine

# Get the certificate from the location where it was placed by the export process
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 $certPath

# Open the store with maximum allowed privileges
$certStore.Open("MaxAllowed")

# Add the certificate to the store
$certStore.Add($cert)

# Close the store
$certStore.Close()

That’s it for now. Hopefully, I will find some time to write up more about troubleshooting certificates in SharePoint soon. In the meanwhile, happy scripting!

%d bloggers like this: