How to read/write administration.config

IIS7 configuration system understands machine.config, web.config and applicationHost.config but does not handle administration.config natively. This means reading and writing administration.config is little difficult. If you use AhAdmin directly and call GetAdminSection for a section defined in administration.config, it will throw a configuration error for all configuration paths saying that it couldn’t find the section in the configuration file. Easiest way you can work with administration.config is by using Microsoft.Web.Administration (MWA). ServerManager::GetAdministrationConfiguration gives you a Configuration object which represents administration.config. Below is a sample program which uses MWA to print UI module providers registered in administration.config.

class
Program
{
    static void Main(string[] args)
    {
        ServerManager sm = new ServerManager();

        Configuration administrationConfig = sm.GetAdministrationConfiguration();
        ConfigurationSection moduleProvidersSection = administrationConfig.GetSection("moduleProviders");
        ConfigurationElementCollection moduleProvidersCollection = moduleProvidersSection.GetCollection();

        foreach
(ConfigurationElement moduleProviderElement in moduleProvidersCollection)
        {
            Console.WriteLine(moduleProviderElement.GetAttribute("name").Value);
        }
    }
}

MWA achieves this by setting a pathMapper to map MACHINE/WEBROOT configuration path to administration.config instead of root web.config (it uses a different AdminManager for root web.config). You can write a pathMapper yourself and use AppHostAdminLibrary directly to read or write administration.config. Program below uses a simple pathMapper to map MACHINE/WEBROOT to administration.config and then prints UI module count.

using
AppHostAdminLibrary;

class Program
{
    static void Main(string[] args)
    {
        AppHostAdminManager configManager = new AppHostAdminManager();
        configManager.SetMetadata("pathMapper", new MyPathMapper());

        IAppHostElement modulesElement = configManager.GetAdminSection(
            "modules",
            "MACHINE/WEBROOT");
        IAppHostElement wmodulesElement = configManager.GetAdminSection(
            "system.webServer/modules",
            "MACHINE/WEBROOT/APPHOST");

        Console.WriteLine(modulesElement.Collection.Count);
        Console.WriteLine(wmodulesElement.Collection.Count);
    }
}

public
class MyPathMapper : IAppHostPathMapper
{
    public string MapPath(
        string bstrConfigPath,
        string bstrMappedPhysicalPath)
    {
        string physicalPath = bstrMappedPhysicalPath;

        if (bstrConfigPath.Equals("MACHINE/WEBROOT", StringComparison.OrdinalIgnoreCase))
        {
            string windir = Environment.ExpandEnvironmentVariables("%windir%");
            physicalPath = windir + @"\system32\inetsrv\config\administration.config";
        }

        return physicalPath;
    }
}

In windows server 2008 you can also implement IAppHostPathMapper2 and then set “pathMapper2” metadata on IAppHostAdminManager. IAppHostPathMapper2 allows you to return the impersonation token with the physical path mapping which is then used by the configuration system to read the configuration file. Also, native configuration system has an in-built pathMapper which maps MACHINE/WEBROOT to administration.config. Sample program below sets this in-built pathMapper and then creates an IIS manager user.

using
System;
using System.Text;
using System.Security.Cryptography;
using AppHostAdminLibrary;

namespace AdminConfig
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                AppHostWritableAdminManager ahadmin = new AppHostWritableAdminManager();
                ahadmin.SetMetadata("pathMapper", "AdministrationConfig");
                ahadmin.CommitPath = "MACHINE/WEBROOT";

               
IAppHostElement authenticationSection = ahadmin.GetAdminSection(
                    "system.webServer/management/authentication",
                    "MACHINE/WEBROOT");

               
IAppHostElement credentialsElement = authenticationSection.GetElementByName("credentials");
                IAppHostElementCollection credentialsCollection = credentialsElement.Collection;
                IAppHostElement newElement = credentialsCollection.CreateNewElement("add");

               
newElement.Properties["name"].Value = "newuser";

                //
                // Get SHA256 hash of password
                // This is required by UI
                // Plain text passwords won't work for IIS Manager users
                //
                SHA256 sha = SHA256.Create();
                byte[] hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes("iisrocks"));

                byte f1 = 0xf0;
                byte f2 = 0x0f;
                string hexString = "";

                foreach (byte b in hashBytes)
                {
                    int first4 = (b & f1) >> 4;
                    int second4 = (b & f2);

                   
hexString = hexString + ((first4 > 9) ? (char)('A' + (first4 - 10)) : (char)('0' + first4));
                    hexString = hexString + ((second4 > 9) ? ((char)('A' + (second4 - 10))) : (char)('0' + second4));
                }

      
          newElement.Properties["password"].Value = hexString;

               
credentialsCollection.AddElement(newElement, -1);
                ahadmin.CommitChanges();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }
}

You can also use Microsoft.Web.Managerment.Server.ManagementAuthentication.CreateUser("user", "password") to create an IIS Manager user. This will also make sure that user is saved to the right provider which might or might not be administration.config.

-Kanwal

1 Comment

Comments have been disabled for this content.