Thursday, December 31, 2009

Getting list of applications in a site from IIS metabase

We will start with creating a class for storing the application details.

public class IisWebApplication
{
   private string _Name = "";
   public string Name
   {
      get { return _Name; }
      set { _Name = value; }
   }

   private string _AspNetFrameworkVersion = "";
   public string AspNetFrameworkVersion
   {
      get { return _AspNetFrameworkVersion; }
      set { _AspNetFrameworkVersion = value; }
   }

   private string _Description = "";
   public string Description
   {
      get { return _Description; }
      set { _Description = value; }
   }

   private string _FolderPath;
   public string FolderPath
   {
      get { return _FolderPath; }
      set { _FolderPath = value; }
   }
}

As specified in my earlier post, each web site is assigned a unique integer value. The path for accessing a site will look like IIS://localhost/W3SVC/{site number}. The below method can help in getting the application details associated with a website passed as siteId. You can also specify whether to get details of sub applications.

public List<IisWebApplication> GetWebApplications(int siteId, bool showSubApplications)
{
   _ApplicationPools = GetApplicationPools();

   List<IisWebApplication> webApps = new List<IisWebApplication>();
   string MetabaseRootPath = @"IIS://localhost/W3SVC/" + siteId.ToString() + "/ROOT";
   DirectoryEntry appEntry = null;
   try
   {
      appEntry = new DirectoryEntry(MetabaseRootPath);
      foreach (DirectoryEntry s in appEntry.Children)
      {
         CheckAndAddWebApplication(s, webApps, showSubApplications);
      }
   }
   catch { }
   finally
   {
      if (appEntry != null)
         appEntry.Close();
   }
   return webApps;
}

private void CheckAndAddWebApplication(DirectoryEntry entry, List<IisWebApplication> webApps, bool addSubApplications)
{
   bool reserved = true;
   if (IsWebApplicationEntry(entry))
   {
      reserved = IsReservedWebApplication(entry.Name);
      if (!reserved)
         webApps.Add(GetWebApplication(entry));
   }
   if (entry.Children != null && addSubApplications && !reserved)
   {
      foreach (DirectoryEntry s in entry.Children)
      {
         CheckAndAddWebApplication(s, webApps, addSubApplications);
      }
   }
}

private IisWebApplication GetWebApplication(DirectoryEntry entry)
{
   IisWebApplication webApp = new IisWebApplication();
   webApp.Name = GetApplicationName(entry);
   webApp.AspNetFrameworkVersion = GetAspNetVersion(entry);
   webApp.FolderPath = GetApplicationFolderPath(entry);
   if (_ApplicationPools != null)
   {
      string appPoolName = entry.Properties["AppPoolId"].Value.ToString();
      webApp.ApplicationPool = GetApplicationPoolFromList(appPoolName);
   }
   return webApp;
}

private bool IsWebApplicationEntry(DirectoryEntry entry)
{
   string keyType = entry.Properties["KeyType"].Value.ToString();
   if (keyType == "IIsWebDirectory" || (keyType == "IIsWebVirtualDir" && entry.Properties["Path"].Value != null))
   {
      string[] appNames = GetApplicationName(entry).Split("/".ToCharArray());
      if (appNames[appNames.Length - 1] == entry.Name)
         return true;
   }
   return false;
}

private string GetApplicationName(DirectoryEntry entry)
{
   string appRoot = entry.Properties["AppRoot"].Value.ToString();
   string matchString = "/ROOT/";
   int index = appRoot.ToUpper().IndexOf(matchString);
   if (index > -1)
      return appRoot.Substring(index + matchString.Length);

   return entry.Name;
}

private bool IsReservedWebApplication(string appName)
{
   if (appName.StartsWith("_vti_") || appName == "_private" || appName == "bin" || appName == "Printers"
      || appName == "aspnet_client")
      return true;
   return false;
}

private string GetApplicationFolderPath(DirectoryEntry entry)
{
   string keyType = entry.Properties["KeyType"].Value.ToString();
   if (keyType == "IIsWebDirectory")
   {
      string path = entry.Path;
      string matchString = "/ROOT/";
      int index = path.IndexOf(matchString);
      return "/" + path.Substring(index + matchString.Length);
   }
   else if (keyType == "IIsWebVirtualDir")
   {
      return entry.Properties["Path"].Value.ToString();
   }
   return "";
}

Getting ASP.Net version for this application depends on the version of IIS you are using. In version 7, the runtime version is set for the App Pool. In earlier versions, runtime version is set for individual applications.

If you are using IIS 7, use the following method.
private string GetAspNetVersion(DirectoryEntry entry)
{
   string appPool = s.Properties["AppPoolId"].Value.ToString();
   string metabaseAppPoolPath = "IIS://localhost/W3SVC/AppPools/" + appPool;
   DirectoryEntry appPoolEntry = new DirectoryEntry(metabaseAppPoolPath);
   return appPoolEntry.Properties["ManagedRuntimeVersion"].Value.ToString();
}

The below method can be used for earlier versions.
private string GetAspNetVersion(DirectoryEntry entry)
{
   PropertyValueCollection vals = entry.Properties["ScriptMaps"];
   if (vals == null)
      return "Could not read the frame work version";
   foreach (string val in vals)
   {
      if (val.StartsWith(".aspx"))
      {
         int startIndex = val.ToLower().IndexOf("framework") + 10;
         int endIndex = val.IndexOf("\\", startIndex);
         string version = val.Substring(startIndex, endIndex - startIndex);
         return version;
      }
   }
   return "No version for .aspx files.";
}

1 comment: