Hey, Scripting Guy! Weekend Scripter: Using the Get-ACL Cmdlet to Show Inherited Permissions on Registry Keys

Hey, Scripting Guy! Weekend Scripter: Using the Get-ACL Cmdlet to Show Inherited Permissions on Registry Keys

  • Comments 5
  • Likes

Bookmark and Share

 

Microsoft Scripting Guy Ed Wilson here. I was sitting in the kitchen waiting for my pot of English Breakfast tea to steep when my mind began to wander back over the week that was nearly completed. One of these days I will write a script to count the number of words in all the documents in a folder. That suggestion is actually up on the white board in my office, but that day will not be today. What would be cool would be to write a script that uses the Twitter API and determines how many tweets I send in a week. But again that will not be happening today. Then it dawned on me—a question I was asked earlier in the week about using the Get-ACL cmdlet to show inherited permissions on registry keys.


To play around with this just a bit, I need to give a user specific permission to a registry key. This is shown in the following image where you can see I gave Teresa (the Scripting Wife) special permission.

Image showing the Scriping Wife has special permission


The actual permission page is shown in the following image, where the Scripting Wife is granted the query value permission.

Image of permission page


The permissions summary page tells me that this value is not inherited. This is seen in the following image.

Image of permissions summary page


If I use the Get-ACL cmdlet to retrieve access control lists from a registry key, the default view is not very helpful. This is shown here:

PS C:\> Get-Acl -Path HKCU:\Software\ScriptingGuys

Path                                                  Owner                                            Access
----                                                     -----                                                ------
Microsoft.PowerShell.Core\Registry::... NWTRADERS\ed                            NWTRADERS\Teresa Allow  QueryValues...


PS C:\>


On the other hand, if I pipe the results of this command to the Format-List cmdlet and choose all of the properties, the display is a bit better. This is shown here where I use the fl alias instead of typing Format-List.

PS C:\> Get-Acl -Path HKCU:\Software\ScriptingGuys | fl *


PSPath                  : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\ScriptingGuys
PSParentPath         : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software
PSChildName          : ScriptingGuys
PSDrive                   : HKCU
PSProvider              : Microsoft.PowerShell.Core\Registry
AccessToString       : NWTRADERS\Teresa Allow  QueryValues
                                NWTRADERS\ed Allow  FullControl
                                NT AUTHORITY\SYSTEM Allow  FullControl
                                BUILTIN\Administrators Allow  FullControl
                                NT AUTHORITY\RESTRICTED Allow  ReadKey
AuditToString           :
Path                        : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\ScriptingGuys
Owner                     : NWTRADERS\ed
Group                      : NWTRADERS\Domain Users
Access                    : {System.Security.AccessControl.RegistryAccessRule, System.Security.AccessControl.RegistryAccessRule, System.Security.AccessControl.RegistryAccessRule, System.Security.AccessControl.
RegistryAccessRule...}
Sddl                         : O:S-1-5-21-3746122405-834892460-3960030898-1115G:DUD:AI(A;CI;CC;;;S-1-5-21-3746122405-8348924
                                60-3960030898-1207)(A;OICIID;KA;;;S-1-5-21-3746122405-834892460-3960030898-1115)(A;OICIID;KA;
                                ;;SY)(A;OICIID;KA;;;BA)(A;OICIID;KR;;;RC)
AccessRightType      : System.Security.AccessControl.RegistryRights
AccessRuleType       : System.Security.AccessControl.RegistryAccessRule
AuditRuleType           : System.Security.AccessControl.RegistryAuditRule
AreAccessRulesProtected : False
AreAuditRulesProtected  : False
AreAccessRulesCanonical : True
AreAuditRulesCanonical  : True


A careful examination of the output above does not tell me where Teresa received her QueryValues permission. The AccessToString property gives me both inherited and non-inherited permissions, but it does not tell me where they came from. If this is all I need, I can use this syntax to receive better output.

PS C:\> (Get-Acl -Path HKCU:\Software\ScriptingGuys).AccessToString
NWTRADERS\Teresa Allow  QueryValues
NWTRADERS\ed Allow  FullControl
NT AUTHORITY\SYSTEM Allow  FullControl
BUILTIN\Administrators Allow  FullControl
NT AUTHORITY\RESTRICTED Allow  ReadKey


One of the really cool things about Windows PowerShell is its support for the .NET Framework. The Format-List output from Get-ACL told me that the Access property that is returned is a series of System.Security.AccessControl.RegistryAccessRule .NET Framework classes. When I looked up System.Security.AccessControl.RegistryAccessRule on MSDN, I found it returns a number of very helpful properties. Because there are several instances of the Access property returned for this particular registry key, I need to use the Foreach-Object cmdlet to display the RegistryAccessRule for each entry on the key. This is shown here where I use the % symbol for an alias for Foreach-Object.

PS C:\> Get-Acl -Path HKCU:\Software\ScriptingGuys | % { $_.access }


RegistryRights    : QueryValues
AccessControlType : Allow
IdentityReference : NWTRADERS\Teresa
IsInherited       : False
InheritanceFlags  : ContainerInherit
PropagationFlags  : None

RegistryRights    : FullControl
AccessControlType : Allow
IdentityReference : NWTRADERS\ed
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

RegistryRights    : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

RegistryRights    : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

RegistryRights    : ReadKey
AccessControlType : Allow
IdentityReference : NT AUTHORITY\RESTRICTED
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

 

Pretty cool, huh? It all revolves around being willing to explore the .NET Framework classes. Luckily, they are all documented on MSDN. I hope you enjoy the rest of your weekend. 

 

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
 

Ed Wilson and Craig Liebendorfer, Scripting Guys

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi,

    Interesting article, but is it possible to filter out the inherited permissions.  E.g. scan a directory and only show objects that have explicitly set permissions?

    Cheers, David

  • What about retrieving registry ACLs from other computers?

  • How do you access registry ACLs from other computers?

  • It seems that 'LiteralPath' doesn't work in powershell 3.0.
    Get-ACL -LiteralPath 'Registry::HKEY_CLASSES_ROOT\.ai'

    get-acl : Cannot find path 'HKEY_CLASSES_ROOT\.ai' because it does not exist.
    At line:1 char:1
    + get-acl -LiteralPath 'Registry::HKEY_CLASSES_ROOT\.ai'
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (:) [Get-Acl], ItemNotFoundException
    + FullyQualifiedErrorId : GetAcl_PathNotFound,Microsoft.PowerShell.Commands.GetAclCommand

  • Wondering if you can help me out here... I am trying to use Get-ChildItem and Get-ACL to recursively spit out any unresolved SID in the ACLs to a CSV something with a filter on IdentityReference -like "S-1-5-21*" but can't seem to get any nice output because of the nature of the array in there