Get-ChildItem Recursive Exclude NOT Excluding Folder

983 views Asked by At

I've check other posts and even following those I can't get this to function.

I'm trying to pull all of the ACL information from a drive but exclude the Windows folder.

This is the code I'm using, but it always tries to include the folder. Can someone tell me why this isn't working?

I've also tried Where-Object.

$containers = Get-ChildItem -Path $Path -Recurse -Exclude $exclude |
              ? {$_.FullName -notmatch '\\windows\\?'}

Main Code:

function Get-PathPermissions {
    param ( [Parameter(Mandatory=$true)] [System.String]${Path} )

    begin {
        $root = Get-Item $Path 
        ($root | Get-Acl).Access |
            Add-Member -MemberType NoteProperty -Name "Path" -Value $($root.fullname).ToString() -PassThru
    }
    process {
        $exclude = @('C:\Windows\*')
        $containers = Get-ChildItem -Path $Path -Recurse -Exclude $exclude |
                      ? {$_.psIscontainer -eq $true}
        if ($containers -eq $null) {break}
            foreach ($container in $containers)
            {
            (Get-Acl $container.FullName).Access |
                ? { $_.IsInherited -eq $false } |
                Add-Member -MemberType NoteProperty -Name "Path" -Value $($container.fullname).ToString() -PassThru
            }

    }
}

Get-PathPermissions $args[0]
2

There are 2 answers

0
Matt On

Couple points about the -Exclude parameter. While it does not explicitly mention it in the documentation it seems to work based on file and directory names.... not the full paths themselves. As a result of that point it does not, in any way, work recursively with directories which I think is your actual conundrum.

Since C:\Windows\* is not a valid directory name that is why it is not filtering anything. Jisaak's suggestion of changing $exclude to just "windows" did work in a sense. If you looked at your output you would have noticed that the actual "c:\windows" folder was missing. What you are actually having a problem with is that exclude does nothing for the sub folders of C:\windows which I will guess is what you intended.

There is another SO post about how -Exclude basically sucks. It can be useful as long as you understand its limitations. Ansgar's answer covers the way around that. It will make sure nothing in the tree of C:\windows ends up in your results.

0
Ansgar Wiechers On

Filtering with -notmatch '\\windows\\?' should work. I'd use the full path, though, to avoid potential undesired exclusions:

$containers = Get-ChildItem -Path $Path -Recurse |
              ? { $_.FullName -notmatch '^c:\\windows\\?' -and $_.PSIsContainer}

On PowerShell v3 or newer you can also use the -Directory switch for restricting the results to directories:

$containers = Get-ChildItem -Path $Path -Recurse -Directory |
              ? { $_.FullName -notmatch '^c:\\windows\\?' }