2012-04-20 14 views
7

encontré How can I get a list of users from active directory?Buscar un ID de inicio de sesión de usuario por el primer nombre y apellido

Es útil cuando sólo tengo unos pocos usuarios, pero tengo tantos usuarios en AD, así que cuando tengo mi consulta

if ((String)(entry.Properties["sn"].Value) == "lname" 
    && (String)(entry.Properties["givenName"].Value) == "fname") 
{ 
    return entry.Properties["samAccountName"].Value.ToString(); 
} 

tardó demasiado en terminar.

¿Qué puedo hacer para buscar un ID de inicio de sesión de usuario en particular por nombre y apellido?

Respuesta

7

Ya que estás en .NET 4, debe verificar el espacio de nombres System.DirectoryServices.AccountManagement (S.DS.AM). Leer todos los detalles aquí:

Básicamente, se puede definir un contexto de dominio y encontrar fácilmente los usuarios y/o grupos en el año:

// set up domain context 
PrincipalContext ctx = new PrincipalContext(ContextType.Domain); 

// find a user - by e.g. his "samAccountName", or the Windows user name or something 
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName"); 

if(user != null) 
{ 
    // do something here....  
    string samAccountName = user.SamAccountName; 
} 

Si no puede encontrar un usuario especificado por un nombre de usuario, también puede usar la nueva funcionalidad de búsqueda:

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the first name (GivenName) and a last name (Surname) 
UserPrincipal qbeUser = new UserPrincipal(ctx); 
qbeUser.GivenName = firstName; 
qbeUser.Surname = lastName; 

// create your principal searcher passing in the QBE principal  
PrincipalSearcher srch = new PrincipalSearcher(qbeUser); 

// find all matches 
foreach(var found in srch.FindAll()) 
{ 
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....   
} 

¡El nuevo S.DS.AM hace que sea muy fácil jugar con usuarios y grupos en AD! Y encontrar un solo usuario también debería ser relativamente rápido.

+0

gran ayuda, me gustaría poder aceptar la totalidad de anwsers de sus individuos – user1225072

+0

@marc_s esto era exactamente lo que estaba buscando, perfecto, gracias. .. sin embargo, descubrí por las malas que si no se necesita ningún campo que solicite al usuario para buscar, omita la propiedad correspondiente en 'UserPrincipal'. Originalmente estaba presionando 'string.empty' y luego incluso' null' y estaba obteniendo ** ** resultados devueltos. Sin embargo, tan pronto como agregué una instrucción 'if' e ignoré ese ítem en' UserPrincipal', finalmente obtuve resultados (_ie: omitido ** GivenName ** cuando ** FirstName ** no estaba poblado, en lugar de establecer por defecto_). – famousKaneis

0

Debe establecer la propiedad QueryFilter en searcher, y luego llamar al searcher.FindOne() en lugar de searcher.FindAll(). El filtro de consulta puede establecerse en un objeto UserPrincipal donde establece los campos en los que desea buscar.

Microsoft tiene un buen ejemplo de esto en la página Query By Example aunque su ejemplo espera encontrar varios objetos que coincidan con los criterios dados.

Una adaptación especial literal de la cuestión vinculada a su requerimiento sería

using (var context = new PrincipalContext(ContextType.Domain, "mydomain.com")) 
{ 
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context) { GivenName = "fname", Surname = "lname" })) 
    { 
      foreach (var result in searcher.FindAll()) 
      { 
       DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry; 
       return de.Properties["samAccountName"].Value.ToString(); 
      } 
    } 
} 
0

Si entry es parte de una colección IEnumerable, usted podría hacer algo como:

var entries = {do your population of the collection here} 

var entry = entries.Where(e=>e.Properties["sn"].Value.ToString() == "lname" 
    && e=>.Properties["givenName"].Value.ToString() == "fname") 
    .FirstOrDefault(); 
2

Debe utilizar el servidor AD para realizar el filtrado. Haga esto suministrando un filtro de sintaxis LDAP. Además, especificar sólo las propiedades que necesita utilizar el argumento propertiesToLoad de FindAll:

public static SearchResultCollection FindByName(
     string domain, string firstName, string lastName, string[] properties) { 
     var rootEntry = new DirectoryEntry("LDAP://" + domain); 
     var filter = string.Format("(&(sn={0})(givenName={1}))", lastName, firstName); 
     var searcher = new DirectorySearcher(rootEntry, filter, properties); 
     return searcher.FindAll(); 
    } 

    // Using the method: 
    var result = FindByName("mydomain", "Robert", "Smith", new[] { "samAccountName" })[0]; 
    string uName = (string)result.Properties["samAccountName"][0]; 
Cuestiones relacionadas