LDAP filters: 20 examples for Active Directory

Most LDAP queries against Active Directory follow a handful of patterns. Here are the 20 most common, each with a short explanation and one click to adapt it in the filter builder.

How to use the filters

# PowerShell (RSAT, ActiveDirectory module)
Get-ADUser -LDAPFilter '(&(objectCategory=person)(objectClass=user)(mail=*))' -Properties mail

# Linux/macOS
ldapsearch -H ldaps://dc1.example.com -D 'svc-ldap@example.com' -W \
  -b 'DC=example,DC=com' '(&(objectCategory=person)(objectClass=user)(mail=*))' sAMAccountName mail

# Windows built-in
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(mail=*))" -attr sAMAccountName mail

The filter defines what is searched for. Where it is searched (the whole domain or just one OU) is set by the search base (-b or -SearchBase).

Users

1. All user accounts

(&(objectCategory=person)(objectClass=user))

objectCategory=person together with objectClass=user returns only real users, no contacts and no computers (in AD computers are user objects too). Open in builder ›

2. Enabled users

(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))

Bit 2 in userAccountControl means “disabled”. The long number is the bitwise AND rule; negated it means “not disabled”. Open in builder ›

3. Disabled users

(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))

The same without negation, handy for clean-ups. Open in builder ›

4. Locked-out accounts

(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))

lockoutTime greater than 0 means the account was locked. The value stays even after the lockout duration has expired, until the user logs on again. So the list may contain more accounts than are actually locked right now. Open in builder ›

5. Password never expires

(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))

Bit 65536 (DONT_EXPIRE_PASSWORD). One for audits. Open in builder ›

6. Must change password at next logon

(&(objectCategory=person)(objectClass=user)(pwdLastSet=0))

pwdLastSet=0 is exactly this state. Open in builder ›

7. Members of a group (direct)

(&(objectCategory=person)(objectClass=user)(memberOf=CN=VPN-Users,OU=Groups,DC=example,DC=com))

The group must be given as a full DN. Wildcards like CN=VPN* do not work with memberOf. Open in builder ›

8. Members of a group including nested groups

(&(objectCategory=person)(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=CN=VPN-Users,OU=Groups,DC=example,DC=com))

The rule 1.2.840.113556.1.4.1941 (LDAP_MATCHING_RULE_IN_CHAIN) resolves nested groups. Slower in large directories. Open in builder ›

9. Users with an email address

(&(objectCategory=person)(objectClass=user)(mail=*))

=* means “attribute is present”. Open in builder ›

10. Users without an email address

(&(objectCategory=person)(objectClass=user)(!(mail=*)))

Negated: attribute is missing. Open in builder ›

11. Search like the address book

(anr=Müller)

anr (ambiguous name resolution) is an AD speciality and searches surname, given name, display name, logon name and more at once. Open in builder ›

12. Logon by user name or UPN

(&(objectCategory=person)(objectClass=user)(|(sAMAccountName={user})(userPrincipalName={user})))

The typical filter for applications with LDAP login. The application replaces {user} with the input, which must be escaped per RFC 4515, otherwise LDAP injection is possible. Open in builder ›

13. Not logged on for a long time

(&(objectCategory=person)(objectClass=user)(lastLogonTimestamp<=134116992000000000))

lastLogonTimestamp is a Windows timestamp (100 ns steps since 1601). The number in the example is January 1, 2026. The attribute is only updated about every 9–14 days and suits “not logged on for months”, not “since yesterday”. Open in builder ›

14. Created since a date

(&(objectCategory=person)(objectClass=user)(whenCreated>=20260101000000.0Z))

whenCreated uses the format YYYYMMDDHHMMSS.0Z (UTC). Open in builder ›

15. Accounts with a service principal name

(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))

User accounts with an SPN are service accounts and the target of Kerberoasting. They should have long random passwords or be gMSAs. Open in builder ›

16. Protected accounts (adminCount)

(&(objectCategory=person)(objectClass=user)(adminCount=1))

adminCount=1 is set on accounts that are or were members of a privileged group. Good for finding forgotten admin rights. Open in builder ›

Computers and groups

17. All computers

(objectCategory=computer)

Computer accounts in the domain. Open in builder ›

18. Domain controllers

(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))

Only domain controllers have bit 8192 (SERVER_TRUST_ACCOUNT). Open in builder ›

19. Windows servers

(&(objectCategory=computer)(operatingSystem=*Server*))

Wildcards work on ordinary text attributes such as operatingSystem. Open in builder ›

20. Empty security groups

(&(objectCategory=group)(groupType:1.2.840.113556.1.4.803:=2147483648)(!(member=*)))

Bit 2147483648 in groupType marks security groups; !(member=*) means “no members”. Members via the primary group (e.g. Domain Users) do not count here. Open in builder ›

Tips for fast and safe filters

FAQ

Why does my filter find computers although I search for objectClass=user?

In Active Directory computer accounts inherit from the user class. objectCategory=person excludes them.

How do I find all groups of a user including nested ones?

With the IN_CHAIN rule the other way round: (member:1.2.840.113556.1.4.1941:=CN=Max Muster,OU=Users,DC=example,DC=com) applied to groups.

Why does the query return only 1000 results?

Active Directory limits responses to 1000 entries per page by default. The tool must use paging; Get-ADUser does this automatically, ldapsearch with -E pr=1000/noprompt.

Can I search for the password with a filter?

No. Passwords are neither readable nor searchable. You can only filter on metadata such as pwdLastSet.