Learn about Windows PowerShell
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.
The actual permission page is shown in the following image, where the Scripting Wife is granted the query value permission.
The permissions summary page tells me that this value is not inherited. This is seen in the following image.
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\ScriptingGuysPath 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\ScriptingGuysPSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\SoftwarePSChildName : ScriptingGuysPSDrive : HKCUPSProvider : Microsoft.PowerShell.Core\RegistryAccessToString : NWTRADERS\Teresa Allow QueryValues NWTRADERS\ed Allow FullControl NT AUTHORITY\SYSTEM Allow FullControl BUILTIN\Administrators Allow FullControl NT AUTHORITY\RESTRICTED Allow ReadKeyAuditToString :Path : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\ScriptingGuysOwner : NWTRADERS\edGroup : NWTRADERS\Domain UsersAccess : {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.RegistryRightsAccessRuleType : System.Security.AccessControl.RegistryAccessRuleAuditRuleType : System.Security.AccessControl.RegistryAuditRuleAreAccessRulesProtected : FalseAreAuditRulesProtected : FalseAreAccessRulesCanonical : TrueAreAuditRulesCanonical : 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).AccessToStringNWTRADERS\Teresa Allow QueryValuesNWTRADERS\ed Allow FullControlNT AUTHORITY\SYSTEM Allow FullControlBUILTIN\Administrators Allow FullControlNT 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 : QueryValuesAccessControlType : AllowIdentityReference : NWTRADERS\TeresaIsInherited : FalseInheritanceFlags : ContainerInheritPropagationFlags : NoneRegistryRights : FullControlAccessControlType : AllowIdentityReference : NWTRADERS\edIsInherited : TrueInheritanceFlags : ContainerInherit, ObjectInheritPropagationFlags : NoneRegistryRights : FullControlAccessControlType : AllowIdentityReference : NT AUTHORITY\SYSTEMIsInherited : TrueInheritanceFlags : ContainerInherit, ObjectInheritPropagationFlags : NoneRegistryRights : FullControlAccessControlType : AllowIdentityReference : BUILTIN\AdministratorsIsInherited : TrueInheritanceFlags : ContainerInherit, ObjectInheritPropagationFlags : NoneRegistryRights : ReadKeyAccessControlType : AllowIdentityReference : NT AUTHORITY\RESTRICTEDIsInherited : TrueInheritanceFlags : ContainerInherit, ObjectInheritPropagationFlags : 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
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