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

13,032

Solution 1

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 = int.Parse(site.Name);
            break;
        }
      }
    }
  }

  return result;
}

Solution 2

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.

Solution 3

Maybe not the best way, but here is a 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

Example :

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

Solution 4

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.Name;
        }
    }

    return null;
}
Share:
13,032
Grzenio
Author by

Grzenio

Software Engineer at Google

Updated on June 09, 2022

Comments

  • Grzenio
    Grzenio almost 2 years

    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")?

  • MattH
    MattH over 14 years
    On my system I had to update the above with the following to get it to compile "result = Convert.ToInt32(site.Name);"
  • CodeMonkeyKing
    CodeMonkeyKing over 11 years
    The string returned can be parsed as an int if that is necessary. My guess is that in most cases you don't really need it returned as an 'int' as you will use it to make a URI.