Adding SSL certificate via "netsh.exe" is not saved after computer restart

I am currently creating an eccomerce ASP.Net MVC 3 application that uses IIS Express for my development server.

Since we accept payments through the app, we need to secure an SSL connection for the verification process.

After Scott Hanselman wrote a good article on how to set up self-signed SSL certificates for use with IIS Express, I can access my site via like:

It's all tide until I restart. It seems that every time I restart (for some reason) I need to run the following commands again:

netsh http delete sslcert ipport=
netsh http add sslcert ipport= appid={214124cd-d05b-4309-9af9-9caa44b2b74a} certhash=<thumbprint from Certificate Manager>


I have tried exporting and importing the generated certificate and also dragging and dropping the certificate from my personal store to Trusted Root Certification Authorities. Both to no avail.

Does anyone have any ideas?


source to share

4 answers

This issue is mentioned by several people in the comments at

Last comment:

I think moving the self signed certificate from the Personal directory to the Trusted Root CA is causing the issue where SSL stops working after restarting their computers. (Not sure how this happens, but it happens sequentially). I will finally get around this issue by exporting and re-importing the self-signed certificate to the trusted root directory (instead of just dragging and dropping). Now my self-signed certificate is considered and I don't need REINSTALL / REPAIR IIS Express every time I restart my computer.



Have you imported the certificate to currentuser or LocalMachine store? It looks like if you import the certificate into the CurrentUser store this issue will occur. Take a look at the following thread



Several comments.

First, you can get the IIS Express fingerprint without using MMC using the following command:

powershell -command "& {get-childitem -path cert: \ localmachine \ my | where-object {$ .FriendlyName -match 'IIS Express Development Certificate'} |% {$ .Thumbprint}}"

As explained at you are using fingerprint in the netsh command. You can use the above powershell technique to generate the correct netsh command for your specific IIS Express installation.

Add to the above command and print the correct netsh command for port 443:

powershell -command "& {get-childitem -path cert: \ localmachine \ my | where-object {$ .FriendlyName -match 'IIS Express Development Certificate}} |% {' netsh http add sslcert ipport = 443 appid = {214124cd-d05b-4309-9af9-9caa44b2b74a} certhash = '+ $. Thumbprint}} "

This will display the complete netsh command that you should be using. You can copy / paste it and call it yourself. You can also add ** | cmd.exe ** to the above command to invoke it automatically. Let's do it. Below is a PowerShell command ready to be copied / pasted in the admin command line to set the local 443 port binding to the local IIS Express certificate:

powershell -command "& {get-childitem -path cert: \ localmachine \ my | where-object {$ .FriendlyName -match 'IIS Express Development Certificate}} |% {' netsh http add sslcert ipport = 443 appid = {214124cd-d05b-4309-9af9-9caa44b2b74a} certhash = '+ $. Thumbprint}} "| cmd.exe



Below is a PowerShell script that can delete an existing certificate and then create and bind a new self-signed certificate to IIS 8.0 Express. The PowerShell that you run to run must use "Run as administrator". I am using it to increase the default key size from 1024 to 4096 bits.

# NOTE: This script MUST use Run as Administrator to work correctly.
# This script works with IIS 8.0 Express.
$currentPrincipal=new-object System.Security.Principal.WindowsPrincipal($currentIdentity)
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator

if (($currentPrincipal -eq $null) -or ($currentPrincipal.IsInRole($adminRole) -eq $false))
    Write-Error "This script must be run with Admnistrator privileges."

$iisExpressAppId = "{214124cd-d05b-4309-9af9-9caa44b2b74a}"
$iisExpressCertFriendlyName = "IIS Express Development Certificate"

# Get the current IIS Express certificate and remove it if it exists
$iisExpressCert = Get-ChildItem Cert:\LocalMachine\My | ? { $_.FriendlyName -eq $iisExpressCertFriendlyName }

if ($iisExpressCert -ne $null)
    Remove-Item $iisExpressCert.PSPath

# Create a new self-signed server certificate with a 4096-bit key
& "C:\Program Files (x86)\Windows Kits\8.1\bin\x86\makecert.exe" -r -pe -n "CN=localhost" -m 60 -ss My -sr LocalMachine -sky Exchange -eku -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -a sha512 -len 4096

# Get the newly generated server certificate
$iisExpressCert = Get-ChildItem Cert:\LocalMachine\My | ? { $_.Subject -eq "CN=localhost" -and [DateTime]::Parse($_.GetEffectiveDateString()).Date -eq [DateTime]::Today }

if ($iisExpressCert -ne $null)
    # Change the friendly name of the new certificate.
    $iisExpressCert.FriendlyName = $iisExpressCertFriendlyName

    # Iterate through the IIS Express ports removing the old certificate
    # and adding the new one.
    44300..44399 | foreach {
        & "C:\Windows\System32\netsh.exe" http delete sslcert ipport=$($_)
        & "C:\Windows\System32\netsh.exe" http add sslcert ipport=$($_) certhash=$($iisExpressCert.Thumbprint) appid=$($iisExpressAppId)

<# Remove comment tags only if you intend to trust the self-signed cert.
# Adds the Public Certificate to the Trusted Root Certification Authorities.
$iisExpressPublicCert = Get-ChildItem Cert:\LocalMachine\AuthRoot | ? { $_.FriendlyName -eq $iisExpressCertFriendlyName }

if ($iisExpressPublicCert -ne $null)
    Remove-Item $iisExpressPublicCert.PSPath

$iisExpressPublicCert = New-Object "System.Security.Cryptography.X509Certificates.X509Certificate2" @(,$iisExpressCert.Export("Cert"))
$iisExpressPublicCert.FriendlyName = $iisExpressCertFriendlyName

$trustedCertStore = Get-Item Cert:\LocalMachine\AuthRoot




All Articles