I've got a script 'ResetEnvironment' that developers can use to reset their developer environment when something goes screwy, or to create the environment when they are first starting on the project. The script has fully automated new environments, except for adding the HTTPS binding to the website in IIS. This always had to be done manually.
Another developer has joined the project and I thought this was a good time to really sort this problem out, so we don't have to manually do this step whenever we reset our environment.
My overall ResetEnvironment.bat script is a batch file that makes calls out to powershell scripts (cmdlet's) when neccessary. My solution for adding https binding involves a few steps
- Delete any existing instances of the certificate I'm about to add. My next step creates a self signed cert. If called multiple times it'll create multiple certs of the same name, not really busting anything but creating unneccessary clutter.
- Create a self-signed certificate.
- Create a https binding on my site.
Precondition: The first thing I do is create the http binding for my site and assign it the correct AppPool. I'll assume this is already done, so I'll leave it out so I can focus on the https binding. I also add a hosts file entry for my site, which is used in the powershell script used by step 3.
%siteName% is a batch file variable I've set to be the name of my site.
1. Deleting any existing certs is done by calling certutil
certutil -delstore MY %siteName%
2. Create a self signed certificate and put it in the MY certificate store. Don't worry too much about the parameters (unless you're really interested). It basically creates a cert that is valid for ages.
makecert -r -pe -n "CN=%siteName%" -b 01/01/2000 -e 01/01/2036 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
3. Use a powershell cmdlet to create the HTTPS binding and assign the certificate to it.
powershell.exe -ExecutionPolicy Bypass -InputFormat none -Command "AddSSLCert.ps1" -Name "%siteName%" -IPAddress "127.0.0.1"
The part I struggled with in the past was assigning the certificate to the https binding I created with appcmd. I've instead put that step in a powershell cmdlet defined in AddSSLCert.ps1
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,Position=0,HelpMessage="The name of the WebSite, AppPool and URL for the Binding")]
[string]$Name,
[Parameter(Mandatory=$True,Position=0,HelpMessage="The IPAddress of the WebSite, AppPool and URL for the Binding")]
[string]$IPAddress)
$ErrorActionPreference = "Stop";
Import-Module WebAdministration
$sslCertificate = gci 'CERT:\LocalMachine\My' | Where-Object { $_.Subject -ilike "*$Name*" };
if (-not $sslCertificate) {
Throw "Cannot find SSL certificate for $Name, cannot configure HTTPS... Installed Certificates are:";
gci CERT:\LocalMachine\My | ft;
}
dir 'IIS:\SslBindings' | Where-Object { $_.IPAddress -eq $ipAddress -and $_.Port -eq 443 } | % { $sslBinding = $_ };
Write-Host "Configuring Website: $Name"
if ($sslBinding) {
Write-Host "Deleting SslBinding " + $sslBinding;
Remove-Item -Path "IIS:\SslBindings\$IPAddress!443";
$sslBinding = $null;
}
New-WebBinding -Name "$Name" -IPAddress $ipAddress -HostHeader "$Name" -Port 443 -Protocol https;
New-Item -Path "IIS:\SslBindings\$IPAddress!443" -Value $sslCertificate;
In the above cmdlet I'm getting the self-signed certificate I created in step 2, creating the https binding, and then assigning the ssl cert to that binding.
That's it! I've got an idempotent script that configures HTTPS entirely automatically.