Thursday, April 14, 2011

How can I look up IIS site id in C#?

I am writing an installer class for my web service. In many cases when I use WMI (e.g. when creating virtual directories) I have to know the siteId to provide the correct metabasePath to the site, e.g.:

metabasePath is of the form "IIS://<servername>/<service>/<siteID>/Root[/<vdir>]"
for example "IIS://localhost/W3SVC/1/Root"

How can I look it up programmatically in C#, based on the name of the site (e.g. for "Default Web Site")?

From stackoverflow
  • Maybe not the best way, but here we do it the following way :

    1. loop through all the sites under "IIS://servername/service"
    2. for each of the sites check if the name is "Default Web Site" in your case
    3. if true then you have your site id

    In Visual Basic 6 (sorry, all the code I have at hand just now) this would be it :

    Dim oSite As IADsContainer
    Dim oService As IADsContainer
    Set oService = GetObject("IIS://localhost/W3SVC")
    For Each oSite In oService
        If IsNumeric(oSite.Name) Then
            If oSite.ServerComment = "Default Web Site" Then
                Debug.Print "Your id = " & oSite.Name
            End If
        End If
    Next
    
  • Here is how to get it by name. You can modify as needed.

     public int GetWebSiteId(string serverName, string websiteName)
            {
                int result = -1;
    
                DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/w3svc", serverName));
    
                foreach (DirectoryEntry site in w3svc.Children)
                {
                    if (site.Properties["ServerComment"] != null)
                    {
                        if (site.Properties["ServerComment"].Value != null)
                        {
                            if (string.Compare(site.Properties["ServerComment"].Value.ToString(), websiteName, 
    
                             false) == 0)
                            {
                                result = site.Name;
                                break;
                            }
                        }
                    }
                }
    
                return result;
            }
    
    MattH : On my system I had to update the above with the following to get it to compile "result = Convert.ToInt32(site.Name);"
  • You can search for a site by inspecting the ServerComment property belonging to children of the metabase path IIS://Localhost/W3SVC that have a SchemaClassName of IIsWebServer.

    The following code demonstrates two approaches:

    string siteToFind = "Default Web Site";
    
    // The Linq way
    using (DirectoryEntry w3svc1 = new DirectoryEntry("IIS://Localhost/W3SVC"))
    {
        IEnumerable<DirectoryEntry> children = 
              w3svc1.Children.Cast<DirectoryEntry>();
    
        var sites = 
            (from de in children
             where
              de.SchemaClassName == "IIsWebServer" &&
              de.Properties["ServerComment"].Value.ToString() == siteToFind
             select de).ToList();
        if(sites.Count() > 0)
        {
            // Found matches...assuming ServerComment is unique:
            Console.WriteLine(sites[0].Name);
        }
    }
    
    // The old way
    using (DirectoryEntry w3svc2 = new DirectoryEntry("IIS://Localhost/W3SVC"))
    {
    
        foreach (DirectoryEntry de in w3svc2.Children)
        {
         if (de.SchemaClassName == "IIsWebServer" && 
             de.Properties["ServerComment"].Value.ToString() == siteToFind)
         {
          // Found match
          Console.WriteLine(de.Name);
         }
        }
    }
    

    This assumes that the ServerComment property has been used (IIS MMC forces its used) and is unique.

    Kev

  • private static string FindWebSiteByName(string serverName, string webSiteName)
    {
     DirectoryEntry w3svc = new DirectoryEntry("IIS://" + serverName + "/W3SVC");
     foreach (DirectoryEntry site in w3svc.Children)
     {
      if (site.SchemaClassName == "IIsWebServer"
       && site.Properties["ServerComment"] != null
       && site.Properties["ServerComment"].Value != null
       && string.Equals(webSiteName, site.Properties["ServerComment"].Value.ToString(), StringComparison.OrdinalIgnoreCase))
      {
       return site.Path;
      }
     }
    
     return null;
    }
    
  • public static ManagementObject GetWebServerSettingsByServerComment(string serverComment)
            {
                ManagementObject returnValue = null;
    
                ManagementScope iisScope = new ManagementScope(@"\\localhost\root\MicrosoftIISv2", new ConnectionOptions());
                iisScope.Connect();
                if (iisScope.IsConnected)
                {
                    ObjectQuery settingQuery = new ObjectQuery(String.Format(
                        "Select * from IIsWebServerSetting where ServerComment = '{0}'", serverComment));
    
                    ManagementObjectSearcher searcher = new ManagementObjectSearcher(iisScope, settingQuery);
                    ManagementObjectCollection results = searcher.Get();
    
                    if (results.Count > 0)
                    {
                        foreach (ManagementObject manObj in results)
                        {
                            returnValue = manObj;
    
                            if (returnValue != null)
                            {
                                break;
                            }
                        }
                    }
                }
    
                return returnValue;
            }
    
    Grzenio : Does it work with IIS version <7? Unfortunately I am stuck with Win2k3
    Helephant : This method works for IIS6. I used it to find app pools.
  • Do you guys know how IIS 6.0 actually generates this ID number for each site? My server admin person is worried that if I set up a site using a random ID number, that IIS might in the future try to use that same number to generate a different site.

    Thanks

    Grzenio : You have to ask a new question. This is not a standard discussion site, noone is going to answer this one.

0 comments:

Post a Comment