A Comprehensive Guide to Retrieving User Lists from Active Directory Using C#

Nov 23, 2025 · Programming · 10 views · 7.8

Keywords: C# | Active Directory | User Retrieval

Abstract: This article provides a detailed explanation of how to retrieve user information, including usernames, first names, and last names, from Active Directory using C#. It begins by covering the fundamental concepts of Active Directory as an LDAP server, then presents a complete code example using the PrincipalSearcher class to connect to a domain, execute queries, and extract user attributes. Additionally, it discusses different user object properties such as samAccountName and userPrincipalName, helping developers understand and utilize these key elements effectively.

Fundamental Concepts of Active Directory

Active Directory is a directory service based on LDAP (Lightweight Directory Access Protocol), used in Windows environments to store and manage network resources. Data is organized in a hierarchical structure, similar to directories and files in a file system, hence the name "directory." Each object in Active Directory has a unique "Distinguished Name," formatted like CN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=com, which acts like a file path to precisely locate objects.

LDAP Query Methods in .NET

In the .NET framework, several approaches are available for executing LDAP queries to access Active Directory data. Common classes include System.DirectoryServices.DirectorySearcher and System.DirectoryServices.Protocols.SearchRequest, which offer flexible query capabilities. For retrieving user principal objects, the System.DirectoryServices.AccountManagement.PrincipalSearcher class is recommended, as it is specifically designed for handling security principals like users, groups, and computers, simplifying the query process.

Retrieving User Information with PrincipalSearcher

Below is a complete C# code example demonstrating how to connect to an Active Directory domain, retrieve all users, and extract attributes such as username, first name, and last name. The code uses using statements to ensure proper resource disposal and avoid memory leaks.

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();

In this example, PrincipalContext establishes a connection to the specified domain, with ContextType.Domain setting the context type to domain and "yourdomain.com" to be replaced with the actual domain name. PrincipalSearcher is initialized with a UserPrincipal object, defining the query filter for all users. The FindAll method allows iteration over all matching user results.

For each result, the GetUnderlyingObject method retrieves the underlying DirectoryEntry object to access raw properties. Key attributes include: givenName (for first name), sn (for last name), samAccountName (SAM account name, commonly used for legacy Windows logins), and userPrincipalName (user principal name, used in modern login scenarios). These attribute values are accessed via the Properties collection and retrieved using the Value property.

Detailed Explanation of User Attributes

Active Directory user objects contain various attributes for storing user information. Beyond basic attributes, samAccountName and userPrincipalName are two common username formats: samAccountName is often used for intra-domain legacy authentication, while userPrincipalName follows an email-like format (e.g., user@domain.com) and supports broader authentication scenarios. In practice, select the appropriate attribute based on requirements, such as when integrating authentication in ASP.NET applications.

Best Practices and Considerations

When using this code, ensure the application has sufficient permissions to access Active Directory; otherwise, exceptions may be thrown. It is advisable to add error handling in production environments, for example, using try-catch blocks to catch PrincipalException or DirectoryServicesCOMException. Additionally, for large domains, queries might return numerous results, so consider using paging or filters to optimize performance, such as setting query conditions via UserPrincipal properties.

In summary, the PrincipalSearcher class enables efficient extraction of user information from Active Directory, suitable for various .NET application scenarios like user management, report generation, or identity service integration.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.