Active Directory (AD) is the central nervous system of most enterprise networks. For a Red Teamer, querying AD is arguably the most important phase of internal reconnaissance. It tells you where the users are, who is an admin, and where the sensitive servers live.

While modern tools like BloodHound and PowerView get all the glory, the built-in Microsoft tool DSQuery (and its cousin DSGet) is a stable, reliable way to extract this data without importing suspicious PowerShell scripts that might trigger AMSI (Antimalware Scan Interface).

In this guide, we will explore how to perform deep reconnaissance using only the tools Microsoft provided.


1. Technical Prerequisite: The RSAT Problem

Before we dive into the commands, let’s address a massive technical hurdle: DSQuery is not installed by default on Windows workstations.

It is part of the Remote Server Administration Tools (RSAT). This means if you land on a standard user’s laptop (e.g., via a Phishing payload), dsquery will likely return “command not found.” You will typically only find this tool on:

  1. Domain Controllers (where it’s always available).
  2. IT Admin Workstations (where RSAT is intentionally installed).
  3. Jump Boxes / Management Servers.
  4. Exchange/SQL Servers.

[!WARNING] Do NOT try to install RSAT on a compromised machine to get these tools. That generates massive telemetry (Windows Update traffic, installer logs). If the tools aren’t there, use the PowerShell ADSI alternatives (see Section 5).


2. Practical DSQuery Commands for Red Teaming

If you are lucky enough to be on a box with RSAT (or you brought your own dsquery.exe binary), here is how you weaponize it.

Finding Passwords in Descriptions (The “Low Hanging Fruit”)

Administrators often leave sensitive information, including temporary passwords, in the object description field.

1
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(description=*pass*))" -attr samid description

Finding Stale Accounts

Accounts that haven’t been used in months are prime candidates for takeover because their owners won’t notice if they are suddenly active.

1
2
# Find users inactive for more than 4 weeks
dsquery user -inactive 4

Enumerating High-Value Groups

We always want to know who the Domain Admins are.

1
dsquery group -name "Domain Admins" | dsget group -members

Note: This pipes the “DN” (Distinguished Name) from query to get, expanding the list.

Identifying Domain Controllers

Detailed info on DCs helps planning attacks like ZeroLogon or PetitPotam.

1
dsquery server -o rdn

3. Advanced Hunting: SPNs and Delegation

This is where dsquery becomes an attack tool.

Identifying Kerberoastable Accounts (SPNs)

Service Principal Names (SPNs) indicate a service account. If a user account has an SPN, you can request a Kerberos ticket for it and crack it offline (Kerberoasting).

1
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))" -attr samid servicePrincipalName

Finding Unconstrained Delegation

Finding servers with Unconstrained Delegation is a high-priority red team task. If a Domain Admin connects to a server with this setting, their TGT is cached in memory, allowing you to impersonate them.

The magic number for TRUSTED_FOR_DELEGATION in the userAccountControl attribute is 524288.

1
dsquery * -filter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" -attr samid ipv4Address

Finding “AdminCount=1” (Protected Users)

Users marked with adminCount=1 are (or were) members of a protected group (like Domain Admins).

1
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(adminCount=1))" -attr samid

4. Chaining DSQuery and DSGet

The true power of DSQuery comes when you pipe it into dsget. dsquery finds the object, and dsget extracts specific attributes.

Finding User Email Addresses

Useful for Phishing or Password Spraying targets.

1
dsquery user -name "*Smith*" | dsget user -email

Finding Computer Operating Systems

Useful for targeting exploitable versions (e.g., Windows 7/2008).

1
dsquery computer -name "SRV*" | dsget computer -os -samid

5. What if dsquery is missing? (PowerShell ADSI)

If you are on a restricted machine without RSAT, you can use the built-in [ADSISearcher] type accelerator in PowerShell. This performs the exact same LDAP queries but uses .NET. It is stealthy, built-in, and powerful.

Example: Finding Domain Admins query equivalent

1
2
3
4
$searcher = [adsisearcher]"(objectCategory=group)"
$searcher.Filter = "name=Domain Admins"
$result = $searcher.FindOne()
$result.GetDirectoryEntry().member

Example: Finding SPNs (Kerberoasting Candidates)

1
([adsisearcher]"(&(objectCategory=user)(servicePrincipalName=*))").FindAll() | Select-Object -ExpandProperty Properties

This is quieter and works on every Windows machine since Windows 7.


6. OpSec and Forensic Considerations

Active Directory enumeration is not silent.

  1. LDAP Traffic: dsquery generates standard LDAP queries (TCP 389). Defenders monitoring network traffic will see large LDAP search responses going to a workstation that shouldn’t be mapping the network.
  2. Microsoft Defender for Identity (MDI): MDI (formerly ATA) has specific alerts for “Reconnaissance using Directory Services.” Bulk queries from a non-admin workstation can trigger this.
  3. Honeytokens: Smart Blue Teams create fake accounts (e.g., da_admin). If you query for *admin* and touch that object, you trip an alarm.
  4. Event Logs: Extensive querying can trigger generic LDAP events, though precise “Who queried what” logging (Event ID 4662) is rare unless SACLs are configured on the AD objects.

Conclusion

DSQuery remains a fundamental tool for Active Directory reconnaissance when it’s available. By understanding how to construct raw LDAP filters, you can uncover critical misconfigurations like delegation issues and Kerberoastable accounts without needing external scripts.

But remember: tools are just wrappers around protocols. Whether you use dsquery, PowerView, or raw ADSI, the underlying LDAP query is the same. Master the query, master the domain.

Happy hunting!


References