PowerShell Snap-in: Configuring SSL with the IIS PowerShell Snap-in

  • Published on July 02, 2008 by pharr
  • Updated on March 09, 2009 by pharr

To enable SSL three steps are involved:

  1. Acquiring and installing a certificate
  2. Creating an SSL binding in IIS 
  3. Assigning the certificate to the IP:Port of the IIS binding

and optionally:

  • Enforcing SSL on your web-site

Acquiring and Installing a Certificate

Acquiring certificates is a tricky business. The users of your web-site have to trust the certificate and that's why you have to get it from a trusted Certificate Authority. For testing purposes you can make your own certificate however. For this walkthrough we will use a so-called self-signed certificate. The tool that helps us creating a self-signed certificate is called MAKECERT and is part of the Visual Studio SDK Tools. The following MAKECERT command will create a self-signed certificate and automatically install it in the "my" Windows Certificate Store:

makecert -r -pe -n "CN=MyTestServer" -b 07/01/2008 -e 07/01/2010 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

You can look at the certificates in the certificate store using the certificate provider:

PS IIS:\> makecert -r -pe -n "CN=MyTestServer" -b 01/01/2008 -e 01/01/2010 -eku 1.3.6.1.5.5.7.3.1 -s
s my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
Succeeded


PS IIS:\> dir cert:\localmachine\my


    Directory: Microsoft.PowerShell.Security\Certificate::localmachine\my


Thumbprint                                Subject
----------                                -------
7ABF581E134280162AFFFC81E62011787B3B19B5  CN=MyTestServer

Note: Your certificate thumbprint will be different!

Now lets use the IIS PowerShell Snap-in to create an SSL binding and associate it with the certificate we just created

Creating an SSL Binding

We are adding the SSL binding to the Default Web Site using one of the task-based cmdlets called New-WebBinding:

PS IIS:\> New-WebBinding -Site "Default Web Site" -IP "*" -Port 443 -Protocol https

You can look at the binding collection using the following command: PS IIS:\> Get-WebBinding 'Default Web Site'

protocol                                          bindingInformation
--------                                          ------------------
http                                              *:80:
https                                             *:443:

Assigning the Certificate to the IP:Port of the IIS Binding

Now it gets a bit tricky because SSL settings get stored in the HTTP.SYS configuration store and the naming conventions are a bit different.

  1. In HTTP.SYS you have to use 0.0.0.0 to specify all IP addresses; in IIS you use an asterisk (*).
  2. In IIS you use ":" to separate the binding. Because PowerShell sees a colon as a drive indicator an exclamation mark is used instead:

You can CD into the IIS:\SslBindings directory and query the existing SSL bindings. The directory will be empty on an IIS default install:

PS IIS:\> cd SslBindings
PS IIS:\SslBindings> dir

Now you can use the certificate hash we got in step one and associate it with all IP addresses (0.0.0.0) and the SSL port 443:

PS IIS:\SslBindings> get-item cert:\LocalMachine\MY\7ABF581E134280162AFFFC81E62011787B3B19B5 | new-item 0.0.0.0!443

The previous command generated the following SSL Binding:

IP Address       Port Store            Sites
----------       ---- -----            -----
0.0.0.0          443  My               Default Web Site

SSL is ready to go now and you can browse to your site by entering https://localhost

Summary

It is fairly straightforward process to set up SSL with PowerShell. You need to get a certificate, create an SSL binding in IIS and then use the IP and Port of the IIS binding to create a SSL binding in HTTP.SYS.

 

Comments

Uhm... and what about SSL enforcement? Is it possible to change user certificate parameters (don't require / accept / request). And what about configuring SSL per-application, not per site.

Oct 03 2008 by 13xforever

How does one associate the certificate when using IPv6? The equivalent of "0.0.0.0" would be "::", so my initial guess would be ".. | new-item [::]!443".

Mar 24 2009 by Chaz6

Great stuff, thanks for sharing.

The '-Site' in

New-WebBinding -Site "Default Web Site" -IP "*" -Port 443 -Protocol https

when creating binding kept throwing an error. I removed that switch and it work like a champ!

Thanks again.

Apr 15 2009 by sonnyr

The missing link: Enforcement

In PowerShell:

Add-PSSnapin "WebAdministration";

$SiteName = "Default Web Site";
$SiteBinding = "~DNS Entry Here~";
$HttpsPort = 443;

CD IIS:;
CD SslBindings;

#Create a HTTPS binding for your web site
New-WebBinding -Name "$SiteName" -IP "*" -Port $HttpsPort -Protocol https -HostHeader "$SiteName";

#Get the list of certificates installed on your web server
$Certs = Get-ChildItem cert:\LocalMachine\My

#Assuming you have only one, access the Thumbprint
#If more than one, $Certs becomes an array
$Thumbprint = $Certs.Thumbprint;

#Assign the Thumbprint to the IP Address & HTTPS port pair
Get-Item Cert:\LocalMachine\My\$Thumbprint | New-Item 0.0.0.0!$HttpsPort

#Set the web site configuration property to require (enforce) SSL128
Set-WebConfigurationProperty -PSPath "IIS:\" -Location "$SiteName" -filter /system.webServer/security/access -name sslFlags -value "Ssl,Ssl128"

Sep 10 2009 by The Evil Overlord

Submit a Comment

You must Log In to comment.

Microsoft Communities