esc

Active Directory LDAP Enumeration Reference

๐Ÿ“… Last Updated: May 12, 2026 10:00 | ๐Ÿ“„ Size: 10.3 KB | ๐ŸŽฏ Type: Security Research Report | ๐Ÿ”— Back to Categories

Active Directory LDAP Enumeration

LDAP is the protocol that sits under almost everything in Active Directory. When you query users, groups, computers, GPOs , you're talking LDAP. Understanding how to query it directly gives you a lot of flexibility, especially in environments where your usual tools get flagged.

This covers four ways to query AD via LDAP: the AD PowerShell module, raw LDAP filters with Get-ADObject, ADSI searcher, and WMI , plus ldapsearch from Linux.

Quick Reference

Command Description
Get-ADGroup -Identity "<GROUP NAME>" -Properties * Get full info on an AD group
whoami /priv Check current user privileges
Get-WindowsCapability -Name RSAT* -Online | Select-Object -Property Name, State Check if RSAT tools are installed
Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability -Online Install all RSAT tools
runas /netonly /user:corp.local\username powershell Run a process as another user (useful for remote AD queries from a non-domain machine)
Get-ADObject -LDAPFilter '(objectClass=group)' | select cn Return all AD groups via LDAP filter
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2)' | select name List disabled users
(Get-ADUser -SearchBase "OU=Employees,DC=corp,DC=local" -Filter *).count Count users in a specific OU
get-ciminstance win32_product | fl Query installed software
Get-ADComputer -Filter "DNSHostName -like 'SQL*'" Find computers with SQL in the hostname
Get-ADGroup -Filter "adminCount -eq 1" | select Name Get all protected/admin groups
Get-ADUser -Filter {adminCount -eq '1' -and DoesNotRequirePreAuth -eq 'True'} Find admin users without Kerberos pre-auth (ASREPRoastable)
Get-ADUser -Filter {adminCount -gt 0} -Properties admincount,useraccountcontrol Enumerate UAC values for admin users
Get-WmiObject -Class win32_group -Filter "Domain='corp'" Get AD groups via WMI
([adsisearcher]"(&(objectClass=Computer))").FindAll() Find all computers using ADSI

LDAP Filter Syntax

LDAP filters follow a prefix notation wrapped in parentheses. Once you know the pattern, you can build almost any query.

(attribute=value)           # basic equality
(&(filter1)(filter2))       # AND
(|(filter1)(filter2))       # OR
(!(filter))                 # NOT
(attribute=*)               # attribute exists
(attribute>=value)          # greater than or equal

The bitwise filter 1.2.840.113556.1.4.803 is used constantly for userAccountControl queries. It means "bitwise AND" , you're checking if a specific flag bit is set in the UAC value.

Common UAC flag values:

Flag Value Meaning
ACCOUNTDISABLE 2 Account is disabled
PASSWD_NOTREQD 32 No password required
DONT_EXPIRE_PASSWORD 65536 Password never expires
DONT_REQ_PREAUTH 4194304 No Kerberos pre-auth required

So (userAccountControl:1.2.840.113556.1.4.803:=4194304) means "find all accounts where the DONT_REQ_PREAUTH bit is set" , that's your ASREPRoast target list.

AD PowerShell Module

The cleanest way to query AD on Windows. Needs RSAT installed or to be run on a DC.

# Check / install RSAT
Get-WindowsCapability -Name RSAT* -Online | Select-Object -Property Name, State
Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability -Online

Import-Module ActiveDirectory

# Domain info
Get-ADDomain
Get-ADForest

# Users
Get-ADUser -Filter * -Properties * | Select-Object SamAccountName, Description, PasswordLastSet, LastLogonDate

# Find disabled accounts
Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2)' | select Name

# Find accounts with no pre-auth (ASREPRoastable)
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} | select SamAccountName

# Find admin users without pre-auth , high value targets
Get-ADUser -Filter {adminCount -eq '1' -and DoesNotRequirePreAuth -eq 'True'}

# Enumerate UAC values for all admin users
Get-ADUser -Filter {adminCount -gt 0} -Properties admincount,useraccountcontrol

# Accounts with passwords set to never expire
Get-ADUser -Filter {PasswordNeverExpires -eq $true} | select SamAccountName

# Accounts with SPNs set (Kerberoastable)
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName |
    select SamAccountName, ServicePrincipalName

# Count users in a specific OU
(Get-ADUser -SearchBase "OU=Employees,DC=corp,DC=local" -Filter *).count

# Groups
Get-ADGroup -Filter * | select Name
Get-ADGroup -Filter "adminCount -eq 1" | select Name
Get-ADGroup -Identity "Domain Admins" -Properties *
Get-ADGroupMember "Domain Admins" -Recursive | select SamAccountName

# Computers
Get-ADComputer -Filter * -Properties * | select Name, OperatingSystem, LastLogonDate
Get-ADComputer -Filter "DNSHostName -like 'SQL*'"

# Trusts
Get-ADTrust -Filter *

Raw LDAP Queries with Get-ADObject

When you need more control over what you're querying, Get-ADObject with -LDAPFilter lets you write raw LDAP filters directly.

