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

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:SoftwareScriptingGuys

Path                                                  Owner                                            Access
—-                                                     —–                                                ——
Microsoft.PowerShell.CoreRegistry::… NWTRADERSed                            NWTRADERSTeresa 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:SoftwareScriptingGuys | fl *


PSPath                  : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_USERSoftwareScriptingGuys
PSParentPath         : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_USERSoftware
PSChildName          : ScriptingGuys
PSDrive                   : HKCU
PSProvider              : Microsoft.PowerShell.CoreRegistry
AccessToString       : NWTRADERSTeresa Allow  QueryValues
                                NWTRADERSed Allow  FullControl
                                NT AUTHORITYSYSTEM Allow  FullControl
                                BUILTINAdministrators Allow  FullControl
                                NT AUTHORITYRESTRICTED Allow  ReadKey
AuditToString           :
Path                        : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_USERSoftwareScriptingGuys
Owner                     : NWTRADERSed
Group                      : NWTRADERSDomain 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:SoftwareScriptingGuys).AccessToString
NWTRADERSTeresa Allow  QueryValues
NWTRADERSed Allow  FullControl
NT AUTHORITYSYSTEM Allow  FullControl
BUILTINAdministrators Allow  FullControl
NT AUTHORITYRESTRICTED 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:SoftwareScriptingGuys | % { $_.access }


RegistryRights    : QueryValues
AccessControlType : Allow
IdentityReference : NWTRADERSTeresa
IsInherited       : False
InheritanceFlags  : ContainerInherit
PropagationFlags  : None

RegistryRights    : FullControl
AccessControlType : Allow
IdentityReference : NWTRADERSed
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

RegistryRights    : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITYSYSTEM
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

RegistryRights    : FullControl
AccessControlType : Allow
IdentityReference : BUILTINAdministrators
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

RegistryRights    : ReadKey
AccessControlType : Allow
IdentityReference : NT AUTHORITYRESTRICTED
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