Thursday, April 8, 2010

SharePoint 2010 AppPool DropDownList

While playing around trying to figure out how SharePoint 2010 populates that wonderful drop down list of AppPools, as seen in the screeshot just below, I noticed that all the classes it uses are marked internal sealed.


Since I wanted to learn more about how this control worked, I decided to use reflector to poke around. Here is the small amount of info I discovered of the items in the list:


And here is the code that produces that output.

public class Program
    {
        static void Main(string[] args)
        {
            DiscoverAppPools();
        }

        public class AppPoolInfo
        {
            public string Name { get; set; }
            public string IISObjectName { get; set; }
            public IdentityType IdentityType { get; set; }
            public string Username { get; set; }
        }

        //Queries the farm to find the list of AppPools to display in an IisWebServiceApplicationPoolSection control
        public static void DiscoverAppPools()
        {
            List discoveredAppPools = new List();

            Assembly assembly = Assembly.Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
            Type typeSPIisWebServiceSettings = assembly.GetType("Microsoft.SharePoint.Administration.SPIisWebServiceSettings");

            /*
             * There are a few other interesting properties that we aren't pulling, but might be handy to peek at.
             * oSettings.IisSiteName
             * oSettings.HttpPort
             * oSettings.HttpsPort
             * oAppPool.Id
             * oAppPool.Status
             * oAppPool.ProcessAccount.SecurityIdentifier.Value
             */
            object oSettings = SPFarm.Local.GetObject("SharePoint Web Services", SPFarm.Local.Id, typeSPIisWebServiceSettings);
            if (oSettings != null)
            {
                Type typeSPIisWebServiceApplicationPoolCollection = assembly.GetType("Microsoft.SharePoint.Administration.SPIisWebServiceApplicationPoolCollection");
                ConstructorInfo constructor = typeSPIisWebServiceApplicationPoolCollection.GetConstructor(
                    BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeSPIisWebServiceSettings }, null);

                object oAppPools = null;                
                if (constructor != null)
                {
                    oAppPools = constructor.Invoke(new object[] {oSettings});
                    if (oAppPools != null)
                    {
                        Type typeSPIisWebServiceApplicationPool = assembly.GetType("Microsoft.SharePoint.Administration.SPIisWebServiceApplicationPool");

                        IEnumerable appPools = (IEnumerable)oAppPools;
                        if (appPools != null)
                        {
                            IEnumerator enumerator = appPools.GetEnumerator();
                            while (enumerator.MoveNext())
                            {
                                AppPoolInfo api = new AppPoolInfo();

                                object oAppPool = enumerator.Current;
                                PropertyInfo piName = typeSPIisWebServiceApplicationPool.GetProperty("Name");
                                if (piName != null)
                                {
                                    api.Name = (string)piName.GetValue(oAppPool, null);
                                }

                                PropertyInfo piIisObjectName = typeSPIisWebServiceApplicationPool.GetProperty("IisObjectName", BindingFlags.Instance | BindingFlags.NonPublic);
                                if (piIisObjectName != null)
                                {
                                    api.IISObjectName = (string)piIisObjectName.GetValue(oAppPool, null);
                                }

                                //not terribly useful; really only gives a SID. Maybe good if you wanted their credentials as a SecureString
                                //PropertyInfo piProcessAccount = typeSPIisWebServiceApplicationPool.GetProperty("ProcessAccount");
                                //if (piProcessAccount != null)
                                //{
                                //    object o = piProcessAccount.GetValue(oAppPool, null);
                                //}

                                PropertyInfo piCurrentIdentityType = typeSPIisWebServiceApplicationPool.GetProperty("CurrentIdentityType", BindingFlags.Instance | BindingFlags.NonPublic);
                                if (piCurrentIdentityType != null)
                                {
                                    api.IdentityType = (IdentityType)piCurrentIdentityType.GetValue(oAppPool, null);
                                }

                                PropertyInfo piManagedAccount = typeSPIisWebServiceApplicationPool.GetProperty("ManagedAccount", BindingFlags.Instance | BindingFlags.NonPublic);
                                if (piManagedAccount != null)
                                {
                                    object oManagedAccount = piManagedAccount.GetValue(oAppPool, null);
                                    if (oManagedAccount != null)
                                    {
                                        PropertyInfo piUsername = oManagedAccount.GetType().GetProperty("Username");
                                        if (piUsername != null)
                                        {
                                            api.Username = (string)piUsername.GetValue(oManagedAccount, null);
                                        }
                                    }
                                }

                                discoveredAppPools.Add(api);
                            }
                        }
                    }
                }
            }

            Console.WriteLine("SharePoint knows about the following AppPools");
            foreach(AppPoolInfo api in discoveredAppPools)
            {
                Console.WriteLine("\nAppPool: {0}", api.Name);
                Console.WriteLine("  IIS Object Name: {0}", api.IISObjectName);
                Console.WriteLine("  Identity Type: {0}", api.IdentityType);
                Console.WriteLine("  Username: {0}", api.Username );
            }
        }
    }

No comments:

Post a Comment