Microsoft.Web.Administration is very useful providing read and write access to the IIS configuration in a simple way.
However, I stumbled across a peculiar issue when trying to add a SSL binding to a website located on another machine. Here’s my code (*asterisk denotes code I’ve hidden on purpose):
using (ServerManager mgr = ServerManager.OpenRemote(serverName))
{
// Code to create the website*
// Adding bindings
// this webSite variable is of a custom type I've created to simplify things
for (int i = 0; i < webSite.Bindings.Count; i++)
{
var binding = webSite.Bindings[i];
string bindingInformation = string.Format("{0}:{1}:{2}", binding.IpAddress, binding.TcpPort, binding.HostName);
// iisSite is of type Microsoft.Web.Administration.Site
iisSite.Bindings.Add(bindingInformation, binding.CertificateHash, binding.CertificateStore);
}
mgr.CommitChanges();
webSite.Id = iisSite.Id;
}
I kept getting this exception:
NotSupportedException: The specified operation is not supported when a server name is specified.
Upon investigating the BindingCollection class, I’ve found the culprit:
Setting BindingInformation also loads the Endpoint. Curiously, this wouldn’t be a problem, however both CertificateHash and CertificateStore also have some additional logic to set their values:
When its underlying variable is null OR the EndPoint is null, it just sets the value. Otherwise, it sets the value and adds/modifies the associated binding transaction. Further investigating this method, I’ve noticed it doesn’t work when the ServerManager is open remotely:
Check inside the EnsureLocal method:
So instead of adding the Binding through the BindingCollection.Add method, I’ve changed my code to this:
using (ServerManager mgr = ServerManager.OpenRemote(serverName))
{
// Code to create the website*
// Adding bindings
// this webSite variable is of a custom type I've created to simplify things
for (int i = 0; i < webSite.Bindings.Count; i++)
{
var binding = webSite.Bindings[i];
// Binding class = Microsoft.Web.Administration.Binding
Binding iisBinding = iisSite.Bindings.CreateElement();
iisBinding.Protocol = protocol;
if (binding.Type == Business.IIS.Binding.BindingType.Https)
{
try
{
iisBinding.CertificateHash = binding.CertificateHash;
iisBinding.CertificateStoreName = binding.CertificateStoreName;
}
catch (Exception)
{
// Error treatment*
}
}
iisBinding.BindingInformation = string.Format("{0}:{1}:{2}", binding.IpAddress, binding.TcpPort, binding.HostName);
// iisSite is of type Microsoft.Web.Administration.Site
iisSite.Bindings.Add(iisBinding);
}
mgr.CommitChanges();
webSite.Id = iisSite.Id;
}
By creating the Binding manually and setting the BindingInformation at last (rather than at the beginning), the problem was gone!
Must confess, though. I have no clue why that method in particular had to “ensure it’s the local server”.



