# Get-ADUser PowerShell Examples: 25 Queries for Active Directory

Source: https://srvscripts.com/guides/get-aduser-powershell-examples/
Updated: 2026-10-03
Publisher: srvScripts (https://srvscripts.com/)

These Get-ADUser PowerShell examples cover the queries Active Directory administrators run every week: finding one user, filtering thousands, reading extra attributes, checking logon and password dates, listing group membership and exporting clean reports. Every command works with the ActiveDirectory module on Windows Server 2016 to 2025 and on Windows 11 with RSAT.

**Short answer:** Use `Get-ADUser -Identity jsmith -Properties *` to inspect one account, and `Get-ADUser -Filter "Enabled -eq 'True'" -SearchBase "OU=Staff,DC=contoso,DC=com" -Properties Department` to query many. Filter on the server with `-Filter` or `-LDAPFilter`, request only the properties you need, and pipe to `Export-Csv` for reports.

In short: Use Get-ADUser -Identity jsmith -Properties * to inspect one account, and Get-ADUser -Filter “Enabled -eq ‘True'” -SearchBase “OU=Staff,DC=contoso,DC=com” -Properties Department to query many.

## Which query style to use

| Parameter | Use it for | Pros | Cons |
| --- | --- | --- | --- |
| -Identity | One known account (sAMAccountName, DN, GUID or SID) | Fastest; exact match | Throws an error if the user does not exist |
| -Filter | Most searches | PowerShell-style operators; friendly property names such as Enabled | Only * wildcards; some quoting rules |
| -LDAPFilter | Bitwise flags, recursive membership, filters copied from other tools | Full LDAP syntax, matching rules | Uses raw attribute names only |
| Search-ADAccount | Disabled, locked, expired, inactive accounts | Ready-made switches | Fewer filter options |

## Prerequisites

- The ActiveDirectory module. On Windows Server: `Install-WindowsFeature RSAT-AD-PowerShell`. On Windows 11: `Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0`.

- A reachable domain controller running Active Directory Web Services (TCP 9389). The cmdlets talk to ADWS, not directly to LDAP.

- A normal domain account can read most user attributes. Some attributes, such as BitLocker or LAPS data, need delegated rights.

## Basic lookups (examples 1–5)

The first Get-ADUser PowerShell examples retrieve single accounts and show which properties you get by default.

```
# 1. One user by sAMAccountName, DN, SID or GUID
Get-ADUser -Identity jsmith
Get-ADUser -Identity "CN=John Smith,OU=Staff,DC=contoso,DC=com"
# 2. One user with extra properties
Get-ADUser -Identity jsmith -Properties Department, Title, Manager, EmailAddress
# 3. Every attribute that has a value (use for discovery, not in scripts)
Get-ADUser -Identity jsmith -Properties *
# 4. Find a user by UPN or e-mail address
Get-ADUser -Filter "UserPrincipalName -eq 'john.smith@contoso.com'"
Get-ADUser -Filter "mail -eq 'john.smith@contoso.com'" -Properties mail
# 5. Name search with a wildcard
Get-ADUser -Filter "Name -like 'John*'" | Select-Object Name, SamAccountName, Enabled
```

Without `-Properties`, Get-ADUser returns a small default set: `DistinguishedName`, `Enabled`, `GivenName`, `Name`, `ObjectClass`, `ObjectGUID`, `SamAccountName`, `SID`, `Surname` and `UserPrincipalName`. Anything else, including `mail`, `Department` and `LastLogonDate`, must be requested.

## Filter syntax (examples 6–10)

The `-Filter` parameter accepts `-eq`, `-ne`, `-lt`, `-le`, `-gt`, `-ge`, `-like`, `-notlike`, `-and`, `-or` and `-not`. Only the `*` wildcard is supported. Put the filter in double quotes and string values in single quotes so variables expand correctly.

```
# 6. Enabled users in one department
Get-ADUser -Filter "Enabled -eq 'True' -and Department -eq 'Finance'" -Properties Department
# 7. Use a variable inside the filter
$dept = 'Sales'
Get-ADUser -Filter "Department -eq '$dept'" -Properties Department, Title
# 8. Users whose password never expires
Get-ADUser -Filter "PasswordNeverExpires -eq 'True'" -Properties PasswordNeverExpires
# 9. Accounts created in the last 30 days (single quotes: the module reads $since)
$since = (Get-Date).AddDays(-30)
Get-ADUser -Filter 'whenCreated -ge $since' -Properties whenCreated |
    Sort-Object whenCreated | Select-Object Name, whenCreated
# 10. Users with an empty attribute (no e-mail address)
Get-ADUser -Filter "Enabled -eq 'True' -and mail -notlike '*'" | Select-Object Name, SamAccountName
```

In example 10, `-notlike '*'` means “attribute not set”. The same query as an LDAP filter is `(&(!(mail=*))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))`. Date comparisons such as example 9 are safest with the filter in single quotes, so the module converts the `DateTime` variable itself instead of relying on your regional date format.

## LDAP filters (examples 11–12)

```
# 11. Enabled users only, using the ACCOUNTDISABLE bit (2) of userAccountControl
Get-ADUser -LDAPFilter '(!userAccountControl:1.2.840.113556.1.4.803:=2)'
# 12. Users with a service principal name (often service accounts)
Get-ADUser -LDAPFilter '(servicePrincipalName=*)' -Properties servicePrincipalName |
    Select-Object SamAccountName, servicePrincipalName
```

The OID `1.2.840.113556.1.4.803` is the bitwise AND matching rule; `1.2.840.113556.1.4.804` is bitwise OR.

## Search base and scope (examples 13–14)

```
# 13. All users in an OU and its child OUs (Subtree is the default)
Get-ADUser -Filter * -SearchBase "OU=Staff,DC=contoso,DC=com"
# 14. Only the OU itself, not child OUs, against a specific DC
Get-ADUser -Filter * -SearchBase "OU=Staff,DC=contoso,DC=com" -SearchScope OneLevel -Server dc01.contoso.com
```

`-SearchScope` accepts `Base`, `OneLevel` and `Subtree`. Use `-Server` when you have just changed an object and want to read it from the DC you wrote it to, before replication completes.

## Disabled, locked and expired accounts (examples 15–17)

These Get-ADUser PowerShell examples mix Get-ADUser with `Search-ADAccount`, which has ready-made switches for account states.

```
# 15. Disabled users
Get-ADUser -Filter "Enabled -eq 'False'" | Select-Object Name, SamAccountName
Search-ADAccount -AccountDisabled -UsersOnly
# 16. Locked-out users, then unlock one
Search-ADAccount -LockedOut -UsersOnly | Select-Object Name, SamAccountName, LastLogonDate
Get-ADUser -Identity jsmith -Properties LockedOut, lockoutTime, BadLogonCount
Unlock-ADAccount -Identity jsmith
# 17. Expired accounts and accounts expiring in the next 14 days
Search-ADAccount -AccountExpired -UsersOnly
Search-ADAccount -AccountExpiring -UsersOnly -TimeSpan 14.00:00:00 |
    Select-Object Name, AccountExpirationDate
```

`LockedOut` is calculated from `lockoutTime` and the lockout duration of the policy that applies to the user. If a user is locked out again straight after an unlock, a device is still sending an old password; to trace where the bad passwords come from, see our guide on event 4740.

## Last logon: lastLogonTimestamp vs LastLogonDate vs lastLogon (examples 18–19)

| Property | Source | Replicated | Accuracy |
| --- | --- | --- | --- |
| lastLogon | Raw attribute on each DC | No | Exact on that DC only |
| lastLogonTimestamp | Raw attribute | Yes | Updated only when older than msDS-LogonTimeSyncInterval (14 days by default, minus a random offset) |
| LastLogonDate | Module property converted from lastLogonTimestamp | Yes | Same as above, as a readable date |

```
# 18. Users with no logon in 90 days (good enough for cleanup, not for audits)
$cutoff = (Get-Date).AddDays(-90)
Get-ADUser -Filter 'Enabled -eq $true -and LastLogonDate -lt $cutoff' -Properties LastLogonDate |
    Select-Object Name, SamAccountName, LastLogonDate
# 19. Exact last logon for one user: query lastLogon on every DC
$user = 'jsmith'
$times = foreach ($dc in (Get-ADDomainController -Filter *).HostName) {
    $u = Get-ADUser -Identity $user -Properties lastLogon -Server $dc
    [pscustomobject]@{ DC = $dc; LastLogon = [datetime]::FromFileTime($u.lastLogon) }
}
$times | Sort-Object LastLogon -Descending | Select-Object -First 1
```

A `lastLogon` of 0 converts to 1 January 1601, which means “never on this DC”. Users who never signed in at all have no `LastLogonDate`, so example 18 does not return them. To include them, use `-Filter 'Enabled -eq $true -and (LastLogonDate -lt $cutoff -or LastLogonDate -notlike "*")'` and check `whenCreated` so brand-new accounts are not flagged.

## Password dates and expiry (examples 20–21)

```
# 20. Password last set, expired flag and computed expiry date
Get-ADUser -Filter "Enabled -eq 'True' -and PasswordNeverExpires -eq 'False'" -SearchBase "OU=Staff,DC=contoso,DC=com" -Properties PasswordLastSet, PasswordExpired, 'msDS-UserPasswordExpiryTimeComputed' |
    Select-Object Name, PasswordLastSet, PasswordExpired,
        @{ n = 'PasswordExpires'; e = {
            $v = $_.'msDS-UserPasswordExpiryTimeComputed'
            if ($v -gt 0 -and $v -lt 9223372036854775807) { [datetime]::FromFileTime($v) } } }
# 21. Which password policy applies (domain policy or a fine-grained PSO)
Get-ADUserResultantPasswordPolicy -Identity jsmith
Get-ADDefaultDomainPasswordPolicy
```

`msDS-UserPasswordExpiryTimeComputed` is a constructed attribute: the DC calculates it from `pwdLastSet` and the maximum password age of the effective policy, including fine-grained password policies. It returns `0` when the user must change the password at next logon and `0x7FFFFFFFFFFFFFFF` when the password never expires or a smart card is required. Because it is constructed, you must name it in `-Properties` and cannot use it inside `-Filter`.

## Group membership (examples 22–23)

Group queries are the Get-ADUser PowerShell examples most often asked for by auditors, and the ones most often done wrong, because direct and nested membership differ.

```
# 22. Direct group membership
Get-ADPrincipalGroupMembership -Identity jsmith | Select-Object Name, GroupScope
(Get-ADUser -Identity jsmith -Properties MemberOf).MemberOf
# 23. Recursive (nested) membership with the in-chain matching rule
$dn = (Get-ADUser -Identity jsmith).DistinguishedName
Get-ADGroup -LDAPFilter "(member:1.2.840.113556.1.4.1941:=$dn)" | Select-Object Name
# ...and the reverse: every user in a group, including nested groups
Get-ADGroupMember -Identity 'GRP-Finance' -Recursive | Where-Object objectClass -eq 'user'
```

`MemberOf` does not include the primary group (normally Domain Users), and `Get-ADPrincipalGroupMembership` needs a global catalog. The matching rule `1.2.840.113556.1.4.1941` (LDAP_MATCHING_RULE_IN_CHAIN) walks nested groups on the DC and is the quickest way to get recursive membership for one user.

## Reports and exports (examples 24–25)

```
# 24. Export a user report to CSV (UTF-8, no type header)
Get-ADUser -Filter "Enabled -eq 'True'" -SearchBase "OU=Staff,DC=contoso,DC=com" -Properties Department, Title, EmailAddress, LastLogonDate, Manager |
    Select-Object Name, SamAccountName, UserPrincipalName, Department, Title, EmailAddress, LastLogonDate,
        @{ n = 'Manager'; e = { if ($_.Manager) { (Get-ADUser -Identity $_.Manager).Name } } } |
    Export-Csv -Path C:\Reports\staff.csv -NoTypeInformation -Encoding UTF8
# 25. Test a query on a small sample, then count results per OU
Get-ADUser -Filter * -ResultSetSize 10
Get-ADUser -Filter * | Group-Object { $_.DistinguishedName -replace '^CN=.+?(?

Keep these Get-ADUser PowerShell examples in a snippets file and adapt the OU paths and attribute lists; most daily reports are combinations of examples 6, 13, 18, 20 and 24.

## Get-ADUser PowerShell examples at a glance

**Official documentation:** [Get-ADUser (ActiveDirectory module)](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser), [Search-ADAccount](https://learn.microsoft.com/en-us/powershell/module/activedirectory/search-adaccount), [ms-DS-User-Password-Expiry-Time-Computed attribute](https://learn.microsoft.com/en-us/windows/win32/adschema/a-msds-userpasswordexpirytimecomputed).

**Related guides:** [Find inactive AD users and computers](/guides/find-inactive-ad-users-computers/) · [AD Account Lockout Source: Easy Event 4740 Tracing](/guides/ad-account-lockout-source-event-4740/) · [Bulk create AD users from CSV with PowerShell](/guides/bulk-create-ad-users-csv/).

## Frequently asked questions

### What is the difference between LastLogonDate and lastLogon?

LastLogonDate is a converted copy of lastLogonTimestamp, which replicates but can be up to about 14 days behind. lastLogon is exact but stored separately on each domain controller, so you must query every DC and take the newest value.

### How do I get all properties of an AD user with PowerShell?

Run Get-ADUser -Identity username -Properties *. Use it to discover attribute names, then list only the properties you need in scripts because -Properties * is slower.

### Why can I not use msDS-UserPasswordExpiryTimeComputed in -Filter?

It is a constructed attribute that the domain controller calculates when you read it, so it cannot be searched. Request it with -Properties and filter the results with Where-Object.

### How do I list nested group membership for a user?

Use Get-ADGroup with the LDAP filter member:1.2.840.113556.1.4.1941:= followed by the user’s distinguished name. The in-chain matching rule returns direct and nested groups in one query.
