PowerView
Enumeration
# Domain information
Get-Domain
# Domain SID
Get-DomainSID
# DC info
Get-DomainControllerWhen forging tickets, the Kerberos-related policies are typically set to the default values by the tools (e.g. mimikatz, rubeus) automatically. If the domain has custom values, the mismatch will probably cause issues.
# Domain policies
Get-DomainPolicyDataThe unfiltered command will result in a massive output:
# List the specified attributes of all domain users
Get-DomainUser | select samaccountname
# Query about a specified user
Get-DomainUser -Identity ca_svc
# Search for a particular string in a user's attribute
Get-DomainUser -LDAPFilter "Description=*built*" | select name,descriptionOPSEC: The logonCount attribute can help in identifying honeypot or dormant accounts; make sure to not attack these as they will generate a lot of alerts!
# Filter by logonCount
Get-DomainUser | select samaccountname,logonCount
# Enumerate honeypot accounts
Get-DomainUser | Where-Object {$_.logoncount -eq 0}
# Discard honeypot accounts
Get-DomainUser | Where-Object {$_.logoncount -gt 0}By default, a domain user can add up to 10 domain objects. As a result, there is a good chance that not all of them are real hosts. Use logonCount to check:
When querying about Domain Admins members, -500 indicates that this is the default Administrator account, while -1000+ indicates that it is user-created.
OPSEC: Stay away from DAs → the most well-protected and monitored account!
If operating from a child domain, the forest root need to be enumerated separately using -Domain or cross-domain trust enumeration. For instance, the Enterprise Admins group only exists in the forest root.
Querying for local groups require admin rights on non-DC machines:
How to read an ACE → SecurityIdentifier has ActiveDirectoryRights on ObjectDN:
The ObjectAceType fields tells us what ACE the user has over the object:

Search for specific permissions:
In case the script cannot be used, we can use native cmdlets. To convert the GUID into a human-readable format we can either perform a reverse search or just google it:
# List domain GPOs
Get-DomainGPO | select displayname
Get-DomainGPO -Identity <host>
# GPOs which use Restricted Groups or groups.xml for interesting users
Get-DomainGPOLocalGroup
# Users which are in a local group of a host using GPO
Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity <host>
# Machines where the given user is member of a specific group
Get-DomainGPOUserLocalGroupMapping -Identity user# List domain OUs
Get-DomainOUList the members of an OU:
# Find the gplink attribute
Get-NetOU
(Get-DomainOu -Identity DevOps).gplink
[LDAP://cn={0BF8D01C-1F62-4BDC-958C-57140B67D147},cn=policies,cn=system,DC=dollarcorp,DC=moneycorp,DC=local;0]
# Find the name corresponding to the gplink
Get-DomainGPO -Identity "{0BF8D01C-1F62-4BDC-958C-57140B67D147}"
displayname : DevOps Policy
# List hosts members of the OU
(Get-DomainOU -Identity DevOps).distinguishedname | %{Get-DomainComputer -SearchBase $_} | select nameTo enumerate external trusts between domains filter based on TrustAttributes:
If an external trust exists, the domain can be enumerated. But remember, there is no transitivity, so other domains cannot be enumerated:
Query for active sessions (requires admin rights):
Query for DA sessions by asking the DC for the group members of the specified group (Get-DomainGroupMember) (Domain Admins by default), getting a list of hosts (Get-DomainComputer), and listing sessions (Get-NetSession) and logged on users (Get-NetLoggedon) from each one:
OPSEC: This is noisy as it leaves a 4624 (logon), 4634 (logoff) and, in case of a hit, 4672 (success). In addition, it tries to list sessions on the DC which will create alerts on MDI. Use the ComputerName parameter to scan hosts in batches and exclude the DC from the hosts.
Another way of listing sessions on remote machine is Invoke-SessionHunter. This doesn't need admin privs as it uses Remote Registry and queries the HKEY_USERS hive:
The below function queries the DC (of the current or provided domain) for a list of hosts (Get-NetComputer) and then uses Invoke-CheckLocalAdminAccess on each using RPC/SMB ports:
OPSEC: This is noisy as it leaves a 4624 (logon), 4634 (logoff) and, in case of a hit, 4672 (success). Use the ComputerName parameter to scan hosts in batches.
This command uses the OpenServiceW function to interact with the Service Control Manager (SCM) on a target machine. The SCM manages installed services and drivers. PowerView tries to connect to it with SC_MANAGER_ALL_ACCESS permissions, which require administrative rights. If it succeeds, it infers that the current user has administrator privileges on that machine.
In case ports used by Find-LocalAdminAccess are blocked try:
Find-WMILocalAdminAccess.ps1Find-PSRemotingLocalAdminAccess.ps1
Attacks
Kerberoasting
For Kerberoasting see here.
Password Change
For changing the password of an account see here.
LAPS Password
For changing the LAPS password see here.
Python Version
PowerView.py is an alternative for the original PowerView.ps1 script. Its main goal is to achieve interactive session without having to repeatedly authenticate to LDAP.
Add a user to a group:
Check object's ACL:
Last updated
Was this helpful?