Effective Access Active Directory Object Using PowerShell

Viewed 2275

I am trying to get effective permissions of certain active directory users on various Active Directory objects. I can see these permissions from the UI - enter image description here

I am trying to get this using Powershell. I have already tried dsacls and Get-Acls but these don't give effective permissions. These both give "who has access/permissions" which is not the same as "who has what effective permissions". These also don't list out all the granular details that would provide context around the effective access.

Any pointers on how this can be achieved programmatically would be really appreciated.

Update -

Effective permissions here would mean which permissions are allowed to the object in reality based on inheritances or other rules set at a different level.

For example -

All the properties in the below example are not visible with Get-ACL. enter image description here

Another example of what Get-Acl shows while the UI tells differently is when I pulled permissions for domain admins on one of the OUs via Get-ACL , after resolving the values in ObjectType and InheritedObjectType (use get-effective access function mentioned by Santiago Squarzon) I get -

enter image description here

While the UI effective access shows-

enter image description here

My end goal is to get all the permission in the above screenshot using powershell.

2 Answers

This is pretty close to what you're looking for. Source for more details. Access Control Lists with Get-ACL are not as easy to read as Effective Access on Advanced Security Settings and I don't think there is a way around that. I do think that, once used to it, Get-ACL gives a lot more details when you know what you're looking for \ filter the ACLs to get what you're looking for.

Code

function Get-EffectiveAccess {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidatePattern('(?:(CN=([^,]*)),)?(?:((?:(?:CN|OU)=[^,]+,?)+),)?((?:DC=[^,]+,?)+)$')]
        [alias('DistinguishedName')]
        [string] $Identity,

        [parameter()]
        [alias('Domain')]
        [string] $Server
    )

    begin {
        $guid    = [guid]::Empty
        $GUIDMap = @{}

        if($PSBoundParameters.ContainsKey('Server')) {
            $domain = Get-ADRootDSE -Server $Server
        }
        else {
            $domain = Get-ADRootDSE
        }

        $params = @{
            SearchBase  = $domain.schemaNamingContext
            LDAPFilter  = '(schemaIDGUID=*)'
            Properties  = 'name', 'schemaIDGUID'
            ErrorAction = 'SilentlyContinue'
        }
        $adObjParams = @{
            Properties = 'nTSecurityDescriptor'
        }

        if($PSBoundParameters.ContainsKey('Server')) {
            $params['Server']  = $Server
            $adObjParams['Server'] = $Server
        }
        $schemaIDs = Get-ADObject @params

        $params['SearchBase'] = "CN=Extended-Rights,$($domain.configurationNamingContext)"
        $params['LDAPFilter'] = '(objectClass=controlAccessRight)'
        $params['Properties'] = 'name', 'rightsGUID'
        $extendedRigths = Get-ADObject @params

        foreach($i in $schemaIDs) {
            if(-not $GUIDMap.ContainsKey([guid] $i.schemaIDGUID)) {
                $GUIDMap.Add([guid] $i.schemaIDGUID, $i.name)
            }
        }
        foreach($i in $extendedRigths) {
            if(-not $GUIDMap.ContainsKey([guid] $i.rightsGUID)) {
                $GUIDMap.Add([guid] $i.rightsGUID, $i.name)
            }
        }
    }

    process {
        try {
            $adObjParams['Identity'] = $Identity
            $object = Get-ADObject @adObjParams

            foreach($acl in $object.nTSecurityDescriptor.Access) {
                if($guid.Equals($acl.ObjectType)) {
                    $objectType = 'All Objects (Full Control)'
                }
                elseif($GUIDMap.ContainsKey($acl.ObjectType)) {
                    $objectType = $GUIDMap[$acl.ObjectType]
                }
                else {
                    $objectType = $acl.ObjectType
                }

                if($guid.Equals($acl.InheritedObjectType)) {
                    $inheritedObjType = 'Applied to Any Inherited Object'
                }
                elseif($GUIDMap.ContainsKey($acl.InheritedObjectType)) {
                    $inheritedObjType = $GUIDMap[$acl.InheritedObjectType]
                }
                else {
                    $inheritedObjType = $acl.InheritedObjectType
                }

                [PSCustomObject]@{
                    Name                  = $object.Name
                    IdentityReference     = $acl.IdentityReference
                    AccessControlType     = $acl.AccessControlType
                    ActiveDirectoryRights = $acl.ActiveDirectoryRights
                    ObjectType            = $objectType
                    InheritedObjectType   = $inheritedObjType
                    InheritanceType       = $acl.InheritanceType
                    IsInherited           = $acl.IsInherited
                }
            }
        }
        catch {
            $PSCmdlet.WriteError($_)
        }
    }
}

Examples

  • Get the Effective Access of the Organizational Unit named ExampleOU:
Get-ADOrganizationalUnit -Filter "Name -eq 'ExampleOU'" |
    Get-EffectiveAccess | Out-GridView
  • Get the Effective Access of the Organizational Unit named ExampleOU on a Trusted Domain:
Get-ADOrganizationalUnit -Filter "Name -eq 'ExampleOU'" -Server trustedDomain |
    Get-EffectiveAccess -Server trustedDomain | Out-GridView
  • Same as above but using the OU's DistinguishedName attribute:
Get-EffectiveAccess -Identity 'OU=ExampleOU,DC=domainName,DC=com' | Out-GridView
  • Store the Effective Access of the group named exampleGroup in a variable:
$effectiveAccess = Get-ADGroup exampleGroup | Get-EffectiveAccess
  • Get the Effective Access of the first 10 OUs found in the Domain:
Get-ADOrganizationalUnit -Filter * | Select -First 10 |
    Get-EffectiveAccess | Out-GridView

Sample

For reference, this is how Full Control looks like with Get-ACL

fullcontrol

Compared with BUILTIN\Administrators which has write permissions on this OU but not Full Control

writepermissions

You can try PowerShellAccessControl module I think the details for this module are covered in this youtube video with the function Get-EffectiveAccess. This should help you get the information. The module has been deleted from the Microsoft's PS Gallery. I am not sure how you might be able to install the module from Github, I couldn't try it as I am working with a Mac.

Related