PowerShell/Community-Blog

Understanding Active Directory ACL via PowerShell

farismalaeb opened this issue · 8 comments

Summary of the new document or enhancement

Details of requested document:

  • Are you offering to write the post [Y/N]: Y
  • Proposed title: Understanding Active Directory ACL via PowerShell
  • Links to related posts:
  • Description of the problem/scenario/question you want covered: Understanding how to get and read Active Directory ACL and what are the ObjectGUID mean when running Get-ACL against an Active Directory object. This post will focus on explaining the permission name and how to resolve the permission GUID to name as its not much available on the internet and whats available is not clear.

Seems an interesting post.

Some comments/suggestions.
I suggest you spend some time creating a 2-3 level outline. ACLs and AD could be a pretty broad subject, so start with an outline of what we can expect from this article.

What cmdlets are you planning to use? I am not aware of any specific AD ACL cmdlets - so you will, I am guessing, going to be dipping down into .NET. Are there any 3rd party cmdlets you can use?

What is the use case for what this article covers? What problem are you trying to solve and why should an IT Professional care about getting AD ACLs.

And finally, I hope there will be some warnings. I know all too well, erroneous automation can be painful!

So let's see the outline and the article! And thanks for offering to do another article,.

Hi.
This post will explain how to use the Get-ACL to query Active Directory ACL basic and explain the different returns.
Most of the time in AD the permission are referenced by GUID when its an ExtendedRight, similar to the following return

ActiveDirectoryRights : ReadProperty, WriteProperty, ExtendedRight
InheritanceType : All
ObjectType : 91e647de-d96f-4b70-9557-d63ff4f3ccd8
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SELF
IsInherited : True
InheritanceFlags : ContainerInherit
PropagationFlags : None

The post should explain to each one what does it mean, and what is the ObjectType and InheritedObjectType... when they are all zero and why

This post should give the AD administrator a great understanding of what the permission is and how to filter the permissions as needed.

I am assuming you are using the AD: drive and the provider extension for Get-ACL?

You need to explain the System.DirectoryServices.ActiveDirectorySecurity object. Since there are no cmdlets in the AD modules to support ACLs, presumably one uses the methods to do useful things?

Let's see the outline to H3 level and a first draft.

Thanks for doing this post.

Yes,
the plan is to explain the Get-ACL with the AD: drive result.
but its OK to include some about System.DirectoryService.ActiveSe..

Hi
This is a quick look.
should I submit a pull request?


post_title: Understanding Get-ACL and AD Drive Output
username: farisnt@gmail.com
Categories: PowerShell
tags: PowerShell, Active Directory, ACL
Summary: Understanding Get-ACL and AD Drive Output

Understanding Get-ACL and AD: Drive Output

Understanding Active Directory ACL using PowerShell can be a bit tricky.
There are no out-of-the-box cmdlets with ActiveDirectory PowerShell module to help in settings the permission quickly.
This may be due to the nature of permission and how the relationship between objects and subjects.

In this post, I will try to simplify Active Directory ACL and how to read the result easily, So let's start.

Prerequisites

To follow along with this article, you need the following:

  • PowerShell 7. x or Windows PowerShell 5.1
  • Domain Admin permission.
  • Windows Server 2012, 2016, or 2019 with Active Directory Domain Service role installed.

The domain name used for this tutorial is Test.local.

Reading Active Directory Permission using Get-ACL

Reading Active Directory permission using Get-ACL doesn't require a long line of code.
Still, since we are reading from Active Directory and not from a flat file, we need to use the Active Directory drive AD: which automatically loaded when importing the ActiveDirectory PowerShell module.

Also, the path format used to query objects is the Distinguished Name for the AD object.
To get the ACL for the MyOrgOU organization unit in the Test.local using the following line.

(Get-Acl -Path "AD:OU=MyOrgOU,DC=Test,DC=local").Access

ActiveDirectoryRights : CreateChild, DeleteChild
InheritanceType       : None
ObjectType            : bf967aba-0de6-11d0-a285-00aa003049e2
InheritedObjectType   : 00000000-0000-0000-0000-000000000000
ObjectFlags           : ObjectAceTypePresent
AccessControlType     : Allow
IdentityReference     : BUILTIN\\Account Operators
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None
.
.
Output Trimmed to make the result clear.

As the output shows, there are multiple properties, but not that clear.
You can tell from the first view is that there is a CreateChild and DeleteChild permission assigned to the BUILTIN\Account Operators.
But on which object (User, Computer...etc) and which AD attribute?
Let's take another example.
A user named User1 was assigned permission on MyOrgOU organizational unit by another administrator.
Using the Get-ACL cmdlet, return the following results.

