Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core and Microsoft.Web.Administration

Tags:

c#

.net

iis

ssl

I am trying to write a service that can add bindings to IIS on a remote srver. I am using Microsoft.Web.Administration. My code to add the bindings looks like this:

    public static bool AddSiteBinding(string siteName, string ipAddress, string tcpPort, string hostHeader, string protocol)
    {
        try
        {
            if (string.IsNullOrEmpty(siteName))
            {
                throw new ArgumentNullException("siteName", "AddSiteBinding: siteName is null or empty.");
            }
            //get the server manager instance

            using (ServerManager mgr = ServerManager.OpenRemote(@"\\Qasql01\c$\Windows\System32\inetsrv\config\applicationHost.config"))
            //using (ServerManager mgr = new ServerManager())
            {
                SiteCollection sites = mgr.Sites;
                Site site = mgr.Sites[siteName];
                if (site != null)
                {
                    string bind = ipAddress + ":" + tcpPort + ":" + hostHeader;
                    //check the binding exists or not
                    foreach (Binding b in site.Bindings)
                    {
                        if (b.Protocol == protocol && b.BindingInformation == bind)
                        {
                            throw new Exception("A binding with the same ip, port and host header already exists.");
                        }
                    }
                    Binding newBinding = site.Bindings.CreateElement();
                    newBinding.Protocol = protocol;
                    newBinding.BindingInformation = bind;
                    site.Bindings.Add(newBinding);
                    mgr.CommitChanges();
                    return true;
                }
                else
                    throw new Exception("Site: " + siteName + " does not exist.");
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message, ex);
        }
    }

The problem is that this code (which works fine locally) blows up with an Object reference not set to an instance of an object. error when it's run against the remote server. The remote server in this case is IIS 8.5 on Windows Server 2012. I have tried every solution I can find without any luck at all. I am running this code from VS 2017 which is running as an administrator. Here's what I've tried:

  1. Verified that the IIS management tools are installed on the server
  2. Verified that DCOM is configured and added a specific endpoint in ahaadmin
  3. Turned the firewall on the server off.
  4. Turned off UAC
  5. Verified that I have the right version of Microsoft.Web.Administration DLL
  6. I have tried entering the IP address, the remote path to the config on the server, and the server name.

I cannot test my solution on my local machine because the versions of IIS are different. Ultimately I will be writing code to add an SSL certificate to the "Central Certificate Store" which is an IIS feature not available in Windows 10. I really need "OpenRemote" to work, but it seems like it doesn't. There are no examples from Microsoft for the ServerManager.OpenRemote() method. The examples that I have found simply don't work (most reference IIS7). I'm beginning to think the OpenRemote method was never tested in anything above IIS7. Is anyone out there successfully using ServerManager.OpenRemote() against IIS 8.5?

Update: Here is a pic of what I see in VS in debug: VS Debug

like image 823
user2033791 Avatar asked Mar 07 '23 12:03

user2033791


2 Answers

OK I just figured this out. First, I am convinced that OpenRemote DOES not work. The article I read showed examples of OpenRemote passing in the config file--which is not right. After digging around a bit in MS code I see that there is a constructor that accepts the applicationHost.config path, but not a version of OpenRemote that accepts a config path. It's possible that this may have worked in IIS 7 and an earlier version of MWA but certainly not this version. Of course, passing in Server or IP doesn't work either. I changed the line that instantiates the ServerManager to:

using (ServerManager mgr = new ServerManager(@"\\qasql01\IISSharedConfig\applicationHost.config"))

and now it works. This seems to be the only way to configure a remote server. At least this way allows you to use plain ole file security and bypass all the DCOM mystical security requirements.

like image 67
user2033791 Avatar answered Mar 20 '23 02:03

user2033791


As far as I understand, ServerManager.OpenRemote() is meant to take the server name, not the path to applicationHost.config. Maybe that was the issue?

It stopped working for me when I upgraded the Microsoft.Web.Administration NuGet package. Works fine when I downgrade back to version 7.0.0.0.

like image 36
marchica Avatar answered Mar 20 '23 00:03

marchica