{"id":486,"date":"2021-09-30T08:05:16","date_gmt":"2021-09-30T15:05:16","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/powershell-community\/?p=486"},"modified":"2021-09-30T08:09:11","modified_gmt":"2021-09-30T15:09:11","slug":"understanding-get-acl-and-ad-drive-output","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell-community\/understanding-get-acl-and-ad-drive-output\/","title":{"rendered":"Understanding Get-ACL and AD Drive Output"},"content":{"rendered":"<p>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. While there are no cmdlets, you can nevertheless manage AD permissions using the AD PowerShell drive.<\/p>\n<p>In this post, I will try to simplify Active Directory ACL and how to read the result easily, so let&#8217;s start.<\/p>\n<h2>Prerequisites<\/h2>\n<p>To follow along with this article, you need the following:<\/p>\n<ul>\n<li>PowerShell 7. x or Windows PowerShell 5.1<\/li>\n<li>A user account that is member of Domain Admin AD Group.<\/li>\n<li>Windows Server 2012, 2016, 2019 or 2022 with Active Directory Domain Service role installed and participating in a domain.<\/li>\n<\/ul>\n<p>The domain name used for this tutorial is <strong>Contoso.com<\/strong>.<\/p>\n<h2>Reading Active Directory Permission using Get-ACL<\/h2>\n<p>Reading Active Directory permission using\u00a0<code>Get-ACL<\/code>\u00a0doesn&#8217;t require a long line of code. However, we are reading from AD and not the FileSystem provider. So we use the <code>AD:<\/code> drive. This drive is automatically loaded when you load the ActiveDirectory module.<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Note<\/strong><\/p>To import Active Directory Module, use the <code>Import-Module ActiveDirectory<\/code>.<\/div><\/p>\n<p>When you query for an object to get its ACL, you need to search based on <strong>Distinguished Name<\/strong>. Use the following statement to get the ACL for the\u00a0<strong>MyOrgOU<\/strong>\u00a0organization unit in the\u00a0<strong>Contoso.com<\/strong>.<\/p>\n<pre><code class=\"language-powershell-console\">PS&gt; (Get-Acl -Path \"AD:OU=MyOrgOU,DC=Contoso,DC=com\").Access\n\nActiveDirectoryRights : CreateChild, DeleteChild\nInheritanceType       : None\nObjectType            : bf967aba-0de6-11d0-a285-00aa003049e2\nInheritedObjectType   : 00000000-0000-0000-0000-000000000000\nObjectFlags           : ObjectAceTypePresent\nAccessControlType     : Allow\nIdentityReference     : BUILTIN\\Account Operators\nIsInherited           : False\nInheritanceFlags      : None\nPropagationFlags      : None\n...\n<\/code><\/pre>\n<p>Output Trimmed to make the result clear.<\/p>\n<p>As the output shows, there are multiple properties, but some are not obvious in terms of their usage. You can tell from the first view is that there is a <strong>CreateChild<\/strong> and <strong>DeleteChild<\/strong> permission assigned to the <strong>BUILTINAccount Operators<\/strong>. But on which object (User, Computer&#8230;etc) and which AD attribute? Let&#8217;s take another example. You created user <strong>User1<\/strong> and assigned permission on <strong>MyOrgOU<\/strong> organizational unit by another administrator. Using the <code>Get-ACL<\/code> cmdlet, return the following results.<\/p>\n<pre><code class=\"language-powershell-console\">PS&gt; (Get-Acl -Path \"AD:OU=MyOrgOU,DC=Contoso,DC=Com\").Access | Where-Object {$_.IdentityReference -Like \"Contoso\\User1\"}\n\nActiveDirectoryRights : WriteProperty\nInheritanceType       : Descendents\nObjectType            : 28630ebf-41d5-11d1-a9c1-0000f80367c1\nInheritedObjectType   : bf967aba-0de6-11d0-a285-00aa003049e2\nObjectFlags           : ObjectAceTypePresent, InheritedObjectAceTypePresent\nAccessControlType     : Allow\nIdentityReference     : Contoso\\User1\nIsInherited           : False\nInheritanceFlags      : ContainerInherit\nPropagationFlags      : InheritOnly<\/code><\/pre>\n<p>Same as the first case, the question is what <strong>ContosoUser1<\/strong> actually has permission to do?<\/p>\n<h2>Understanding the Get-ACL and AD Drive Output<\/h2>\n<p>To make things easier, let&#8217;s start by understanding each property of the output and what that property does..<\/p>\n<h3>Understanding the ActiveDirectoryRights Property<\/h3>\n<ul>\n<li><strong>ActiveDirectoryRights<\/strong>: The <strong>ActiveDirectoryRights<\/strong> refer to what rights are assigned to the AD object; usually, this is readable, like <strong>WriteProperty<\/strong>, <strong>DeleteProperty<\/strong>. But this is not always the case. The <strong>ActiveDirectoryRights<\/strong> can also hold <strong>ExtendedRights<\/strong>, <strong>Generic<\/strong>, and other values.<\/li>\n<\/ul>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Note<\/strong><\/p>You can read more about <strong>ActiveDirectoryRights<\/strong> on the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.directoryservices.activedirectoryrights?view=net-5.0\">ActiveDirectoryRights<\/a> page.<\/div><\/p>\n<ul>\n<li>The <strong>ExtendedRight<\/strong> flag means permission is set to a very specific AD object attribute, such as setting the write <em>pwdLastSet<\/em> to a AD user object attribute. <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2021\/09\/ExtADPermission.png\" alt=\"Customized property permission = ExtendedRights in ActiveDirectoryRights\" \/><\/li>\n<li><strong>Generic<\/strong>: Some generic permission values include \n<ul>\n<li><strong>GenericAll<\/strong>: Equivalent to Full Control, so the user with <em>GenericAll<\/em> has full control permission on the object.<\/li>\n<li><strong>GenericRead<\/strong>: Can read all object properties and permission and list content if its a container or OU.<\/li>\n<li><strong>GenericWrite<\/strong>: Can write to all object&#8217;s properties and permission.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Understanding the InheritanceType Property<\/h2>\n<p>The <strong>InheritanceType<\/strong> shows the scope of the applied permission and defines which AD objects the ACE should be applied to. You can see the <strong>InheritanceType<\/strong> in the ACL GUI in the Advance Security Permission Window.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2021\/09\/InheritanceType_In_GUI.png\" alt=\"Applies to\" \/> The <strong>InheritanceType<\/strong> can hold one of the following values:<\/p>\n<ul>\n<li><strong>None<\/strong>: The permission is applied to the object where the permission is set. The <strong>Applies to<\/strong> is set to <strong>This Object Only<\/strong><\/li>\n<li><strong>All<\/strong>: The permission is applied to the object where the permission is set and all the child items in the tree. The <strong>Applies to<\/strong> is set to <strong>This object and all descendant objects<\/strong>.<\/li>\n<li><strong>Descendents<\/strong>: The permission is applied to child items only but not to the object where the permission is set. The <strong>Applies to<\/strong> is set to <strong>All descendant objects<\/strong>. Think of <strong>OU1<\/strong> and a child <strong>OU2<\/strong>. <strong>User1<\/strong> has the following permission on <strong>OU1<\/strong><\/li>\n<\/ul>\n<pre><code class=\"language-powershell-console\">    PS&gt; (Get-Acl -Path \"AD:OU=OU1,DC=Contoso,DC=Com\").Access | Where-Object {($_.IdentityReference -Like \"*User1*\")}\n\n    ActiveDirectoryRights : GenericAll\n    InheritanceType       : Descendents\n    ObjectType            : 00000000-0000-0000-0000-000000000000\n    InheritedObjectType   : 00000000-0000-0000-0000-000000000000\n    ObjectFlags           : None\n    AccessControlType     : Allow\n    IdentityReference     : Contoso\\User1\n    IsInherited           : False\n    InheritanceFlags      : ContainerInherit\n    PropagationFlags      : InheritOnly<\/code><\/pre>\n<p>User1 can perform an action on <strong>OU2<\/strong> and <strong>OU1<\/strong> child items but not on the <strong>OU1<\/strong> object.<\/p>\n<ul>\n<li><strong>Children<\/strong>: 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 <strong>Applies to<\/strong> set to any value other than <strong>This object only<\/strong> or <strong>This object and all descendant objects<\/strong> and at the same time the <strong>Only apply this permission to objects and\/or containers within this container<\/strong> check box is selected.<\/li>\n<li><strong>SelfAndChildren<\/strong>: Set permissions on the object itself where the permission is placed and the direct child only. You get this value when the <strong>Applies to<\/strong> set to value <strong>This object and all descendant objects<\/strong> and at the same time the <strong>Only apply this permission to objects and\/or containers within this container<\/strong> check box is selected.<\/li>\n<\/ul>\n<h3>Understanding the ObjectType Property<\/h3>\n<p>The <strong>ObjectType<\/strong> is represented by a GUID value, even though this is one of the most important values that should be clear. The output of <code>Get-ACL<\/code> makes it complex to understand. The <strong>ObjectType<\/strong> is the object attribute. For example, in the following output, <strong>User1<\/strong> is <strong>Allowed<\/strong> to <strong>WriteProperty<\/strong> to object <strong>28630ebf-41d5-11d1-a9c1-0000f80367c1<\/strong>.<\/p>\n<pre><code class=\"language-powershell-console\">PS&gt; (Get-Acl -Path \"AD:OU=MyOrgOU,DC=Contoso,DC=Com\").Access | where-Object {$_.IdentityReference -Like \"Contoso\\user1\"}\n\nActiveDirectoryRights : WriteProperty\nInheritanceType       : Descendents\nObjectType            : 28630ebf-41d5-11d1-a9c1-0000f80367c1\nInheritedObjectType   : bf967aba-0de6-11d0-a285-00aa003049e2\nObjectFlags           : ObjectAceTypePresent, InheritedObjectAceTypePresent\nAccessControlType     : Allow\nIdentityReference     : Contoso\\User1\nIsInherited           : False\nInheritanceFlags      : ContainerInherit\nPropagationFlags      : InheritOnly<\/code><\/pre>\n<p>To resolve this GUID to a name we need to see where these GUIDs are stored.<\/p>\n<p>To get the list of <em>ObjectType<\/em> names, run the following PowerShell code<\/p>\n<pre><code class=\"language-powershell\">$ObjectTypeGUID = @{}\n\n$GetADObjectParameter=@{\n    SearchBase=(Get-ADRootDSE).SchemaNamingContext\n    LDAPFilter='(SchemaIDGUID=*)'\n    Properties=@(\"Name\", \"SchemaIDGUID\")\n}\n\n$SchGUID=Get-ADObject @GetADObjectParameter\n    Foreach ($SchemaItem in $SchGUID){\n    $ObjectTypeGUID.Add([GUID]$SchemaItem.SchemaIDGUID,$SchemaItem.Name)\n}\n\n$ADObjExtPar=@{\n    SearchBase=\"CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)\"\n    LDAPFilter='(ObjectClass=ControlAccessRight)'\n    Properties=@(\"Name\", \"RightsGUID\")\n}\n\n$SchExtGUID=Get-ADObject @ADObjExtPar\n    ForEach($SchExtItem in $SchExtGUID){\n    $ObjectTypeGUID.Add([GUID]$SchExtItem.RightsGUID,$SchExtItem.Name)\n}\n\n$ObjectTypeGUID | Format-Table -AutoSize<\/code><\/pre>\n<p>Take a look at the output, you see that there is the ObjectType GUID and the Name what an ObjectType GUID.<\/p>\n<pre><code class=\"language-powershell-console\">Name                                 Value                                                           \n----                                 -----                                                           \na8032e74-30ef-4ff5-affc-0fc217783fec NisNetgroupTriple                                               \n5b7eae84-7e67-4d56-8fca-9cee24d19a65 ms-Exch-Policy-Tag-Link                                         \n5245803a-ca6a-11d0-afff-0000f80367c1 NTFRS-Replica-Set                                               \n52458038-ca6a-11d0-afff-0000f80367c1 Admin-Property-Pages                                            \n52458039-ca6a-11d0-afff-0000f80367c1 Shell-Property-Pages                                            \n296de070-b098-11d2-aa06-00c04f8eedd8 ms-Exch-Server2-Page-Size                                       \n203d2f32-b099-11d2-aa06-00c04f8eedd8 ms-Exch-Source-BH-Address                                       \nb8d47e4e-4b78-11d3-aa75-00c04f8eedd8 ms-Exch-Security-Password                                       \nb8fe00a9-8e59-4d4d-8939-85b79de4d8cf ms-Exch-Provisioning-Flags                                      \n4d7ea1cd-43a0-4255-9bb0-12f17be23ffb ms-Exch-ESE-Param-Replay-Background-Database-Maintenance-Delay  \n2dbb448a-5d85-4144-a9a5-2fc724e194a8 ms-Exch-Auto-Discover-Flags                                     \ne85e1204-3434-41ad-9b56-e2901228fff0 MS-DRM-Identity-Certificate                                     \n28630ebf-41d5-11d1-a9c1-0000f80367c1 Lockout-Time                                                    \n28630ebe-41d5-11d1-a9c1-0000f80367c1 Is-Defunct                                                      \n28630ebd-41d5-11d1-a9c1-0000f80367c1 Tree-Name                                                       \n28630ebc-41d5-11d1-a9c1-0000f80367c1 Legacy-Exchange-DN                                              \n2d485eee-45e1-4902-add1-5630d25d13c2 ms-Exch-UM-Enabled-Flags                                        \n28630eba-41d5-11d1-a9c1-0000f80367c1 Service-DNS-Name-Type<\/code><\/pre>\n<p>So if you have an <strong>ObjectType<\/strong> GUID, you can search through the hashtable, and as you can see below, the <strong>ObjectType<\/strong> GUID is <strong>Lockout-Time<\/strong><\/p>\n<pre><code class=\"language-powershell-console\">PS&gt; $ObjectTypeGUID[[GUID]'28630ebf-41d5-11d1-a9c1-0000f80367c1']\nLockout-Time<\/code><\/pre>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Note<\/strong><\/p>If you want to know more about Hashtables, read this great post on <a href=\"https:\/\/docs.microsoft.com\/en-us\/powershell\/scripting\/learn\/deep-dives\/everything-about-hashtable?view=powershell-7.1\">Everything you wanted to know about hashtables<\/a><\/div><\/p>\n<p>From the previous example and after understanding the <strong>ObjectType<\/strong> value, we know that <strong>ContosoUser1<\/strong> is <strong>Allowed* to *WrtiteProperty<\/strong> to <strong>Lockout-Time<\/strong> property<\/p>\n<p><div class=\"alert alert-primary\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Note<\/strong><\/p>One side note, if the value of the <strong>ObjectType<\/strong> was 00000000-0000-0000-0000-000000000000 this means that the user is allowed\/\/denied to all properties, not a specific one.<\/div><\/p>\n<h2>Understanding InheritedObjectType Property<\/h2>\n<p>The <strong>InheritedObjectType<\/strong> GUID represents the targeted object such as a <strong>Computer<\/strong>, <strong>User<\/strong>, <strong>Contact<\/strong>&#8230;etc., For example, when delegating the Helpdesk to unlock user&#8217;s account, the <strong>InheritedObjectType<\/strong> value is <strong>User<\/strong> which the GUID of <strong>bf967aba-0de6-11d0-a285-00aa003049e2<\/strong> represents. You can see the value in the GUI from here<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2021\/09\/InheritedObjectType.png\" alt=\"User Object\" \/><\/p>\n<h2>Understanding IsInherited, InheritanceFlags, and PropagationFlags<\/h2>\n<p>The Inheritance and how the object is inherited to the child object defined by three properties:<\/p>\n<ul>\n<li><strong>IsInherited<\/strong>: Object is inherited from a parent object, and the possible values are true or false.<\/li>\n<li>\n<p><strong>InheritanceFlags<\/strong>: Two values this flag can have are:<\/p>\n<ul>\n<li><strong>None<\/strong>: The ACE won&#8217;t inherit to the child items. It&#8217;s only applied to the object it&#8217;s set to.<\/li>\n<li><strong>ContainerInherit<\/strong>: The ACE is inherited to the child items.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.security.accesscontrol.propagationflags?view=net-5.0\">PropagationFlags<\/a><\/strong>: control how the ACE is propagated to the child items, and the possible values are:<\/p>\n<ul>\n<li><strong>None<\/strong>: Specifies that no inheritance flags are set.<\/li>\n<li><strong>InheritOnly<\/strong>: The ACE is applied to the child items only, not the object where the ACE is set.<\/li>\n<li><strong>NoPropagateInherit<\/strong>: The ACE is applied on the object where the ACE is set not propagated to any child. You can see this value when the <em>Only Apply this permission to objects and\/or containers within this container<\/em> is selected.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-content\/uploads\/sites\/69\/2021\/09\/applythiscontainer.png\" alt=\"Apply to This Container only\" \/><\/p>\n<\/li>\n<\/ul>\n<p>Keep in mind that the <strong>PropagationFlags<\/strong> are significant only if inheritance flags are present.<\/p>\n<h2>Conslucsion<\/h2>\n<p>As you can see, the <code>Get-ACL<\/code> cmdlet is a powerful cmdlet, and it works in the <code>AD:<\/code> drive as the FileSystem drive, but with some challenges. In this post, I try to simplify the <code>Get-ACL<\/code> output result and explain the GUIDs and what these GUID mean, as it helps in better understanding the permission structure through PowerShell.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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. While there are no cmdlets, you can nevertheless manage AD permissions using the AD PowerShell drive. In this post, I will try to simplify Active Directory ACL and [&hellip;]<\/p>\n","protected":false},"author":53227,"featured_media":77,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[13],"tags":[46,22,3],"class_list":["post-486","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-acl","tag-active-directory","tag-powershell"],"acf":[],"blog_post_summary":"<p>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. While there are no cmdlets, you can nevertheless manage AD permissions using the AD PowerShell drive. In this post, I will try to simplify Active Directory ACL and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts\/486","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/users\/53227"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/comments?post=486"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/posts\/486\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/media\/77"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/media?parent=486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/categories?post=486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell-community\/wp-json\/wp\/v2\/tags?post=486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}