(Get-Acl -Path "AD:OU=MyOrgOU,DC=Test,DC=local").Access | Where-Object {$_.IdentityReference -Like "Test\\User1"}

ActiveDirectoryRights : WriteProperty
InheritanceType       : Descendents
ObjectType            : 28630ebf-41d5-11d1-a9c1-0000f80367c1
InheritedObjectType   : bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags           : ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType     : Allow
IdentityReference     : TEST\\User1
IsInherited           : False
InheritanceFlags      : ContainerInherit
PropagationFlags      : InheritOnly

Same as the first case, the question is what Test\User1 actually has permission to do?

Understanding the Get-ACL and AD Drive Output

To make things easier, let's start by understanding each property of the output and what does it mean.

Understanding the ActiveDirectoryRights Property

  • ActiveDirectoryRights: The ActiveDirectoryRights refer to what rights are assigned to the AD object;
    usually, this is readable, like WriteProperty, DeleteProperty.
    But this is not always the case.
    The ActiveDirectoryRights can also hold ExtendedRights, Generic, and other values.

Note

You can read more about ActiveDirectoryRights on the ActiveDirectoryRights page.

  • The ExtendedRight flag means permission is set to a very specific AD object attribute, such as setting the write pwdLastSet to a AD user object attribute.
    Customized property permission = ExtendedRights in ActiveDirectoryRights
  • Generic: Some generic permission values include
    • GenericAll: Equivalent to Full Control, so the user with GenericAll has full control permission on the object.
    • GenericRead: Can read all object properties and permission and list content if its a container or OU.
    • GenericWrite: Can write to all object's properties and permission.

Understanding the InheritanceType Property

The InheritanceType shows the scope of the applied permission and define which AD objects should the AEC applied to.
You can see the InheritanceType in the ACL GUI in the Advance Security Permission Window.

Applies to
The InheritanceType can hold one of the following values:
- None: The permission is applied to the object where the permission is set.
The Applies to is set to This Object Only
- All: The permission is applied to the object where the permission is set and all the child items in the tree.
The Applies to is set to This object and all descendant objects.
- Descendents: The permission is applied to child items only but not to the object where the permission is set.
The Applies to is set to All descendant objects.
Think of OU1 and a child OU2.
User1 has the following permission on OU1

    (Get-Acl -Path "AD:OU=OU1,DC=Test,DC=local").Access | Where-Object {($_.IdentityReference -Like "*User1*")}

    ActiveDirectoryRights : GenericAll
    InheritanceType       : Descendents
    ObjectType            : 00000000-0000-0000-0000-000000000000
    InheritedObjectType   : 00000000-0000-0000-0000-000000000000
    ObjectFlags           : None
    AccessControlType     : Allow
    IdentityReference     : TEST\\User1
    IsInherited           : False
    InheritanceFlags      : ContainerInherit
    PropagationFlags      : InheritOnly

User1 can perform an action on OU2 and OU1 child items but not on the OU1 object.

  • Children: set permissions on the direct child only, not the on the object itself neither any descendants object of its children.
    You get this value when the Applies to set to any value other than This object only or This object and all descendant objects and at the same time the Only apply this permission to objects and/or containers within this container check box is selected.
  • SelfAndChildren: Set permissions on the object itself where the permission is placed and the direct child only.
    You get this value when the Applies to set to value This object and all descendant objects and at the same time the Only apply this permission to objects and/or containers within this container check box is selected.

Understanding the ObjectType Property

The ObjectType is represented by a GUID value, even though this is one of the most important values that should be clear.
The output of Get-ACL makes it complex to understand.
The ObjectType is the object attribute. For example

In the following output, User1 is Allowed to WriteProperty to object 28630ebf-41d5-11d1-a9c1-0000f80367c1.

(Get-Acl -Path "AD:OU=MyOrgOU,DC=Test,DC=local").Access | where-Object {$_.IdentityReference -Like "Test\\user1"}

ActiveDirectoryRights : WriteProperty
InheritanceType       : Descendents
ObjectType            : 28630ebf-41d5-11d1-a9c1-0000f80367c1
InheritedObjectType   : bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags           : ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType     : Allow
IdentityReference     : TEST\\User1
IsInherited           : False
InheritanceFlags      : ContainerInherit
PropagationFlags      : InheritOnly

To resolve this GUID to a name we need to see where these GUID are stored.

To get the list of ObjectType names, run the following PowerShell code

