How to exclude folder from Recursive Get-Childpath

Viewed 69

Im trying to run a recursive search through all of C Drive, but wish to exclude Windows & Program Files.

Confused as to why this doesn't work.

$b = if(Get-ChildItem -Path C:\ -Recurse -Force -filter *.exe -Exclude Users,Windows | ? {$_.Name -eq 'firefox.exe'})
{
    return $true
} 
else {
    return $false
}

$b

I know it isn't working as I get access denied errors due to the drive permissions.

Get-ChildItem : Access to the path 'C:\Windows\ccmsetup' is denied.
At line:1 char:9
+ $b = if(Get-ChildItem -Path C:\ -Recurse -Force -filter *.exe -Exclud ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (C:\Windows\ccmsetup:String) [Get-ChildItem], UnauthorizedAccessException
    + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
1 Answers

The -Exclude parameter of Get-ChildItem is not very reliable and for this particular case, the process would be quite slow using this cmdlet. I would recommend you to use a Collections.Queue and IO.Directory to enumerate files and folders.

Below code will attempt to find all appearances of firefox.exe, however, if you wish to stop at first appearance you should uncomment break outer.

Note that this requires you to add the absolute paths of the folders you wish to exclude to the $pathToExclude array.

[System.IO.Directory]::EnumerateFiles($target) could be replaced by [System.IO.Directory]::GetFiles($target, '*firefox.exe').

$pathToExclude = @(
    'C:\Users'
    'C:\Windows'
)

$queue = [System.Collections.Queue]::new()
$queue.Enqueue('C:\')

:outer while($queue.Count) {
    $target = $queue.Dequeue()
    foreach($path in $pathToExclude) {
        if($target.StartsWith($path)) {
            continue outer
        }
    }

    try {
        foreach($dir in [System.IO.Directory]::EnumerateDirectories($target)) {
            $queue.Enqueue($dir)
        }

        foreach($file in [System.IO.Directory]::EnumerateFiles($target)) {
            if($file -like '*firefox.exe') {
                # return the full path of the file if it contains `firefox.exe`
                $file

                # if you want to stop the loop at the first finding of the file,
                # uncomment below line:
                # break outer
            }
        }
    }
    catch {
        # Ignoring folders we're unable to enumerate
        # You can however add these directories to a list or display error messages
    }
}
Related