Modification History:

07/01/04 - added support for vroots & appPools

Sample Described at: http://blogs.msdn.com/ramesh_r/archive/2004/03/24/95109.aspx

//////////////////// sample xml

<?xml version="1.0" encoding="utf-8" ?>
<webSettings>
 <serverSettings>
  <appPools>
   <appPool name="My Test App Pool">
    <propertyList>
     <property name="IdleTimeOut" value="20"/>  
     <property name="AppPoolQueueLength" value="2000"/>
     <property name="MaxProcesses" value="1"/>
     <property name="PingingEnabled" value="True"/>
     <property name="PingInterval" value="30"/> 
     <property name="StartupTimeLimit" value="90"/>
     <property name="ShutdownTimeLimit" value="90"/>
    </propertyList>
   </appPool>
  </appPools>
 </serverSettings>
     <webSites>
             <webSite ServerId="1234" ServerComment="My Test WebSite" PathOfDefaultVroot="c:\inetpub\wwwroot\Test" >
                    <siteSettings>
                          <propertyList>
                                 <property name="AllowKeepAlive" value="True"/>
                                 <property name="ConnectionTimeout" value="90"/>
                          </propertyList>
                         <serverBinding Hostname="" IP="" Port="80"/>
                   </siteSettings>
                   <rootSettings>
      <propertyList>
       <property name="AccessRead" value="True"/>
       <property name="AccessScript" value="True"/>
       <property name="AspAllowSessionState" value="False"/>
       <property name="AspScriptTimeOut" value="300"/>
       <property name="AspBufferingOn" value="True"/>
       <property name="EnableDefaultDoc" value="True"/>
       <property name="DefaultDoc" value="Default.aspx"/>
       <property name="AuthPassport" value="True"/>
       <property name="AuthAnonymous" value="True"/>
       <property name="AnonymousPasswordSync" value="True"/> 
      </propertyList>
                   </rootSettings>
                   <virtualDirs>
      <virtualDir type="folder" name="vdirA" location="C:\inetpub\wwwroot\Test\vroot1"/>
      <virtualDir type="redirect" name="vdirRedriect" location="http://encarta.msn.com"/>
                   </virtualDirs>
            </webSite>
     </webSites>
</webSettings>

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