$ObjectTypeGUID = @{}
(Get-ADObject -SearchBase (Get-ADRootDSE).SchemaNamingContext -LDAPFilter '(SchemaIDGUID=*)' -Properties Name, SchemaIDGUID).ForEach({$ObjectTypeGUID.Add([GUID]$_.SchemaIDGUID,$_.Name)})
(Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" -LDAPFilter '(ObjectClass=ControlAccessRight)' -Properties Name, RightsGUID).ForEach({$ObjectTypeGUID.Add([GUID]$_.RightsGUID,$_.Name)})
$ObjectTypeGUID | Format-Table -AutoSize

Take a look at the output, you see that there is the ObjectType GUID and the Name what an ObjectType GUID.

Name                                 Value                                                           
----                                 -----                                                           
a8032e74-30ef-4ff5-affc-0fc217783fec NisNetgroupTriple                                               
5b7eae84-7e67-4d56-8fca-9cee24d19a65 ms-Exch-Policy-Tag-Link                                         
5245803a-ca6a-11d0-afff-0000f80367c1 NTFRS-Replica-Set                                               
52458038-ca6a-11d0-afff-0000f80367c1 Admin-Property-Pages                                            
52458039-ca6a-11d0-afff-0000f80367c1 Shell-Property-Pages                                            
296de070-b098-11d2-aa06-00c04f8eedd8 ms-Exch-Server2-Page-Size                                       
203d2f32-b099-11d2-aa06-00c04f8eedd8 ms-Exch-Source-BH-Address                                       
b8d47e4e-4b78-11d3-aa75-00c04f8eedd8 ms-Exch-Security-Password                                       
b8fe00a9-8e59-4d4d-8939-85b79de4d8cf ms-Exch-Provisioning-Flags                                      
4d7ea1cd-43a0-4255-9bb0-12f17be23ffb ms-Exch-ESE-Param-Replay-Background-Database-Maintenance-Delay  
2dbb448a-5d85-4144-a9a5-2fc724e194a8 ms-Exch-Auto-Discover-Flags                                     
e85e1204-3434-41ad-9b56-e2901228fff0 MS-DRM-Identity-Certificate                                     
28630ebf-41d5-11d1-a9c1-0000f80367c1 Lockout-Time                                                    
28630ebe-41d5-11d1-a9c1-0000f80367c1 Is-Defunct                                                      
28630ebd-41d5-11d1-a9c1-0000f80367c1 Tree-Name                                                       
28630ebc-41d5-11d1-a9c1-0000f80367c1 Legacy-Exchange-DN                                              
2d485eee-45e1-4902-add1-5630d25d13c2 ms-Exch-UM-Enabled-Flags                                        
28630eba-41d5-11d1-a9c1-0000f80367c1 Service-DNS-Name-Type

So if you have an ObjectType GUID, you can search through the hashtable, and as you can see below, the ObjectType GUID is Lockout-Time

$ObjectTypeGUID[[GUID]'28630ebf-41d5-11d1-a9c1-0000f80367c1']
Lockout-Time

![Note]
Looking to know more about Hashtable, read this great post on Everything you wanted to know about hashtables

From the previous example and after understanding the ObjectType value, we know that Test\User1 is Allowed to WrtiteProperty to Lockout-Time property

Note

One side note, if the value of the ObjectType was 00000000-0000-0000-0000-000000000000 this means that the user is allowed//denied to all properties, not a specific one.

Understanding InheritedObjectType Property

The InheritedObjectType GUID represents the targeted object such as a Computer, User, Contact...etc., For example, when delegating the Helpdesk to unlock user's account, the InheritedObjectType value is User which the GUID of bf967aba-0de6-11d0-a285-00aa003049e2 represents.
You can see the value in the GUI from here

User Object

Understanding IsInherited, InheritanceFlags, and PropagationFlags

The Inheritance and how the object is inherited to the child object defined by three properties:

  • IsInherited: Object is inherited from a parent object, and the possible values are true or false
  • InheritanceFlags: Two values this flag can have are:
    • None: The ACE won't inherit to the child items. It's only applied to the object it's set to.
    • ContainerInherit: The ACE is inherited to the child items.
  • PropagationFlags: control how the ACE is propagated to the child items, and the possible values are:
    • None: Specifies that no inheritance flags are set.
    • InheritOnly: The ACE is applied to the child items only, not the object where the ACE is set.
    • NoPropagateInherit: The ACE is applied on the object where the ACE is set not propagated to any child.
      You can see this value when the Only Apply this permission to objects and/or containers within this container is selected.

Apply to This Container only

Keep in mind that the PropagationFlags are significant only if inheritance flags are present.
In this post, I try to simplify the Get-ACL output result as it helps in better understanding the permission structure through PowerShell.

Dear
I had created the PR, I updated most of the points, and sure there is still more to fix which can be revealed by your review.
Thanks for your time

Published and closed.