# All groups
Get-ADObject -LDAPFilter '(objectClass=group)' | select cn

# All users with a description set (check these for passwords)
Get-ADObject -LDAPFilter '(&(objectClass=user)(description=*))' -Properties description |
    select cn, description

# Computers running a specific OS
Get-ADObject -LDAPFilter '(&(objectClass=computer)(operatingSystem=*Server 2016*))' |
    select cn

# Find accounts locked out
Get-ADObject -LDAPFilter '(lockoutTime>=1)' | select cn

# Find objects with adminCount set
Get-ADObject -LDAPFilter '(adminCount=1)' | select cn, objectClass

# Custom search base
Get-ADObject -LDAPFilter '(objectClass=user)' \
    -SearchBase "OU=IT,DC=corp,DC=local" | select cn

ADSI Searcher

[adsisearcher] is a .NET class built into Windows , no imports, no modules needed. Useful when PowerShell remoting is restricted or the AD module isn't available.

# All computers
([adsisearcher]"(&(objectClass=Computer))").FindAll()

# All users
([adsisearcher]"(&(objectClass=user))").FindAll()

# Specific user by samAccountName
([adsisearcher]"(&(objectClass=user)(samAccountName=targetuser))").FindOne()

# Users with SPNs
([adsisearcher]"(&(objectClass=user)(servicePrincipalName=*))").FindAll() |
    foreach { $_.Properties['samaccountname'] }

# Disabled accounts
([adsisearcher]"(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))").FindAll() |
    foreach { $_.Properties['samaccountname'] }

# All groups
([adsisearcher]"(&(objectClass=group))").FindAll() |
    foreach { $_.Properties['cn'] }

# Search a specific OU
$searcher = [adsisearcher]""
$searcher.SearchRoot = [ADSI]"LDAP://OU=IT,DC=corp,DC=local"
$searcher.Filter = "(objectClass=user)"
$searcher.FindAll()

WMI

WMI can query AD objects through the root\directory\LDAP namespace. Slower than the AD module but built into every Windows machine.

# Get AD groups via WMI
Get-WmiObject -Class win32_group -Filter "Domain='corp'"

# Get group members
Get-WmiObject -Class win32_groupuser | Where-Object { $_.GroupComponent -match "Domain Admins" }

# Installed software , useful for identifying vulnerable packages
get-ciminstance win32_product | fl

# Running processes
Get-WmiObject win32_process | Select-Object Name, ProcessId, CommandLine

# All WMI AD classes
Get-WmiObject -Namespace "root\directory\LDAP" -List | Where-Object { $_.Name -like "*user*" }

ldapsearch from Linux

When you're on Linux with valid creds, ldapsearch gives you direct LDAP access without needing a Windows host.

# Authenticate and dump all users
ldapsearch -H ldap://<DC_IP> -D "corp\username" -w 'Password' \
    -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName

# Disabled accounts
ldapsearch -H ldap://<DC_IP> -D "corp\username" -w 'Password' \
    -b "DC=corp,DC=local" "(userAccountControl:1.2.840.113556.1.4.803:=2)" sAMAccountName

# ASREPRoastable accounts
ldapsearch -H ldap://<DC_IP> -D "corp\username" -w 'Password' \
    -b "DC=corp,DC=local" "(userAccountControl:1.2.840.113556.1.4.803:=4194304)" sAMAccountName

# Kerberoastable accounts
ldapsearch -H ldap://<DC_IP> -D "corp\username" -w 'Password' \
    -b "DC=corp,DC=local" "(&(objectClass=user)(servicePrincipalName=*))" \
    sAMAccountName servicePrincipalName

# All groups
ldapsearch -H ldap://<DC_IP> -D "corp\username" -w 'Password' \
    -b "DC=corp,DC=local" "(objectClass=group)" cn

# Anonymous bind check (no creds , sometimes works on misconfigured DCs)
ldapsearch -H ldap://<DC_IP> -x -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName

# Using LDAPS (port 636)
ldapsearch -H ldaps://<DC_IP>:636 -D "corp\username" -w 'Password' \
    -b "DC=corp,DC=local" "(objectClass=user)"

Running as Another User

When you're on a non-domain machine but have domain credentials, runas /netonly lets you spawn a process that authenticates to the domain remotely while still running locally as your current user. Useful for running AD tools from a workstation that isn't joined to the target domain.

runas /netonly /user:corp.local\username powershell
# Enter the password when prompted
# The new PowerShell window will use those creds for any network/domain requests

What to Look For

A few queries worth running on every engagement:

# Accounts that are admin AND don't require Kerberos pre-auth , easy wins
Get-ADUser -Filter {adminCount -eq '1' -and DoesNotRequirePreAuth -eq 'True'}

# Accounts with descriptions , admins sometimes store passwords here
Get-ADUser -Filter * -Properties Description | Where-Object {$_.Description -ne $null} |
    select SamAccountName, Description

# Service accounts with SPNs , Kerberoasting targets
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName |
    select SamAccountName, ServicePrincipalName

# Computers you haven't seen before , find SQL, web, or dev servers
Get-ADComputer -Filter * -Properties * | 
    select Name, OperatingSystem, IPv4Address | Sort-Object OperatingSystem