Invoke-ADPermissionAnalysis¶
Synopsis¶
Produces a comprehensive inventory of every DACL ACE on every object in a single Active Directory domain, across all naming contexts, for least-privilege analysis.
Description¶
Entry point for the AD Permissions Analyzer. Orchestrates all six phases per docs/AD-Permissions-Analyzer-Plan.md §3 by dot-sourcing scripts/lib/Phase[1-6]-*.ps1 and wiring the per-phase JSONL events from §13:
Phase 1 — LDAP bind + naming-context discovery + GUID/SID maps (§5, §8) Phase 2 — paged enumeration with SecurityDescriptorFlagControl(OWNER | DACL) Phase 3 — ACE parsing in a runspace pool (synthetic Owner + IsDaclProtected) Phase 4 — trustee resolution + transitive group expansion + skip-set Phase 5 — inheritance-source resolution via composite-key index Phase 6 — streaming detail CSV + incremental pivot accumulator + pivot CSV
Outputs two CSVs (per-ACE detail, per-trustee pivot) and a JSONL log to -OutputDirectory. Exit code 0 on success, 1 on unrecoverable fault, 2 on success-with-warnings (per §14). House style — foreach, .Where({}), typed collections, CmdletBinding, structured JSONL logging, no Set-StrictMode, no ForEach-Object, no Where-Object — applies throughout.
Syntax¶
.\Invoke-ADPermissionAnalysis.ps1 [-Domain <string>] [-Server <string>] [-Credential <pscredential>]
-OutputDirectory <string> [-DetailFileName <string>] [-PivotFileName <string>]
[-LogFileName <string>] [-BatchSize <int32>] [-ThreadCount <int32>] [-PageSize <int32>]
[-IncludeNamingContexts <string[]>] [-SkipTransitiveExpansion] [<CommonParameters>]
Parameters¶
-Domain¶
FQDN of the target domain. Default: the current user's domain (resolved at runtime).
| Attribute | Value |
|---|---|
| Type | String |
| Required | False |
| Default | — |
| Position | Named |
-Server¶
Specific domain controller to bind to. Default: DC locator.
| Attribute | Value |
|---|---|
| Type | String |
| Required | False |
| Default | — |
| Position | Named |
-Credential¶
Credential to use for the LDAP bind. Default: current process identity.
| Attribute | Value |
|---|---|
| Type | PSCredential |
| Required | False |
| Default | — |
| Position | Named |
-OutputDirectory¶
Directory where the detail CSV, pivot CSV, and JSONL log are written. Created if it does not exist.
| Attribute | Value |
|---|---|
| Type | String |
| Required | True |
| Default | — |
| Position | Named |
-DetailFileName¶
Filename for the per-ACE detail CSV. Default: ADPermissions_Detail_
| Attribute | Value |
|---|---|
| Type | String |
| Required | False |
| Default | — |
| Position | Named |
-PivotFileName¶
Filename for the per-trustee pivot CSV. Default: ADPermissions_Pivot_
| Attribute | Value |
|---|---|
| Type | String |
| Required | False |
| Default | — |
| Position | Named |
-LogFileName¶
Filename for the structured JSONL log. Default: ADPermissions_
| Attribute | Value |
|---|---|
| Type | String |
| Required | False |
| Default | — |
| Position | Named |
-BatchSize¶
Number of objects per runspace work unit during phase 3 ACE parsing. Default: 250.
| Attribute | Value |
|---|---|
| Type | Int32 |
| Required | False |
| Default | 250 |
| Position | Named |
-ThreadCount¶
Number of runspaces in the pool. Default: [Environment]::ProcessorCount. Accepted range 1-32; in practice LDAP becomes the bottleneck around 8-16 threads, so values above ~16 typically yield diminishing returns.
| Attribute | Value |
|---|---|
| Type | Int32 |
| Required | False |
| Default | [Environment]::ProcessorCount |
| Position | Named |
-PageSize¶
LDAP paged-search page size. Default: 1000 (the AD server-side cap).
| Attribute | Value |
|---|---|
| Type | Int32 |
| Required | False |
| Default | 1000 |
| Position | Named |
-IncludeNamingContexts¶
Naming contexts to enumerate. Default: Domain, Configuration, Schema, DNS.
| Attribute | Value |
|---|---|
| Type | String[] |
| Required | False |
| Default | @('Domain', 'Configuration', 'Schema', 'DNS') |
| Position | Named |
-SkipTransitiveExpansion¶
Escape hatch: skip transitive group expansion. Group-trustee ACEs are emitted with the group as the effective trustee. Default: off.
| Attribute | Value |
|---|---|
| Type | SwitchParameter |
| Required | False |
| Default | — |
| Position | Named |
CommonParameters¶
This script supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters.
Examples¶
Example 1: Run against the current domain with default settings¶
Run against the current domain with default settings.
Example 2: Run against a specific domain and DC, with limited NCs and a fixed thread count¶
$params = @{
Domain = '<domain.fqdn>'
Server = '<dc-fqdn>'
OutputDirectory = 'C:\AdPermAudit'
ThreadCount = 8
IncludeNamingContexts = @('Domain', 'Configuration')
}
.\Invoke-ADPermissionAnalysis.ps1 @params
Run against a specific domain and DC, with limited NCs and a fixed thread count.
Inputs¶
None.
Outputs¶
None.
Notes¶
Windows-only. Uses System.DirectoryServices.ActiveDirectorySecurity and NTAccount.Translate(); these are not available on .NET on Linux/macOS.
Permissions: read access to nTSecurityDescriptor on every enumerated object. Typically Domain Admins or an explicitly delegated principal.
Specification: docs/AD-Permissions-Analyzer-Plan.md