2011-03-02 28 views
71

¿Cómo puedo obtener una lista de usuarios del directorio activo? ¿Hay alguna forma de extraer nombre de usuario, nombre, apellido? Vi una publicación similar donde se usaba esto:¿Cómo puedo obtener una lista de usuarios del directorio activo?

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"); 

Nunca he hecho nada con el directorio activo, así que estoy completamente perdido. ¡Cualquier ayuda sería muy apreciada!

+3

Leer el excelente artículo de MSDN [directores gerente de seguridad para directorio en el .NET Framework 3.5] (http://msdn.microsoft.com/en-us/magazine/cc135979.aspx) para una gran introducción a la utilización de AD con .NET 3.5 –

+0

Parece que el artículo de @marc_s se ha archivado, aquí hay un [enlace actualizado] (http://blogs.msdn.com/b/msdnmagazine/archive/2008/01/16/7120454.aspx) –

+0

@marc_s Me encantaría leer señor, pero el enlace está muerto. Intenté esto https://blogs.msdn.microsoft.com/msdnmagazine/2008/01/16/managing-directory-security-principals-in-the-net-framework-3-5/ pero incluso los enlaces en ese artículo conduce a una página genética para la revista microsoft –

Respuesta

169

Si usted es nuevo en Active Directory, le sugiero que debe entender cómo los datos de Active Directory almacena en primer lugar.

Active Directory es en realidad un servidor LDAP. Los objetos almacenados en el servidor LDAP se almacenan jerárquicamente. Es muy similar a almacenar sus archivos en su sistema de archivos. Es por eso que recibió el nombre Directorio servidor y Active Directory

Los recipientes y objetos en Active Directory puede ser especificado por un distinguished name. El nombre completo es así CN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=com. Al igual que una base de datos relacional tradicional, puede ejecutar consultas en un servidor LDAP. Se llama consulta LDAP.

Hay una serie de formas de ejecutar una consulta LDAP en .NET. Puede usar DirectorySearcher desde System.DirectoryServices o SearchRequest desde System.DirectoryServices.Protocol.

Para su pregunta, ya que está pidiendo que encuentre el objeto principal de usuario específicamente, creo que la forma más intuitiva es usar PrincipalSearcher de System.DirectoryServices.AccountManagement. Puede encontrar fácilmente muchos ejemplos diferentes de google. Aquí hay una muestra que está haciendo exactamente lo que está pidiendo.

using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com")) 
{ 
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context))) 
    { 
     foreach (var result in searcher.FindAll()) 
     { 
      DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry; 
      Console.WriteLine("First Name: " + de.Properties["givenName"].Value); 
      Console.WriteLine("Last Name : " + de.Properties["sn"].Value); 
      Console.WriteLine("SAM account name : " + de.Properties["samAccountName"].Value); 
      Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value); 
      Console.WriteLine(); 
     } 
    } 
} 
Console.ReadLine(); 

Tenga en cuenta que en el objeto de usuario de AD, hay una serie de atributos. En particular, givenName le dará el First Name y sn le dará el Last Name. Sobre el nombre de usuario. Creo que quisiste decir el nombre de inicio de sesión del usuario. Tenga en cuenta que hay dos nombres de inicio de sesión en el objeto de usuario AD. Uno es samAccountName, que también se conoce como nombre de inicio de sesión anterior a Windows 2000. userPrincipalName se utiliza generalmente después de que Windows 2000.

+2

¿Qué pasa si el servidor no contiene el dominio –

+0

¿Cómo se usa el mismo código para listar a los usuarios de un grupo AD? – nJoshi

+0

¿Hay alguna manera de utilizar este método para limitar la búsqueda a solo aquellos en el directorio al que se le ha asignado una dirección de correo electrónico? – ARidder101

2

Incluir el System.DirectoryServices.dll, a continuación, utilizar el código de abajo:

DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + Environment.MachineName); 
string userNames="<strong class="highlight">Users</strong> : "; 
foreach (DirectoryEntry child in directoryEntry.Children) 
{ 
    if (child.SchemaClassName == "User") 
    { 
     userNames += child.Name + Environment.NewLine ;   
    } 

} 
MessageBox.Show(userNames); 
15

Si desea filtrar cuentas activas Y agrega esto a código de Harvey:

UserPrincipal userPrin = new UserPrincipal(context); 
userPrin.Enabled = true; 

después del primer uso. A continuación, agregue

searcher.QueryFilter = userPrin; 

antes de encontrar todo. Y eso debería hacerte los activos.

+0

No creo que necesite 'searcher.QueryFilter = userPrin;' ya que pasamos el usuario principal al buscador principal en la inicialización, pero de lo contrario ¡gracias por la sugerencia de filtrar usuarios activos solamente! – Andrey

+0

Sí, Andrey tiene razón Así que, básicamente, esto podría reemplazarse por agregar esta propiedad en la segunda declaración de uso: 'using (var searcher = new PrincipalSearcher (new UserPrincipal (context) {Enabled = true}))' –

1

Ciertamente, el crédito es para @Harvey Kwok aquí, pero solo quería agregar este ejemplo porque en mi caso quería obtener una Lista real de UserPrincipals. Probablemente sea más eficiente filtrar esta consulta por adelantado, pero en mi entorno pequeño, es más fácil extraer todo y luego filtrar según sea necesario más adelante de mi lista.

Dependiendo de lo que necesite, es posible que no necesite realizar el fundido en DirectoryEntry, pero algunas propiedades no están disponibles en UserPrincipal.

using (var searcher = new PrincipalSearcher(new UserPrincipal(new PrincipalContext(ContextType.Domain, Environment.UserDomainName)))) 
{ 
    List<UserPrincipal> users = searcher.FindAll().Select(u => (UserPrincipal)u).ToList(); 
    foreach(var u in users) 
     { 
      DirectoryEntry d = (DirectoryEntry)e.GetUnderlyingObject(); 
      Console.WriteLine(d.Properties["GivenName"].Value.ToString() + d.Properties["sn"].Value.ToString()); 
     } 
} 
Cuestiones relacionadas