HowTo: Obtener TODOS los usuarios de un grupo del Directorio Activo

Siguiendo con el tema de las últimas entradas, vamos a ver cómo obtener TODOS los usuarios que pertenecen a un grupo del directorio activo. Y cuando digo TODOS los usuarios, me refiero a TODOS (por algo lo he puesto en mayúsculas :-D). Es decir, dentro de un grupo podemos tener otros grupos, que a su vez contengan otros grupos y así succesivamente… y nuestro objetivo es obtener todos los usuarios de forma recursiva.

ADGroups

Para obtener los datos de estos usuarios vamos a crear una clase, para ir almacenando las propiedades que deseamos obtener de cada usuario. Y una función que obtenga los usuarios de un grupo, y se llame a sí misma de forma recursiva en caso que este grupo contenga otros grupos.

El código de la clase:

public class ADUser
{
    public byte[] Sid { get; set; }
    public string Name { get; set; }
    public string DistinguishedName { get; set; }
    public string SAMAccountName { get; set; }
    
    public int RoleType { get; set; }
 
    public ADUser(byte[] sid, string name, 
        string distinguishedName, string sAMAccountName)
    {
        Sid = sid;
        Name = name;
        DistinguishedName = distinguishedName;
        SAMAccountName = sAMAccountName;
    }
 
    public string sIDtoString()
    {
        SecurityIdentifier sid = new SecurityIdentifier(Sid, 0);
        return sid.ToString();
    }
}

Y el método que devuelve todos los usuarios de un grupo de forma recursiva:

namespace Alpha.Code
{
    public class SecurityContextEx
    {
        public static string getDomainName()
        {
            return IPGlobalProperties.GetIPGlobalProperties().DomainName;
        }
 
        public static string getLDAPDomainName(string domainName)
        {
            StringBuilder sb = new StringBuilder();
            string[] dcItems = domainName.Split(".".ToCharArray());
            sb.Append("LDAP://");
            foreach (string item in dcItems)
            {
                sb.AppendFormat("DC={0},", item);
            }
            return sb.ToString().Substring(0, sb.ToString().Length - 1);
        }
 
        public static List<ADUser> GetUsersInGroup(string group)
        {
            List<ADUser> users = new List<ADUser>();
            string ldapDomainName = SecurityContext.getLDAPDomainName(SecurityContext.getDomainName());
            string domainName = ldapDomainName.Replace("LDAP://", string.Empty);
            List<string> groupMemebers = new List<string>();
 
            DirectoryEntry de = new DirectoryEntry(ldapDomainName);
            DirectorySearcher ds = new DirectorySearcher(de, "(objectClass=person)");
 
            ds.Filter = "(&(objectClass=group)(cn=" + group + "))";
            foreach (SearchResult result in ds.FindAll())
            {
                var dir = result.GetDirectoryEntry();
                var list = dir.Invoke("Members");
                IEnumerable entries = (IEnumerable)list;
                foreach (var entry in entries)
                {
                    DirectoryEntry member = new DirectoryEntry(entry);
                    if (member.SchemaClassName == "group")
                    {
                        List<ADUser> usersInGroup =
                            GetUsersInGroup(member.Properties["name"][0].ToString());
                        foreach (ADUser aduser in usersInGroup)
                        {
                            if (!users.ToDictionary(u => u.Name).ContainsKey(aduser.Name))
                            {
                                users.Add(aduser);
                            }
                        }
                    }
                    else
                    {
                        ADUser aduser = new ADUser(
                            (byte[])member.Properties["objectSid"][0],
                            member.Properties["name"][0].ToString(),
                            member.Properties["distinguishedName"][0].ToString(),
                            member.Properties["sAMAccountName"][0].ToString());
                        users.Add(aduser);
                    }
                }
            }
            return users;
        }
    }
}

Aparte de la función GetUsersInGroup, también existen un par de métodos de apoyo para averiguar el nombre de nuestro dominio, que creo recordar que he publicado con anterioridad, pero por si acaso os los he publicado también.

Si deseamos obtener los usuarios de un grupo en particular, basta con usarlo de este modo:

List<ADUser> users = SecurityContextEx.GetUsersInGroup("My users");

Nota: En ocasiones, puede resultar una buena práctica para la administración de la seguridad de nuestras aplicaciones, crear un grupo en el directorio activo con el mismo nombre de la aplicación. Y de este modo conceder acceso a todos los miembros de dicho grupo a nuestra aplicación. En este caso todavía resultaría más sencillo mostrar todos los usuarios a los que hemos concedido acceso:

List<ADUser> users = SecurityContextEx.GetUsersInGroup(Application.ProductName);

Espero que os haya gustado,

Un saludo desde las frías tierras de Andorra 🙂

Y después de la nevada de ayer, esta vez más frías que nunca…

Noviembre 2009

** crossposting desde el blog de Lluís Franco en geeks.ms **

5 thoughts on “HowTo: Obtener TODOS los usuarios de un grupo del Directorio Activo

  1. Hola:
    Quisiera que me ayudes con algo muy simple, yo programo en Visual basic.net, como sería la sintaxis de este procedimineto.
    Mucahs gracias por tu ayuda

  2. Hola: Te molesto co una cosa, como sería un procedimiento que me devuelva solamente los usuarios de UN grupo del active directory ( procedimiento no recursivo)

  3. Hola, buen dia, me ha quedado claro el codigo, solo que tengo una duda, como obtengo los dominios desde el Active Directory? porque la clase IPGlobalProperties obtiene el dominio del la maquina local, es interesante obtener los dominios que tiene registrado el AD, he estado buscando y no logro encontrar algo en concreto. se que tienen algo de tiempo este post pero espero encontrar alguna forma. TKSS
    Saludos!

  4. Me Contesto Solo, para aquellos que andan buscando algo como lo que comente, en lugar de utilizar LDAP, utilizen GC, con ello estaran haciendo las busquedas de usuarios en el catalogo global del Active Directory, jejeje NICE!!! Saludos desde Monterrey NL, MEX

Leave a Reply

Your email address will not be published. Required fields are marked *