six demon bag
Wind, fire, all that kind of thing!
2014-07-11
Compare ACLs
Recently I had the need to compare the ACLs of two Active
Directory objects. With file ACLs I could expand their Access
properties and compare the resulting lists with Compare-Object
. However, for
ACLs of Active Directory objects that didn't work, so I came up with
the following function.
function Compare-Acl {
[CmdletBinding()]
Param(
[Parameter()]
[string]$ReferenceObjectPath,
[Parameter()]
[string]$DifferenceObjectPath,
[Switch]
[bool]$ExcludeDifferent = $false,
[Switch]
[bool]$IncludeEqual = $false
)
$acl1 = Get-Acl -Path $ReferenceObjectPath | select -Expand Access
$acl2 = Get-Acl -Path $DifferenceObjectPath | select -Expand Access
$props1 = $acl1 | select -First 1 | % { $_.PSObject.Properties | % { $_.Name } }
$props2 = $acl2 | select -First 1 | % { $_.PSObject.Properties | % { $_.Name } }
if ( Compare-Object $props1 $props2 ) {
throw "Objects don't have matching property sets."
}
$csv1 = $acl1 | ConvertTo-Csv -NoType
$csv2 = $acl2 | ConvertTo-Csv -NoType
$diff1 = $csv1 | ? { $csv2 -notcontains $_ }
$diff2 = $csv2 | ? { $csv1 -notcontains $_ }
if ( $diff1 -and -not $ExcludeDifferent ) {
$diff1 | ConvertFrom-Csv -Header $props1 | % {
New-Object -Type PSObject -Property @{
'AccessRule' = $_
'SideIndicator' = '<='
}
}
}
if ( $diff2 -and -not $ExcludeDifferent ) {
$diff2 | ConvertFrom-Csv -Header $props2 | % {
New-Object -Type PSObject -Property @{
'AccessRule' = $_
'SideIndicator' = '=>'
}
}
}
if ( $IncludeEqual ) {
$csv1 | ? { $csv2 -contains $_ } | ConvertFrom-Csv -Header $props1 | % {
New-Object -Type PSObject -Property @{
'AccessRule' = $_
'SideIndicator' = '=='
}
}
}
}
Usage example:
PS C:\> Import-Module ActiveDirectory # otherwise the AD: PSDrive won't work
PS C:\> $dn1 = 'OU=some,DC=example,DC=org'
PS C:\> $dn2 = 'OU=other,DC=example,DC=org'
PS C:\> Compare-Acl -Reference "AD:$dn1" -Difference "AD:$dn2"
AccessRule SideIndicator
---------- -------------
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=ExtendedRight; InheritanceType=D... <=
@{ActiveDirectoryRights=ExtendedRight; InheritanceType=D... <=
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... <=
@{ActiveDirectoryRights=Self; InheritanceType=Descendent... <=
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... <=
@{ActiveDirectoryRights=GenericAll; InheritanceType=Desc... =>
@{ActiveDirectoryRights=GenericAll; InheritanceType=Desc... =>
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... =>
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... =>
PS C:\> Compare-Acl -Reference "AD:$dn1" -Difference "AD:$dn2" -Include -Exclude
AccessRule SideIndicator
---------- -------------
@{ActiveDirectoryRights=ActiveDirectoryRights; Inheritan... ==
@{ActiveDirectoryRights=DeleteChild, DeleteTree, Delete;... ==
@{ActiveDirectoryRights=GenericRead; InheritanceType=Non... ==
@{ActiveDirectoryRights=GenericRead; InheritanceType=Non... ==
@{ActiveDirectoryRights=GenericAll; InheritanceType=None... ==
@{ActiveDirectoryRights=GenericAll; InheritanceType=None... ==
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... ==
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... ==
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... ==
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... ==
@{ActiveDirectoryRights=CreateChild, DeleteChild; Inheri... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=ReadProperty; InheritanceType=De... ==
@{ActiveDirectoryRights=WriteProperty; InheritanceType=D... ==
@{ActiveDirectoryRights=GenericRead; InheritanceType=Des... ==
@{ActiveDirectoryRights=GenericRead; InheritanceType=Des... ==
@{ActiveDirectoryRights=GenericRead; InheritanceType=Des... ==
@{ActiveDirectoryRights=ReadProperty, WriteProperty; Inh... ==
@{ActiveDirectoryRights=ReadProperty, WriteProperty, Ext... ==
@{ActiveDirectoryRights=GenericAll; InheritanceType=All;... ==
@{ActiveDirectoryRights=ListChildren; InheritanceType=Al... ==
@{ActiveDirectoryRights=CreateChild, Self, WriteProperty... ==
PS C:\> Compare-Acl -Reference 'C:\Windows' -Difference "AD:$dn2"
Objects don't have matching property sets.
At line:18 char:5
+ throw "Objects don't have matching property sets."
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Objects don't h... property sets.:String) [],
RuntimeException
+ FullyQualifiedErrorId : Objects don't have matching property sets.
PS C:\> Compare-Acl -Reference 'C:\Windows' -Difference 'C:\bootmgr'
AccessRule SideIndicator
---------- -------------
@{FileSystemRights=268435456; AccessControlType=Allow; I... <=
@{FileSystemRights=268435456; AccessControlType=Allow; I... <=
@{FileSystemRights=Modify, Synchronize; AccessControlTyp... <=
@{FileSystemRights=268435456; AccessControlType=Allow; I... <=
@{FileSystemRights=Modify, Synchronize; AccessControlTyp... <=
@{FileSystemRights=-1610612736; AccessControlType=Allow;... <=
@{FileSystemRights=268435456; AccessControlType=Allow; I... <=
@{FileSystemRights=ReadAndExecute, Synchronize; AccessCo... <=
@{FileSystemRights=-1610612736; AccessControlType=Allow;... <=
@{FileSystemRights=ReadAndExecute, Synchronize; AccessCo... =>
@{FileSystemRights=ReadAndExecute, Synchronize; AccessCo... =>
PS C:\> Compare-Acl -Reference 'HKLM:\SOFTWARE' -Difference 'HKCU:\Software'
AccessRule SideIndicator
---------- -------------
@{RegistryRights=268435456; AccessControlType=Allow; Ide... <=
@{RegistryRights=268435456; AccessControlType=Allow; Ide... <=
@{RegistryRights=FullControl; AccessControlType=Allow; I... <=
@{RegistryRights=268435456; AccessControlType=Allow; Ide... <=
@{RegistryRights=FullControl; AccessControlType=Allow; I... <=
@{RegistryRights=-2147483648; AccessControlType=Allow; I... <=
@{RegistryRights=ReadKey; AccessControlType=Allow; Ident... <=
@{RegistryRights=FullControl; AccessControlType=Allow; I... =>
@{RegistryRights=FullControl; AccessControlType=Allow; I... =>
@{RegistryRights=FullControl; AccessControlType=Allow; I... =>
@{RegistryRights=ReadKey; AccessControlType=Allow; Ident... =>
Posted 18:50 [permalink]