MSMVPS.COM
The Ultimate Destination for Blogs by Current and Former Microsoft Most Valuable Professionals.

HowTo: Agrupando grupos :-)

Blogs

El blog de Lluis Franco

Syndication

Una entrada rápida, no como la de ayer. Aunque el tema está bastante relacionado ya que ambos tratan de Active Directory e identidades.

GroupPolicy

Hoy vamos a ver una forma sencilla de obtener todos los grupos a los que pertenece un usuario, y agruparlos por su nombre de dominio. Y todo esto mediante una sola sentencia LINQ to objects. A ver quién es el guapo o guapa que me dice que LINQ to objects no es una maravilla!

El resultado que vamos a obtener es el siguiente (algunos nombres se han omitido por razones obvias :-P):

Groups under:
  - Group name: Todos
  - Group name: LOCAL
Groups under: BUILTIN
  - Group name: Usuarios
  - Group name: Administradores
Groups under: PRIMARY_DOMAIN_NAME
  - Group name: xxx1
  - Group name: xxx2
  - Group name: xxx3
  - Group name: xxx4
  - Group name: xxxN
Groups under: NT AUTHORITY
  - Group name: INTERACTIVE
  - Group name: Usuarios autentificados

Y el código resultante es un método extensor para la clase WindowsIdentity, con dos funciones auxiliares en forma de métodos extensores de la clase NTAccount:

using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
 
namespace Alpha.Code
{
    public static class SecurityExtensions
    {
        public static IOrderedEnumerable<IGrouping <string, NTAccount>> 
            GetGroupsUnderDomains(this WindowsIdentity identity)
        {
            var groups =
                        from grIdentity in identity.Groups
                        where grIdentity.IsValidTargetType(typeof(NTAccount))
                        select grIdentity.Translate(typeof(NTAccount)) as NTAccount into ntAccounts
                        let domainName = ntAccounts.GetDomainName()
                        let groupName = ntAccounts.GetAccountName()
                        orderby domainName
                        group ntAccounts by domainName into domainGroups
                        orderby domainGroups.Key
                        select domainGroups;
            return groups;
        }
 
        public static string GetDomainName(this NTAccount account)
        {
            string[] split = account.Value.Split('\\');
            return split.Length == 1 ? string.Empty : split[0];
        }
 
        public static string GetAccountName(this NTAccount account)
        {
            string[] split = account.Value.Split('\\');
            return split[split.Length - 1];
        }
    }
}

Para probarlo y ver el resultado:

var groups = WindowsIdentity.GetCurrent().GetGroupsUnderDomains();
foreach (var dg in groups)
{
    Console.WriteLine(string.Format("Groups under: {0}", dg.Key));
    foreach (var g in dg)
    {
        Console.WriteLine(string.Format("  - Group name: {0}", g.GetAccountName()));
    }
}

Un saludo desde las frías tierras de Andorra :-)

Noviembre 2009

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

Posted Thu, Nov 26 2009 11:53 by lfranco
Filed under: , , , ,

Add a Comment

(optional)  
(optional)
(required)  
Remember Me?