//  application /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 class App
 {
  [STAThread]
  static int Main (string[] args)
  {
   if (args.Length != 2)
   {
    StdOut ("Usage: Xml2IIs <targetServer> <configPath>");
    StdOut ("  e.g: Xml2IIs localhost mywebsites.xml");
    return 1;
   }

   string target = args[0];
   string configPath = args[1];

   XmlConfig config = new XmlConfig (configPath);
   if (config.ApplySettings (target))
    return 0;
   else
    return 1;

  }

  public static void LogException (Exception ex)
  {
   Console.Error.WriteLine ("EXCEPTION!> " + ex.Source);
   Console.Error.WriteLine ("EXCEPTION!> " + ex.Message);
   Console.Error.WriteLine ("EXCEPTION!> " + ex.StackTrace);
  }

  public static void StdOut (string msg)
  {
   Console.WriteLine (">{0}", msg);
  }


 }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// XMLConfig Class ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 public class XmlConfig
 {
  public XmlConfig (string configPath)
  {
   Load (configPath);
  }

  public bool ApplySettings (string target)
  {
   if (_doc == null) return false;

   // connect to WMI on target server
   _wmi = new WmiIIS ();
   _wmi.Connect (target);

   if (!_wmi.IsConnected ()) return false;

   // process server settings
   XmlNode serverSettingsNode = _doc.SelectSingleNode (@"webSettings/serverSettings");
   if (serverSettingsNode != null)
   {
    XmlNode appPoolsNode = serverSettingsNode.SelectSingleNode ("appPools");
    foreach (XmlNode appPoolNode in appPoolsNode)
    {
     string name = appPoolNode.Attributes["name"].Value;
     ManagementObject oAppPool = _wmi.CreateAppPool (name);
     if (oAppPool != null)
     {
      // handle properties

      XmlNode propertyNodes = appPoolNode.SelectSingleNode ("propertyList");
      ApplyProperties (oAppPool, propertyNodes);
     }
    }
   }

 

   // process website nodes
   XmlNodeList siteNodes = _doc.SelectNodes (@"webSettings/webSites/webSite");
   foreach (XmlNode siteNode in siteNodes)
   {
    HandleWebSite (siteNode);
   }

   return true;
  }

  private bool HandleWebSite (XmlNode siteNode)
  {
   try
   {
    XmlNode settingsNode = siteNode.SelectSingleNode ("siteSettings");

    XmlNodeList bindingNodes = settingsNode.SelectNodes ("serverBinding");
    ManagementBaseObject[] serverBindings = new ManagementBaseObject[bindingNodes.Count];

    int i = 0;
    foreach (XmlNode bindingNode in bindingNodes)
    {

     serverBindings[i++] =
     _wmi.CreateServerBinding (bindingNode.Attributes["Hostname"].Value,
      bindingNode.Attributes["IP"].Value,
      bindingNode.Attributes["Port"].Value);
    }

    string wmiPath = _wmi.CreateWebSite (siteNode.Attributes["ServerId"].Value,
     siteNode.Attributes["ServerComment"].Value,
     siteNode.Attributes["PathOfDefaultVroot"].Value,
     serverBindings);

    ManagementObject oSite = _wmi.GetInstance (wmiPath.Replace ("IIsWebServer", "IIsWebServerSetting"));

    App.StdOut ("Connected To..." + oSite.Path);


    // handle properties

    XmlNode propertyNodes = settingsNode.SelectSingleNode ("propertyList");
    ApplyProperties (oSite, propertyNodes);

    // settings on the root vdir

    XmlNode rootSettingsNode = siteNode.SelectSingleNode ("rootSettings");
    if (rootSettingsNode != null)
    {
     propertyNodes = rootSettingsNode.SelectSingleNode ("propertyList");

     string objectPath = string.Format ("IIsWebVirtualDirSetting='{0}'", oSite["Name"] + "/ROOT");
     ManagementObject oRoot = _wmi.GetInstance (objectPath);
     ApplyProperties (oRoot, propertyNodes);
    }


    // handle vroots

    XmlNode virtualDirsNode = siteNode.SelectSingleNode ("virtualDirs");

    foreach (XmlNode virtualDirNode in virtualDirsNode.ChildNodes)
    {
     string type = virtualDirNode.Attributes["type"].Value;
     string name = virtualDirNode.Attributes["name"].Value;
     string location = virtualDirNode.Attributes["location"].Value;

     string vdirPath = oSite["Name"] + "/ROOT/" + name;

     ManagementObject oVDir = _wmi.CreateVirtualDir (type, vdirPath, location);
    }

    oSite.Put ();

    return true;

   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return false;
   }

  }

  private bool ApplyProperties (ManagementObject o, XmlNode propertyNodes)
  {
   try
   {

    if (propertyNodes != null && propertyNodes.ChildNodes.Count > 0)
    {

     Hashtable tableProperty = new Hashtable ();
     foreach (XmlNode propertyNode in propertyNodes.ChildNodes)
     {
      string name, value;
      name = propertyNode.Attributes["name"].Value;
      value = propertyNode.Attributes["value"].Value;

      tableProperty.Add (name, value);
     }

     return _wmi.ApplyPropertyList (o, tableProperty);
    }

   }
   catch (Exception ex)
   {
    App.LogException (ex);
   }

   return false;
  }


  private bool Load (string configPath)
  {
   try
   {
    _doc = new XmlDocument ();
    _doc.Load (configPath);

    return true;

   }
   catch (Exception ex)
   {
    App.LogException (ex);
    _doc = null;
    return false;
   }

  }


  private XmlDocument _doc = null;
  private WmiIIS _wmi = null;
 }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// WmiIIS Class /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 public class WmiIIS
 {
  public WmiIIS ()
  {
  }

  public bool IsConnected()
  {
   if (_target == null || _connection == null || _scope == null) return false;
   return _scope.IsConnected;
  }

  public bool Connect (string target)
  {
   if (target == null) return false;


   try
   {
    _target = target;
    _connection = new ConnectionOptions ();
    _scope = new ManagementScope (@"\\" + target + @"\root\MicrosoftIISV2", _connection);
    _scope.Connect ();

    App.StdOut ("Connected To... " + target);
   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return false;
   }

   return IsConnected ();
  }

  public ManagementObject CreateServerBinding (string HostName, string IP, string Port)
  {
   try
   {
    ManagementClass classBinding = new ManagementClass (_scope, new ManagementPath ("ServerBinding"), null);
    ManagementObject serverBinding = classBinding.CreateInstance ();
    serverBinding.Properties["Hostname"].Value = HostName;
    serverBinding.Properties["IP"].Value = IP;
    serverBinding.Properties["Port"].Value = Port;
    serverBinding.Put ();
    return serverBinding;
   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return null;
   }
  }

  public string CreateWebSite (string serverID, string serverComment, string defaultVrootPath, ManagementBaseObject[] serverBinding)
  {
   if (serverID == null || serverID.Length == 0) return null;
   if (defaultVrootPath == null || defaultVrootPath.Length == 0) return null;
   if (serverComment == null || serverComment.Length == 0) return null;
   if (serverBinding == null) return null;

   try
   {

    ManagementObject oW3SVC = new ManagementObject (_scope, new ManagementPath (@"IIsWebService='W3SVC'"), null);
    App.StdOut("Connected To..." + oW3SVC.Path);

    if (IsWebSiteExists (serverID))
    {
    App.StdOut ("Site Already Exists..." + serverID);
    DeleteSite (serverID);
    }

    ManagementBaseObject inputParameters = oW3SVC.GetMethodParameters ("CreateNewSite");

    inputParameters["ServerComment"] = serverComment;
    inputParameters["ServerBindings"] = serverBinding;
    inputParameters["PathOfRootVirtualDir"] = defaultVrootPath;
    inputParameters["ServerId"] = serverID;

    ManagementBaseObject outParameter = null;
    outParameter = oW3SVC.InvokeMethod ("CreateNewSite", inputParameters, null);
    return (string)outParameter.Properties["ReturnValue"].Value;

   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return null;
   }
  }

  public ManagementObject CreateVirtualDir (string type, string wmiPath, string location)
  {
   try
   {
    ManagementClass classVDir = new ManagementClass (_scope, new ManagementPath ("IIsWebVirtualDirSetting"), null);
    ManagementObject objectVDir = classVDir.CreateInstance ();

    type = type.ToLower ();

    if (type == "folder")
    {
     objectVDir.Properties["Name"].Value = wmiPath;
     objectVDir.Properties["Path"].Value = location;
     objectVDir.Put ();
    }
    else if (type == "redirect")
    {
     objectVDir.Properties["Name"].Value = wmiPath;
     objectVDir.Properties["Path"].Value = "REDIRECT";
     objectVDir.Properties["HttpRedirect"].Value = location;
     objectVDir.Put ();
    }
    else
    {
     objectVDir = null;
    }

    if (objectVDir != null)
    {
     App.StdOut ("CREATED VDIR " + objectVDir["Name"]);
    }

    return objectVDir;

   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return null;
   }
  }

  public ManagementObject CreateAppPool (string name)
  {
   try
   {
    ManagementClass classAppPool = new ManagementClass (_scope, new ManagementPath ("IIsApplicationPoolSetting"), null);
    ManagementObject objectAppPool = classAppPool.CreateInstance ();

    objectAppPool.Properties["Name"].Value = "W3SVC/AppPools/" + name;
    objectAppPool.Put ();

    App.StdOut ("CREATED APP POOL: " + objectAppPool["Name"]);

    return objectAppPool;


   }
   catch (Exception ex)
   {
    App.LogException(ex);
    return null;
   }

  }

 

  public bool ApplyPropertyList(ManagementObject managementObject, Hashtable tableProperty)
  {
   try
   {
    App.StdOut ("Setting Properties On..." + managementObject.Path);

    foreach (string key in tableProperty.Keys)
    {
    Console.WriteLine ("Setting...{0}={1}", key, tableProperty[key]);
    managementObject.Properties[key].Value = tableProperty[key];
    }

    managementObject.Put ();
    return true;
   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return false;
   }
  }

  public ManagementObject GetInstance (string wmiPath)
  {
   try
   {
    return new ManagementObject(_scope, new ManagementPath(wmiPath),null);
   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return null;
   }
  }

  public bool IsWebSiteExists (string serverID)
  {
   try
   {
    string siteName = "W3SVC/" + serverID;
    ManagementObjectSearcher searcher = new ManagementObjectSearcher (_scope, new ObjectQuery ("SELECT * FROM IIsWebServer"), null);

    ManagementObjectCollection webSites = searcher.Get ();
    foreach (ManagementObject webSite in webSites)
    {
    if ((string)webSite.Properties["Name"].Value == siteName)
    return true;
    }

    return false;
   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return false;
   }
  }

  public bool DeleteSite (string serverID)
  {
   try
   {
    string serverName = "W3SVC/" + serverID;
    ManagementObject webSite = new ManagementObject (_scope, new ManagementPath (@"IIsWebServer='" + serverName + "'"), null);

    App.StdOut ("Stopping..." + webSite.Path);
    webSite.InvokeMethod ("Stop", null);

    App.StdOut ("Deleting..." + webSite.Path);
    webSite.Delete();

    webSite = null;

    return true;
   }
   catch (Exception ex)
   {
    App.LogException (ex);
    return false;
   }
  }


 string _target = null;
 ManagementScope _scope = null;
 ConnectionOptions _connection = null;

 }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////