This is a quick script I put together to help out in a situation I often come across when configuring multiple IIS applications in environments where resources are constrained and you are hosting multiple applications on the same server. #### Background The correct way to handle this is with Server Name Identification, a technology that Microsoft introduced back in IIS 8 in 2012. SNI is an extension to TLS that allows for binding a domain name to a certificate. In effect, this allows for multiple different sites with different SSL certificates to be colocated on the same server, with determination of which certificate to use based on the URL that is accessed. You can read more about SNI here. Because some of how SNI is implemented is “left as an exercise to the reader” (the browser, in this case), the browser your users are using must support SNI for it to work properly. Wikipedia has a page that addresses current browser support for SNI. However, it’s not really a concern since it was initially released so long ago.

Assumptions

For this script to work, you should have the different certificates for each of your sites, with the subject field of the certificate containing the URL that users will access each site with. These should be imported into the Personal certificate store.

For simplicity’s sake, I am also assuming that you have an application “app1” and “app2” but this could be easily extended to any arbitrary number of applications.

The Script

Import-Module WebAdministration -Force
#bind one web application's certificate with port 443 for requests over the "app1" URLs
#retrieve the certificate for the first application's URL
$app1Certificate = Get-ChildItem Cert:\LocalMachine\My | Where {$_.Subject -match "app1"} | select -First 1
#create new IIS web bindings to redirect all traffic for your first application, with both a non-FQDN and FQDN URL
New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https -HostHeader "app1" -SslFlags 1
New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https -HostHeader "app1.ryandzink.com" -SslFlags 1
New-Item -Path "IIS:\SslBindings\0.0.0.0!443!app1" -Value $app1Certificate -SSLFlags 1 -Force | Out-Null
New-Item -Path "IIS:\SslBindings\0.0.0.0!443!app1.ryandzink.com" -Value $app1Certificate -SSLFlags 1 -Force | Out-Null

You can repeat these steps for as many different applications you want to host on the same port. However, you will also need to decide how to handle traffic that doesn’t come in with any of your specified URLs, and how to handle traffic from browsers that don’t implement SNI (they will both be routed to a default certificate or they will present certificate errors). For example, if you are hosting your applications on a server called SERV1 and have certificates for app1 and app2 but someone does browse to SERV1, their traffic will not match any of the existing bindings and so will need an additional binding to route traffic. powershell #bind a default certificate with port 443 for requests over all other URLs or if the user's browser doesn't support SNI New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https -SslFlags 0 Additionally, if you only add the SNI port bindings, IIS will alert you with this:

If you see that, you haven’t run the second script block.

You can download an example script for two applications at the link below.

BindMultipleIISCerts.ps1

Results

After executing this script, you should see a port 443 https binding for each of your applications:

And when you click Edit to explore their properties, you will see that they are bound to the correct certificate and using SNI:

At this point, users should not receive any certificate errors when visiting your applications, even if they visit an unexpected URL or if they have an ancient browser that doesn’t support SNI.