In PowerShell, I can define a .NET Directory Security object and give it different rules:
$acl = New-Object System.Security.AccessControl.DirectorySecurity
$acl.AddAccessRule($rule_a)
$acl.AddAccessRule($rule_b)
...
Now depending of the Access Rule Protection settings, those settings in the .Net Directory Security object $acl
could be inherited to the child items of the folder or not. The inheritance rules can be changed like this:
$acl.SetAccessRuleProtection($true, $true) # could also be ($false, $false) or a different setting...
After $acl
has been defined as needed, it gets applied to a folder:
Set-Acl $folder $acl
Now I want to test if the settings in $acl
have been applied correctly to $folder
. My expected settings are simply what I defined before in $acl
:
$expectedAclSettings = $acl
I can get the Access Control Lists of a folder and all its child items recursively like this to get the actual acl settings:
$folderAndChildren = @(Get-Item -Path $folder) + @(Get-ChildItem -Path $folder -Recurse)
$actualAclSettings = ($folderAndChildren | Get-Acl)
Now my question is:
Is there an easy way (like a one-liner) to compare $expectedAclSettings
and $actualAclSettings
and test if the settings have been applied correctly for all files in $actualAclSettings?
Or do I have to check in $expectedAclSettings
if the inheritance rules are preserved/protected or not, and depending on that, write a more complex test function that f.e. iterates over each path in $actualAclSettings
, and checks based on the depth of the current file/folder and the inheritance settings that acl values should have been applied or not? Are there other approaches to test the acl values?
I did not find a solution to compare the access control lists in a one-liner. The solution I used to compare the permissions and have the differences in a readable output, is to "hash" the permissions to a string, and recursively compare if the permissions. I will post the code I used below, maybe it helps somebody. If anyone has a better answer, feel free to post it, and I might update my code.
I used the following function
Compare-AccessRules
to compare access rules. It expects two objects of type "Access", these are returned fromGet-ACL
, f.e.:Here is the function:
Inside this function, access rules are "hashed" with the
Convert-AccessRuleToString
function: