Active Directory Permission Model
- Version: 3.0
- Methodology: Extracted from
[MaesterTest] Permissionattribute on each AD test - Total tests: 270
- Format:
<Service>:<Kind>:<Name>
The permission model documents the exact minimum permissions each built-in AD test requires. It does not describe human role names (e.g., Domain Admin); it describes the technical permission a test needs to retrieve its data.
Permission Formatโ
Every AD test declares its permissions via the [MaesterTest] Permission attribute as one or more strings in this format:
<Service>:<Kind>:<Name>
| Segment | Description | Examples |
|---|---|---|
Service | Service registry name the test also lists in Service | ActiveDirectory, Graph, Azure |
Kind | Kind of grant for that service | Ldap, Cim, File, Remoting, Group |
Name | Permission as the product spells it (everything after the second colon) | domainDNS.msDS-Behavior-Version:ReadProperty, SYSVOL:Read, Microsoft.PowerShell |
AND / OR semanticsโ
- Array elements are AND โ the identity needs every element.
- Pipe
|inside an element is OR โ any one alternative is enough, least privileged first.
# Both required
Permission = ('ActiveDirectory:Ldap:user:ReadProperty', 'ActiveDirectory:Ldap:group:ReadProperty')
# Either sufficient
Permission = 'ActiveDirectory:Ldap:domainDNS.name:ReadProperty | ActiveDirectory:Ldap:domainDNS:ReadProperty'
# (One domain attribute OR another) AND group access
Permission = ('ActiveDirectory:Ldap:domainDNS.name:ReadProperty | ActiveDirectory:Ldap:domainDNS:ReadProperty',
'ActiveDirectory:Ldap:group:ReadProperty')
Use parenthesized constant lists ('a', 'b') in the attribute, not @('a', 'b').
Examplesโ
| Test | Permission string | What it means |
|---|---|---|
AD-DOM-01 | ActiveDirectory:Ldap:domainDNS.name:ReadProperty | Read the name attribute on the domainDNS object via LDAP |
AD-DACL-01 | ActiveDirectory:Ldap:*.ntSecurityDescriptor:ReadControl | Read ntSecurityDescriptor (with DACL) on all object classes via LDAP |
AD-GPO-01 | ActiveDirectory:Ldap:groupPolicyContainer.gPCFileSysPath:ReadProperty | Read GPO LDAP metadata |
AD-GPO-01 | ActiveDirectory:File:SYSVOL:Read | Read GPO files from SYSVOL share |
AD-DNS-01 | ActiveDirectory:Cim:root\MicrosoftDNS:MicrosoftDNS_Zone:Read | Read DNS zone data via CIM |
AD-DNS-01 | ActiveDirectory:Remoting:Microsoft.PowerShell | Execute commands via PowerShell remoting endpoint |
AD-DC-02 | ActiveDirectory:Cim:root\Microsoft\Windows\SMB:MSFT_SmbServerConfiguration:Read | Read SMB configuration via CIM |
These are technical permission strings, not human role names. A test that requires ActiveDirectory:Ldap:groupPolicyContainer.gPCFileSysPath:ReadProperty needs the technical ability to read that specific GPO attribute; it does not require membership in a built-in administrative group.
Querying Test Permissionsโ
Every AD test declares its permissions via the [MaesterTest] Permission attribute. You can query them dynamically:
Import-Module Maester -Force
$test = Get-MtTest -Path ./tests/ad/domain/Test.AD-DOM-01.ps1
$test.Permission # outputs: ActiveDirectory:Ldap:domainDNS.name:ReadProperty
Or discover all AD test permissions in bulk:
Get-ChildItem ./tests/ad -Recurse -Filter 'Test.AD-*.ps1' | ForEach-Object {
$test = Get-MtTest -Path $_.FullName
[PSCustomObject]@{
Id = $test.Id
Permissions = $test.Permission -join '; '
}
}
The ADPermissionValidation.Tests.ps1 unit test validates that every AD test's Permission attribute parses without engine errors. Run it to verify the model:
Invoke-Pester ./powershell/tests/general/ADPermissionValidation.Tests.ps1
Active Directory Permission Kindsโ
| Kind | Name format | Example |
|---|---|---|
Ldap | [<partition>/]<objectClass>[.<attribute>]:<right> | ActiveDirectory:Ldap:Configuration/*:ReadProperty |
Cim | <namespace>:<class>:<right> | ActiveDirectory:Cim:root\MicrosoftDNS:MicrosoftDNS_Zone:Read |
File | <share>:<right> | ActiveDirectory:File:SYSVOL:Read |
Remoting | <endpoint> | ActiveDirectory:Remoting:Microsoft.PowerShell |
Group | <group name> | ActiveDirectory:Group:Remote Management Users |
For LDAP, the optional partition is Configuration or Schema; omitted means the domain. objectClass.attribute reads one attribute; omitting .attribute reads all attributes of that object class.
Tests Requiring Elevated Privilegesโ
A standard authenticated user (Domain User) can read most LDAP attributes on most objects via the default security descriptor. The following tests require privileges beyond what a standard Domain User holds by default.
DACL Tests (18 tests)โ
| Tests | Required Permission | Why It Requires Elevation |
|---|---|---|
| AD-DACL-01 through AD-DACL-18 | ActiveDirectory:Ldap:*.ntSecurityDescriptor:ReadControl | Reading the DACL portion of ntSecurityDescriptor is restricted. Standard users can read the owner and group, but not the full DACL. |
DNS Tests (19 tests)โ
| Tests | Required Permissions | Why It Requires Elevation |
|---|---|---|
| AD-DNS-01 through AD-DNS-19 | ActiveDirectory:Cim:root\MicrosoftDNS:MicrosoftDNS_Zone:Read, ActiveDirectory:Remoting:Microsoft.PowerShell | Remote CIM/WMI access and PowerShell remoting both require administrative or specific group membership. |
DC Management Tests (3 tests)โ
| Tests | Required Permissions | Why It Requires Elevation |
|---|---|---|
| AD-DC-02, AD-DC-03, AD-DC-04 | ActiveDirectory:Cim:root\Microsoft\Windows\SMB:MSFT_SmbServerConfiguration:Read, ActiveDirectory:Remoting:Microsoft.PowerShell | Remote CIM access for SMB server configuration and PowerShell remoting execution require elevated access. |
GPO Tests (40 tests)โ
| Tests | Required Permission | Why It May Require Elevation |
|---|---|---|
| AD-GPO-01 through AD-GPO-05, AD-GPOL-01 through AD-GPOL-06, AD-GPOREP-01 through AD-GPOREP-20, AD-GPOS-01 through AD-GPOS-09 | ActiveDirectory:File:SYSVOL:Read | Reading files from the \\domain\SYSVOL share. While Authenticated Users typically receive read access to SYSVOL, this is filesystem access separate from LDAP and may be restricted in hardened environments. |
Summary: 80 of 270 AD tests (30%) require privileges beyond a standard authenticated user. The remaining 190 tests can run with standard Domain User LDAP read access.
Category Summaryโ
| Category | Tests | Required permissions |
|---|---|---|
cfg | AD-CFG-01 through AD-CFG-24 | ActiveDirectory:Ldap:Configuration/*:ReadProperty |
comp | AD-COMP-01 through AD-COMP-10 | ActiveDirectory:Ldap:computer:ReadProperty |
dacl | AD-DACL-01 through AD-DACL-18 | ActiveDirectory:Ldap:*.ntSecurityDescriptor:ReadControl |
dc | AD-DC-01 through AD-DC-08 | ActiveDirectory:Ldap:nTDSDSA:ReadProperty; AD-DC-02 through AD-DC-04 also need ActiveDirectory:Cim:root\Microsoft\Windows\SMB:MSFT_SmbServerConfiguration:Read and ActiveDirectory:Remoting:Microsoft.PowerShell |
dcd | AD-DCD-01 through AD-DCD-04 | ActiveDirectory:Ldap:nTDSDSA:ReadProperty |
dcomp | AD-DCOMP-01 through AD-DCOMP-09 | ActiveDirectory:Ldap:computer:ReadProperty |
dfsr | AD-DFSR-01 | ActiveDirectory:Ldap:domainDNS.distinguishedName:ReadProperty |
dns | AD-DNS-01 through AD-DNS-19 | ActiveDirectory:Cim:root\MicrosoftDNS:MicrosoftDNS_Zone:Read, ActiveDirectory:Remoting:Microsoft.PowerShell |
dom | AD-DOM-01 through AD-DOM-08 | ActiveDirectory:Ldap:domainDNS:ReadProperty |
doms | AD-DOMS-01 | ActiveDirectory:Ldap:domainDNS:ReadProperty |
feat | AD-FEAT-01 through AD-FEAT-02 | ActiveDirectory:Ldap:msDS-OptionalFeature:ReadProperty |
fgpp | AD-FGPP-01 through AD-FGPP-04 | ActiveDirectory:Ldap:msDS-PasswordSettings:ReadProperty |
for | AD-FOR-01 through AD-FOR-04 | ActiveDirectory:Ldap:crossRef:ReadProperty |
fors | AD-FORS-01 through AD-FORS-04 | ActiveDirectory:Ldap:crossRef:ReadProperty |
gchg | AD-GCHG-01 | ActiveDirectory:Ldap:group:ReadProperty |
gmc | AD-GMC-01 through AD-GMC-11 | ActiveDirectory:Ldap:group:ReadProperty; GMC-01 also needs ActiveDirectory:Ldap:group.member:ReadProperty |
gpo | AD-GPO-01 through AD-GPO-05 | ActiveDirectory:Ldap:groupPolicyContainer.gPCFileSysPath:ReadProperty, ActiveDirectory:File:SYSVOL:Read |
gpol | AD-GPOL-01 through AD-GPOL-06 | ActiveDirectory:Ldap:groupPolicyContainer.gPCFileSysPath:ReadProperty, ActiveDirectory:File:SYSVOL:Read |
gporep | AD-GPOREP-01 through AD-GPOREP-20 | ActiveDirectory:Ldap:groupPolicyContainer.gPCFileSysPath:ReadProperty, ActiveDirectory:File:SYSVOL:Read |
gpos | AD-GPOS-01 through AD-GPOS-09 | ActiveDirectory:Ldap:groupPolicyContainer.gPCFileSysPath:ReadProperty, ActiveDirectory:File:SYSVOL:Read |
grp | AD-GRP-01 through AD-GRP-10 | ActiveDirectory:Ldap:group:ReadProperty |
krbtgt | AD-KRBTGT-01 through AD-KRBTGT-03 | ActiveDirectory:Ldap:user:ReadProperty |
msa | AD-MSA-01 | ActiveDirectory:Ldap:msDS-GroupManagedServiceAccount:ReadProperty |
ou | AD-OU-01 through AD-OU-05 | ActiveDirectory:Ldap:organizationalUnit:ReadProperty |
print | AD-PRINT-01 | ActiveDirectory:Ldap:printQueue:ReadProperty |
pwdpol | AD-PWDPOL-01 through AD-PWDPOL-07 | ActiveDirectory:Ldap:domainDNS:ReadProperty |
repl | AD-REPL-01 through AD-REPL-02 | ActiveDirectory:Ldap:nTDSConnection:ReadProperty |
rootdse | AD-ROOTDSE-01 through AD-ROOTDSE-03 | ActiveDirectory:Ldap:domainDNS:ReadProperty |
sch | AD-SCH-01 through AD-SCH-05 | ActiveDirectory:Ldap:attributeSchema:ReadProperty |
site | AD-SITE-01 through AD-SITE-05 | ActiveDirectory:Ldap:site:ReadProperty |
spn | AD-SPN-01 through AD-SPN-13 | ActiveDirectory:Ldap:computer:ReadProperty, ActiveDirectory:Ldap:user:ReadProperty |
sub | AD-SUB-01 through AD-SUB-11 | ActiveDirectory:Ldap:subnet:ReadProperty |
trust | AD-TRUST-01 through AD-TRUST-07 | ActiveDirectory:Ldap:trustedDomain:ReadProperty |
user | AD-USER-01 through AD-USER-29 | ActiveDirectory:Ldap:user:ReadProperty |
Known Misleading Outcomesโ
The following behaviors can hide incomplete access. They are documented here so operators do not misinterpret empty or partial results as proof of a clean configuration.
DACL tests (AD-DACL-*)โ
Get-MtLdapDacl delegates to Invoke-MtLdapSearch and returns an empty array when no entries match. An empty result is indistinguishable from insufficient access. Tests set $testResult = $true even when the array is empty, so a pass does not prove the DACL was fully read.
GPO tests (AD-GPO-, AD-GPOL-, AD-GPOREP-, AD-GPOS-)โ
Get-MtADGpoState can return a non-null state with an empty GPO array. A non-null check therefore does not establish that GPO data was retrieved. GPO reads also depend on SMB/SYSVOL file access; an LDAP probe alone does not prove policy files were read.
DNS tests (AD-DNS-*)โ
If Invoke-MtADManagementCommand fails, the DNS category collector throws. Get-MtADDomainState catches the failure and leaves DNS arrays empty. The helper then skips with NotConnectedActiveDirectoryDNS, which does not distinguish "server has no data" from "query could not retrieve data."
Configuration tests (AD-CFG-*)โ
Get-MtLdapConfigurationContainer catches individual query errors. The state object survives with empty arrays or null properties even when subqueries did not return data.
Transport and cacheโ
WinRM HTTPS-to-HTTP Negotiate fallback (commit ca74fc79) means a successful management result may have used HTTP; it does not prove the HTTPS listener or certificate was validated. Get-MtADGpoState caches by resolved domain and may reuse state across DCs. The target-scoped Get-MtADDomainState cache includes resolved target identity. Do not assume all scoped collections share unscoped data.
This documents current behavior, not a future enforcement model. Tests do not consistently emit LimitedPermissions or NotAuthorized when access is insufficient. A pass, skip, empty collection, or null result must be interpreted with the specific test's known ambiguity in view.