← Back to list

Unlocking Active Directory: How to Read and Retrieve Data Efficiently in C#

Active Directory (AD) is a powerful tool for managing user accounts, permissions, and organizational resources in enterprise environments…

Ali Mustafa · 2025-05-26 00:12 · 0 claps · 3.2 min read
#c-sharp-programming #active-directory #ldap-server #directorysearcher #directoryentry
Open on Medium ↗
Wiki topics: 💻 · Programming 🎬 · Film & Television

Unlocking Active Directory: How to Read and Retrieve Data Efficiently in C

Active Directory (AD) is a powerful tool for managing user accounts, permissions, and organizational resources in enterprise environments. While it’s widely used, efficiently retrieving data from AD can be tricky — especially when working with LDAP queries in C#.

As I’ve been exploring AD data retrieval, I’ve realized that mastering efficient queries is essential for handling authentication, automating administrative tasks, and optimizing system performance.

This article is a beginner-friendly guide to querying Active Directory using C# and LDAP. Whether you’re new to AD or looking for structured insights, we’ll walk through setting up connections, executing queries and filtering results. By the end, you’ll have a solid foundation for reading and retrieving AD data efficiently.

Let’s dive in!

Prerequisites

  1. Active Directory Server: A running AD instance.
  2. User Account: Credentials with read permissions to retreive AD data.
  3. Development Environment:
  • .NET Core
  • Visual Studio or Visual Studio Code
  • NuGet Package: System.DirectoryServices

Setting Up an LDAP Connection in C#

Before querying Active Directory (AD), establishing a connection is the first step. LDAP (Lightweight Directory Access Protocol) enables interaction with AD, allowing retrieval of user details, organizational units, and security groups. In this section, we’ll go through the essential steps to set up and authenticate an LDAP connection using C#.

To establish a connection we are going to use **DirectoryEntry**class provided by the System.DirectoryServices namespace.

The **DirectoryEntry**class will allow us to interact with AD by:

  • Establishes a connection to Active Directory Server
  • Allows us to read data like: users, groups and other objects.
  • Supports authentication for secure access.
        string ipAddress = "server-ipaddress";
        int port = 389; //Use port 389 for standard LDAP, For LDAPS (Secure LDAP) the port should be 636
        string username = "your-username";
        string password = "your-password";

        DirectoryEntry entry = new DirectoryEntry($"LDAP://{ipAddress}:{port}", username, password);

This snippet configures **DirectoryEntry** with a basic setup, initializing the entry point at the root of the domain controller. This ensures that the search begins at the highest level of the directory structure.

Later, you can refine the starting point of the search to target a specific Organizational Unit (OU) instead of the root domain. To do this, modify the DirectoryEntry initialization as follows:

DirectoryEntry entry = new DirectoryEntry($"LDAP://{ipAddress}:{port}/distinguishedNameOfTheOUEntryPoint", username, password);

Replace **distinguishedNameOfTheOUEntryPoint with the Distinguished Name (DN) of the OU where the search should begin. But for now we will keep the search starting from the root entry** of the domain controller.

Now that we have the DirectoryEntryis ready, We need to configure the DirectorySearcher, Which is the key tool for searching and retrieving data from AD using LDAP. We will take an example for retrieving users from AD:

        DirectorySearcher searcher = new DirectorySearcher(entry);
        searcher.Filter = "(&(objectCategory=person)(objectClass=user))";

This code snippet initializes the **DirectorySearcher** object. When creating a DirectorySearcher instance, we must define an entry point that serves as the starting location for our search. Here, we pass the previously initialized entry object into the constructor, ensuring that the search begins from the root domain.

Next, we define searcher.Filter to specify the type of object we want to retrieve. In this case, we are targeting user accounts using objectClass=user, while also ensuring that only human users are included by applying objectCategory=person.

After specifying the seacher.Filter we need to specify which properties we want to retrieve:

searcher.PropertiesToLoad.Add("sAMAccountName");
searcher.PropertiesToLoad.Add("displayName");   
searcher.PropertiesToLoad.Add("mail");        
searcher.PropertiesToLoad.Add("telephoneNumber");
searcher.PropertiesToLoad.Add("department");
searcher.PropertiesToLoad.Add("proxyAddresses");

Next, We will define seacher.SeachScope

seacher.SeachScope = SeachScope.Subtree

We set searcher.SearchScope = SearchScope.Subtree, meaning the search will begin from the specified entry and traverse all nested objects below it.

Types of SearchScope

  1. SearchScope.Base searches only the specified object in the filter and returns at most one result. This is useful when looking for objects by a unique identifier, such as distinguishedName.
  2. SearchScope.OneLevel searches only the immediate children of the specified entry point, without including deeper levels. This is useful when retrieving all users within a single organizational unit, while excluding sub-units.
  3. SearchScope.Subtree searches from the specified entry point and includes all nested children. This is useful for finding objects across the entire directory structure, including sub-units.

Next, Let us execute the LDAP query:

SearchResultCollection results = searcher.FindAll();

This will execute the LDAP query and retrieve the results.

Last step: we need to get the values from the results variable:

The way to get the values from the results variable is by accessing the Properties collection from the SearchResult object withing the results

foreach (SearchResult result in results)
{
    if (result.Properties.Contains("sAMAccountName"))
        Console.WriteLine("Username: " + result.Properties["sAMAccountName"][0]);

    if (result.Properties.Contains("displayName"))
        Console.WriteLine("Display Name: " + result.Properties["displayName"][0]);

    if (result.Properties.Contains("mail"))
        Console.WriteLine("Email: " + result.Properties["mail"][0]);

    if (result.Properties.Contains("telephoneNumber"))
        Console.WriteLine("Phone Number: " + result.Properties["telephoneNumber"][0]);

    if (result.Properties.Contains("department"))
        Console.WriteLine("Department: " + result.Properties["department"][0]);

    if (result.Properties.Contains("proxyAddresses"))
    {
        Console.WriteLine("Proxy Addresses:");
        foreach (var address in result.Properties["proxyAddresses"])
        {
            Console.WriteLine(address);
        }
    }

    Console.WriteLine("----------------------");
}

Conclusion

In this article, we explored how to efficiently query Active Directory using LDAP filters, optimize search scope, and retrieve key attributes like proxyAddresses. By applying these techniques, you can streamline directory searches and improve performance, making Active Directory queries more precise and effective.

If you found this helpful, feel free to leave a comment and share your thoughts!


메타데이터
post_id
adf02e22a397
slug
unlocking-active-directory-how-to-read-and-retrieve-data-efficiently-adf02e22a397
url
https://medium.com/@alimustafa98.tech/unlocking-active-directory-how-to-read-and-retrieve-data-efficiently-adf02e22a397
canonical_url
https://medium.com/@alimustafa98.tech/unlocking-active-directory-how-to-read-and-retrieve-data-efficiently-adf02e22a397
author_url
https://medium.com/@alimustafa98.tech
status
ok
fetched_at
2026-08-11 07:02:11