Filtering AD ACL Object to be excluded from the Get-ACL result?

Hi Everyone,

I need to exclude the certain pattern result of the below script to export the Explicitly defined ACL that is already working.

Script:

$Excludes = 'NT AUTHORITY\SYSTEM', 'BUILTIN\Administrators', 'CREATOR OWNER', 'Everyone', 'S-1-5-21'
$reExcludeObjects = '^({0})$' -f (($Excludes | ForEach-Object { [regex]::Escape($_) }) -join '|')

function Get-CustomDirInfo([IO.DirectoryInfo]$path, $parentAcl)
{
    $containerInherit = [Security.AccessControl.InheritanceFlags]::ContainerInherit
    $acl = (Get-Acl -Path $path.FullName).Access | Foreach-Object {
        New-Object PSObject -Property @{
            Path = $path.FullName;
            IdentityReference = $_.IdentityReference;
            FileSystemRights = $_.FileSystemRights;
            IsInherited = $_.IsInherited;
            InheritanceFlags = $_.InheritanceFlags;
            InheritedFrom = if ($_.IsInherited)
            {
                if ($parentAcl)
                {
                    $current = $_
                    $parentAce = $parentAcl | Where-Object {
                        ($current.IdentityReference -eq $_.IdentityReference) -and
                        ($current.FileSystemRights -band $_.FileSystemRights) -and
                        ($_.InheritanceFlags -band $containerInherit) -and
                        ($_.IdentityReference -notmatch $reExcludeObjects)
                    }
                    if (!$parentAce -or ($parentAce.count -gt 1))
                    {
                        Write-Warning "Something is not right Parent ACE Count = $($parentAce.count) - $($path.FullName)"
                        #Export the broken direcotries path as unique entries 
                        $BrokenACLDirectories += $path.FullName
                        $BrokenACLDirectories | Select-Object -exp FullName -Unique | OGV -Title "There are $($BrokenACLDirectories.Count) Broken Directories"
                    }
                    if ($parentAce.IsInherited)
                    {
                        $parentAce.InheritedFrom
                    }
                    else
                    {
                        Split-Path $path.FullName -Parent
                    }
                }
                else
                {
                    "Unknown (Top:$($path.FullName))"
                }
            }
            else {
                "Not Inherited"
            }
        }
    }
    
    $acl
    $inheritableAcl = $acl | Where-Object { $_.InheritanceFlags -band $containerInherit }
    $path.FullName | Get-ChildItem | Where-Object { $_.PsIsContainer } | Foreach-Object { Get-CustomDirInfo $_ $inheritableAcl }
}

Get-CustomDirInfo (Get-Item F:\FileShare\Corporate) | ft Path, IdentityReference, FileSystemRights, IsInherited, InheritedFrom -Auto

However, even with the above script RegEx filtering, the result is still the same?

Also in Line #28, the OGV is not showing the unique directory which is throwing error:

Select-Object : Property "FullName" cannot be found.
At line:30 char:49
+ ... $BrokenACLDirectories | Select-Object -exp FullName -Unique | OGV - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (F:\FileShare\Shared-Dir\W3SVC71:PSObject) [Select-Object], PSArgumentException
+ FullyQualifiedErrorId : ExpandPropertyNotFound,Microsoft.PowerShell.Commands.SelectObjectCommand

Thank you in advance,

The filter can be done like so:

(Get-Acl -Path C:\Scripts).Access | 
Where{$Excludes -notcontains $_.IdentityReference}

This code:

#Export the broken direcotries path as unique entries 
$BrokenACLDirectories += $path.FullName
$BrokenACLDirectories | Select-Object -exp FullName -Unique | OGV -Title "There are $($BrokenACLDirectories.Count) Broken Directories"

First, there is no where in the code provided that $BrokenACLDirectories is defined, so I would think there would be an error about op_addition when you attempt to append to it. If it is defined and you are appending with +=, it’s an array, not an object. The logic for InheritedFrom could use some work. Recommend you work on collecting information in the function so that you can filter what directories are ‘broken’ rather than doing to much analysis when collecting acls as it’s typically time consuming.

When you crosspost, you should link that post at a minimum.

https://stackoverflow.com/questions/63877519/unable-to-filter-acl-identityreference-to-exclude-certain-pattern/63878031?noredirect=1#comment112970414_63878031

You already have 2 great answers there. If you’re unwilling to take the time to understand them, then please don’t try to get more people to waste their time. As per your screenshot, you are creating a custom identity reference. It’s no longer just the identity, you have added “CreateFile, AppendData, ReadAndExecute,” as well as “DeletedSubdirectoriesAndFiles, Modify,” to the identityreference property. For those that don’t have that added, I would assume a space is added since you are clearly tacking text onto the end of those. What I said in the comment on Theo’s answer is to use the regex match, but you must remove the $ from the exclusion variable as that indicates THE END OF THE LINE. Since the identity reference IS NOT THE END OF THE LINE, this will never match.

Again, I’m specifically referring to

$reExcludeObjects = ‘^({0})$’ -f (($Excludes | ForEach-Object { [regex]::Escape($_) }) -join ‘|’)

Therefore, this here will never match

"NT AUTHORITY\system " -match $reExcludeObjects

However, if you change the line as I suggested, removing the $…

$Excludes = 'NT AUTHORITY\SYSTEM', 'BUILTIN\Administrators', 'CREATOR OWNER', 'Everyone', 'S-1-5-21'
$reExcludeObjects = '^({0})' -f (($Excludes | ForEach-Object { [regex]::Escape($_) }) -join '|')

"NT AUTHORITY\System " -match $reExcludeObjects

True

And it doesn’t matter that you’ve added text onto this property. Even this will match

"NT AUTHORITY\SystemPleaseReadAndTest" -match $reExcludeObjects

True

So please, please, please take a few minutes to try the suggestion. Remove the end of line marker from the code, and hopefully you will have your desired result.

@Doug,

Many thank you for the support and the explanations, yes, you are right, the one character difference $ solve the issue.

RegEx is so powerful :slight_smile:

 

@Rob,

Yes, I’m still confused and no sure what to do to gather all of those broken ACL directories into OGV or .CSV file.

Hence I need some help in the below code:

					if (!$parentAce -or ($parentAce.count -gt 1))
					{
						Write-Warning "Something is not right Parent ACE Count = $($parentAce.count) - $($path.FullName)"
						#Export the broken direcotries path as unique entries 
					    $BrokenACLDirectories += $path.FullName
						$BrokenACLDirectories | Select-Object -exp FullName -Unique | OGV -Title "There are $($BrokenACLDirectories.Count) Broken Directories"
					}

I will create another post topic or thread for the above.