This is intended to be a model for an application that queries an Active Directory. It can return IEnumerables of the following:Users, given context.Groups, given context or users.Users, given group.User Group Membership, given context or users.User Direct Reports, given context or users.Computers, given context.Computers, given group.This should allow any program calling these methods to access everything in the active directory by all possible queries. If you can think of an additional query that you would find useful, please include it in your answer.There are also some included extension methods to make the code more organized in my opinion. Again, if this were used in another program, the underlying directory entry for principals and all the properties thereof would be more convenient to access by using user.GetProperty(propertyName) instead ofvar userAsDirectoryEntry = user.GetUnderlyingObject() as DirectoryEntry;userAsDirectoryEntry.Properties[proeprtyName];where user is a UserPrincipal in both cases.ActiveDirectorySearcher.csusing System.Collections.Generic;using System.DirectoryServices;using System.DirectoryServices.AccountManagement;using System.Linq;namespace ActiveDirectoryTool{    internal struct DirectReports    {        internal IEnumerable<UserPrincipal> Reports { get; set; }        internal UserPrincipal User { get; set; }    }    internal struct UserGroups    {        internal IEnumerable<GroupPrincipal> Groups { get; set; }        internal UserPrincipal User { get; set; }    }    internal static class UserPrincipalExtensions    {        internal static DirectoryEntry GetAsDirectoryEntry(            this UserPrincipal user)        {            return user.GetUnderlyingObject() as DirectoryEntry;        }        internal static IEnumerable<string> GetDirectReportDistinguishedNames(            this UserPrincipal user)        {            return ((IEnumerable<string>)user.GetProperty(directReports));        }        internal static IEnumerable<UserPrincipal> GetDirectReports(            this UserPrincipal user)        {            var directReports = new List<UserPrincipal>();            foreach (var directReportDistinguishedName in                user.GetDirectReportDistinguishedNames())            {                directReports.Add(UserPrincipal.FindByIdentity(                    user.Context,                    IdentityType.DistinguishedName,                    directReportDistinguishedName));            }            return directReports;        }        internal static object GetProperty(            this UserPrincipal user, string propertyName)        {            return user.GetAsDirectoryEntry().Properties[propertyName];        }    }    internal class ActiveDirectorySearcher    {        internal static IEnumerable<ComputerPrincipal> GetComputersFromContext(            PrincipalContext context)        {            var computers = new List<ComputerPrincipal>();            using (var searcher = new PrincipalSearcher(                    new ComputerPrincipal(context)))            {                computers =                    searcher.FindAll().OfType<ComputerPrincipal>().ToList();            }            return computers;        }        internal static IEnumerable<ComputerPrincipal> GetComputersFromGroup(            GroupPrincipal group)        {            return group.GetMembers().OfType<ComputerPrincipal>();        }        internal static IEnumerable<DirectReports> GetDirectReportsFromUsers(                    IEnumerable<UserPrincipal> users)        {            var directReports = new List<DirectReports>();            foreach (var user in users)            {                directReports.Add(new DirectReports                {                    User = user,                    Reports = user.GetDirectReports()                });            }            return directReports;        }        internal static IEnumerable<DirectReports> GetDiretReportsFromContext(            PrincipalContext context)        {            return GetDirectReportsFromUsers(GetUsersFromContext(context));        }        internal static IEnumerable<GroupPrincipal> GetGroupsFromContext(            PrincipalContext context)        {            return GetGroupsFromUsers(GetUsersFromContext(context));        }        internal static IEnumerable<GroupPrincipal> GetGroupsFromUsers(            IEnumerable<UserPrincipal> users)        {            var groups = new HashSet<GroupPrincipal>();            foreach (var user in users)            {                groups.UnionWith(                    user.GetGroups().OfType<GroupPrincipal>().ToList());            }            return groups;        }        internal static IEnumerable<UserGroups> GetUserGroupsFromContext(            PrincipalContext context)        {            return GetUserGroupsFromUsers(GetUsersFromContext(context));        }        internal static IEnumerable<UserGroups> GetUserGroupsFromUsers(            IEnumerable<UserPrincipal> users)        {            var userGroups = new List<UserGroups>();            foreach (var user in users)            {                userGroups.Add(new UserGroups                {                    User = user,                    Groups = user.GetGroups().OfType<GroupPrincipal>().ToList()                });            }            return userGroups;        }        internal static IEnumerable<UserPrincipal> GetUsersFromContext(            PrincipalContext context)        {            var users = new List<UserPrincipal>();            using (var searcher = new PrincipalSearcher(new UserPrincipal(                context)))            {                users = searcher.FindAll().OfType<UserPrincipal>().ToList();            }            return users;        }        internal static IEnumerable<UserPrincipal> GetUsersFromGroup(            GroupPrincipal group)        {            return group.GetMembers().OfType<UserPrincipal>().ToList();        }    }}
Active Directory Searcher class/API
c#;api;active directory