Installing SSL Certificates on Windows Server IIS: Step-by-Step Guide

IIS has the most friction of any common web server when it comes to SSL certificate management. Not because it’s technically harder, but because the workflow is different from Linux-based servers and the GUI-heavy approach obscures what’s actually happening. I’ve set up SSL on IIS for clients a number of times, and each time I end up explaining the same things.

This guide covers both the GUI approach and PowerShell automation, because manually clicking through Certificate Manager on 10 servers gets old fast.

Understanding How IIS Uses Certificates

IIS relies on the Windows Certificate Store, not loose files on disk like Nginx or Apache. When you “install” a certificate on IIS, you’re actually importing it into the Windows certificate store, and then binding it to an IIS website.

This two-step process (import → bind) trips people up. Placing a .crt file in a folder does nothing until you import it into the certificate store and then bind it.

What You Need: The PFX File

IIS requires a PFX (PKCS#12) file for import – check SSL certificate formats explained. This bundles your certificate, private key, and optionally the CA chain into a single password-protected file.

If your CA sent you separate .crt and .key files, you need to convert them first. On a Linux machine or using OpenSSL on Windows:

openssl pkcs12 -export \
  -in certificate.crt \
  -inkey private.key \
  -certfile ca-bundle.crt \
  -out certificate.pfx \
  -name "example.com"

You’ll set a password during this process. Keep it — you need it for the IIS import.

Importing the Certificate: GUI Method

  1. Open IIS Manager (search for “inetmgr” in Run or Start)
  2. Click on the server node in the left panel (not a site — the server itself)
  3. Double-click Server Certificates in the center panel
  4. In the right panel, click Import…
  5. Browse to your .pfx file, enter the password, choose the certificate store (usually “Personal”), and check “Allow this certificate to be exported” if you might need to move it later
  6. Click OK

The certificate should now appear in the Server Certificates list.

Binding the Certificate to a Site

Importing the certificate doesn’t automatically apply it to any website. You need to create an HTTPS binding:

  1. In IIS Manager, expand Sites in the left panel
  2. Click on your site
  3. In the right panel, click Bindings…
  4. Click Add
  5. Set Type to https, IP Address to All Unassigned (or a specific IP), Port to 443
  6. In the SSL certificate dropdown, select the certificate you just imported
  7. Check Require Server Name Indication if hosting multiple SSL sites on the same IP
  8. Click OK

If you’re hosting multiple sites on the same server, you need SNI enabled for each. Without SNI, all sites on that IP will respond with the same certificate — usually the first one alphabetically in the bindings list.

PowerShell: The Better Way

Doing the above through GUI is fine for one server. For multiple servers, PowerShell is far faster.

Import the PFX:

$password = ConvertTo-SecureString -String "YourPFXPassword" -Force -AsPlainText
Import-PfxCertificate -FilePath "C:\certs\certificate.pfx" `
  -CertStoreLocation "Cert:\LocalMachine\My" `******

Get the thumbprint of the certificate you just imported:

Get-ChildItem -Path "Cert:\LocalMachine\My" | 
  Where-Object { $_.Subject -like "*example.com*" } | 
  Select-Object Subject, Thumbprint, NotAfter

Bind the certificate to an IIS site using the thumbprint:

# Import the WebAdministration module
Import-Module WebAdministration

# Get the thumbprint
$thumbprint = (Get-ChildItem -Path "Cert:\LocalMachine\My" | 
  Where-Object { $_.Subject -like "*example.com*" }).Thumbprint

# Remove existing HTTPS binding if one exists
Get-WebBinding -Name "Default Web Site" -Protocol "https" | Remove-WebBinding

# Create new binding
New-WebBinding -Name "Default Web Site" `
  -Protocol "https" `
  -Port 443 `
  -IPAddress "*" `
  -HostHeader "example.com" `
  -SslFlags 1

# Assign the certificate
$binding = Get-WebBinding -Name "Default Web Site" -Protocol "https"
$binding.AddSslCertificate($thumbprint, "My")

The SslFlags 1 enables SNI. For a single-site server without SNI, use SslFlags 0.

Renewing a Certificate on IIS

When a certificate expires, the process is:

  1. Import the new PFX (same process as above — it gets a new thumbprint)
  2. Update the HTTPS binding to use the new thumbprint

IIS doesn’t auto-update bindings when you import a new cert. The old binding will keep pointing to the old (expired) cert until you update it manually. I’ve seen sites continue showing the expired cert for days after a renewal because someone imported the new cert but forgot to update the binding.

PowerShell makes the renewal update straightforward:

# Get the new certificate's thumbprint
$newThumbprint = (Get-ChildItem -Path "Cert:\LocalMachine\My" | 
  Where-Object { $_.Subject -like "*example.com*" } |
  Sort-Object NotAfter -Descending |
  Select-Object -First 1).Thumbprint

# Update the binding
$binding = Get-WebBinding -Name "Your Site Name" -Protocol "https" -Port 443
$binding.AddSslCertificate($newThumbprint, "My")

Certificate Store Locations

Windows has multiple certificate stores. For IIS, you want LocalMachine\My (also called “Personal” in the GUI). Other stores:

  • LocalMachine\Root — Trusted Root CAs
  • LocalMachine\CA — Intermediate Certification Authorities
  • CurrentUser\My — Personal certs for the current user (IIS runs as a service, so it can’t use CurrentUser)

Importing to the wrong store is a common mistake. If IIS can’t see a certificate you just imported, check which store it landed in:

# List certs in the Personal store
Get-ChildItem -Path "Cert:\LocalMachine\My" | Select-Object Subject, Thumbprint, NotAfter

# List certs in the wrong store (CurrentUser)
Get-ChildItem -Path "Cert:\CurrentUser\My" | Select-Object Subject, Thumbprint, NotAfter

Enabling Strong TLS Settings on IIS

By default, IIS supports older TLS versions that you should disable. This requires registry changes (or the Nartac IIS Crypto tool):

# Disable TLS 1.0
$tls10 = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server"
New-Item -Path $tls10 -Force
Set-ItemProperty -Path $tls10 -Name "Enabled" -Value 0
Set-ItemProperty -Path $tls10 -Name "DisabledByDefault" -Value 1

# Disable TLS 1.1
$tls11 = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server"
New-Item -Path $tls11 -Force
Set-ItemProperty -Path $tls11 -Name "Enabled" -Value 0
Set-ItemProperty -Path $tls11 -Name "DisabledByDefault" -Value 1

These changes require a server restart to take effect. They affect all services on the server, not just IIS — so make sure nothing else on the server still needs TLS 1.0/1.1 before disabling them.

Alternatively, IIS Crypto by Nartac is a free GUI tool that applies these settings with a few clicks and includes preset templates for “Best Practices” cipher configurations. It’s what I use when I need to configure this quickly on a Windows server.

Common IIS SSL Issues

“Could not find the certificate” error during binding — You imported the cert to the wrong store. Check LocalMachine\My.

Site shows wrong certificate — Another site on the same IP is responding first and SNI isn’t enabled. Enable SNI on all HTTPS bindings.

Certificate imported but not visible in IIS binding dropdown — The private key wasn’t imported. This happens when you try to import just a .crt file without the private key. You need the PFX which contains both.

Certificate chain not trusted — The CA intermediate certificates weren’t included in the PFX. Regenerate the PFX with the CA chain included, or manually import the intermediate certs into LocalMachine\CA.

IIS is more procedural than Linux web servers but it’s manageable once you understand the certificate store model. The PowerShell approach scales well — I’ve wrapped the import and binding steps into scripts that handle certificate renewals across multiple servers without needing to RDP into each one.

Scroll to Top