I'm writing a PowerShell script to set up several websites on developers' machines in IIS (not IIS Express).
I understand that the current recommendation (as at 2025) is to create IIS websites using the IISAdministration module, rather than the old WebAdministration module, and Microsoft.Web.Administration.ServerManager via the Get-ServerManager cmdlet.
There are several overloads of ServerManager.Sites.Add(). I would prefer to use one of the overloads which doesn't include certificate information, so I can reuse the code to set up multiple sites, some of which do not have HTTPS bindings. I would like to add the certificate information as a separate optional step for those sites which do have HTTPS bindings.
However, I find that if I do add certificate information to a binding after the site is added, when I call ServerManager.CommitChanges() the certificate information disappears.
Is there any way to add a site as a two step process via ServerManager, adding the site first, then the certificate information to the binding if required?
Here is my proof of concept code:
#Requires -RunAsAdministrator
#Requires -Version 5.1
#Requires -Modules @{ ModuleName='IISAdministration'; ModuleVersion='1.1.0.0' }
$physicalPath = 'C:\Working\Test'
$websiteName = 'Test'
# ASSUMPTION: App pool already exists.
$appPoolName = 'Test'
$bindingInfo = @{ Protocol = 'https'; BindingInformation = '*:4000:' }
[byte[]]$certificateHash = 204,219,71,236,31,111,36,12,228,97,184,227,116,172,225,48,123,184,38,197
$certificateInfo = @{
Name = 'IIS Express Development Certificate'
StoreName = 'My'
Hash = $certificateHash
Thumbprint = 'CCDB47EC1F6F240CE461B8E374ACE1307BB826C5'
}
$addCertificateWithSite = $true
$iisServerManager = Get-IISServerManager
if ($addCertificateWithSite)
{
# Works.
$webSite = $iisServerManager.Sites.Add(
$websiteName,
$bindingInfo.BindingInformation,
$physicalPath,
$certificateInfo.Hash,
$certificateInfo.StoreName)
}
else
{
# Doesn't work.
$webSite = $iisServerManager.Sites.Add(
$websiteName,
$bindingInfo.Protocol,
$bindingInfo.BindingInformation,
$physicalPath)
$configuredBinding = $webSite.Bindings[0]
$configuredBinding.CertificateHash = $certificateInfo.Hash
$configuredBinding.CertificateStoreName = $certificateInfo.StoreName
}
$rootWebApp = $website.Applications['/']
$rootWebApp.ApplicationPoolName = $appPoolName
$iisServerManager.CommitChanges()
Write-Host 'End'
If I supply the certificate information in the Sites.Add(...) method the certificate is set up correctly. See the above code when $addCertificateWithSite = $true. However, if I add the certificate information after the site is added, the certificate information disappears when $iisServerManager.CommitChanges() is called. See the above code when $addCertificateWithSite = $false.
When $addCertificateWithSite = $false here is the binding information before CommitChanges() is called:
And here is the binding information after CommitChanges() is called:

