Adding an HTTPS binding to an IIS Website using PowerShell

#IIS #PowerShell

The PowerShell IISAdministration module allows you to write scripts to automate the configuration and management of IIS. I wanted to use it to automate the setup of local development environments and found a good article written by Paul Stovell at Octopus Deploy that describes how the module works and provides plenty of good examples - if you're only just starting out with the module, as I was, it is well worth a read.

Using these examples I was able to achieve most of the tasks I had set out to accomplish with my scripts, but I wanted to add an HTTPS binding to my Website and that is not covered in the article. After a quick search around I didn't come across a succinct guide to achieving my task so I am documenting my solution here.

Before we begin I want to point out two things:

  • I'm making an assumption at this point: you already have an SSL certificate on the machine where you're running this script that IIS can "see"

    • By "see" I mean that if you try to add a binding through IIS Manager, it is listed in the "SSL certificate" dropdown

  • I don't have a lot of experience with PowerShell so there may very well be improvements to be made on the code samples provided, but they have worked well for me!

There are three parts to this solution:

  • Get the SSL certificate thumbprint

  • Convert the thumbprint from hexadecimal to a byte array

  • Add the HTTPS binding

Get the SSL certificate thumbprint

To be able to add an HTTPS binding I needed to associate it with an SSL certificate, and to do that via the IISAdministration module I needed the thumbprint of the certificate. This can be achieved in PowerShell using the below function:

function Get-SslCert([String] $name, [String] $location, [String]$storeName) {
    $thumbprint = (Get-ChildItem "cert:\$location" | where-object { $_.Subject -like "*$name*" } | Select-Object -First 1).Thumbprint
    
    # Return the thumbprint along with the arguments provided for context and later usage
    return new-object psobject -property @{
        Name = $name
        Location = $location
        StoreName = $storeName
        Thumbprint = $thumbprint
    }
}

# This can be called like so if your cert's common name is "dev.example.com" and is located in your "CurrentUser" store (under Local Computer\Personal\Certificates)
$sslCert = Get-SslCert "dev.example.com" "CurrentUser\My" "My"

Convert the thumbprint from hexadecimal to a byte array

The SSL certificate thumbprint must be provided as a byte array when creating the binding using the IISAdministration module, but the thumbprint returned using the function above is in hexadecimal format. I can convert it to a byte array using the following function:

function HexToBytes($hex) {
    $bytes = for($i = 0; $i -lt $hex.Length; $i += 2) {
        [convert]::ToByte($hex.SubString($i, 2), 16)
    }

    return $bytes
}

Add the HTTPS binding

Now I have a way to get the SSL certificate thumbprint in the format that I need it I can add the binding. The following snippet assumes that you are adding the binding after creating a new Website, but you can add a binding to an existing website:

# In this example, we are creating a Website called "example-dev" with a host name of "dev.example.com" that is located under "C:\Sites\example.com"
$name = "example-dev"
$hostname = "dev.example.com"
$path = "C:\Sites\example.com"

# Get the SSL certificate
$sslCert = Get-SslCert "dev.example.com" "CurrentUser\My" "My"

# Get an IISServerManager instance
$manager = Get-IISServerManager

# Create the site with http binding
$site = $manager.Sites.Add($name, "http", "*:80:$hostname", $path)

# Convert the SSL certificate thumbprint to a byte array
$thumbprintBytes = HexToBytes $sslCert.Thumbprint

# Add https binding - this is "noisy" by default so piping to `Out-Null` suppresses the output
$site.Bindings.Add("*:443:$hostname", $thumbprintBytes, $sslCert.StoreName, 1) | Out-Null

# Commit your changes    
$manager.CommitChanges()

Conclusion

The PowerShell IISAdministration module is a good option for scripting and automating the creation of Websites in IIS, and this article shows how it can be used to add HTTPS bindings to new or existing sites.