jpmc26
jpmc26

Reputation: 29884

How do I prevent Get-ChildItem from traversing a particular directory?

Let me start by saying that I've looked at Unable to exclude directory using Get-ChildItem -Exclude parameter in Powershell and How can I exclude multiple folders using Get-ChildItem -exclude?. Neither of these has an answer that solves my problem.

I need to search a directory recursively for files with a certain extension. For simplicity, let's just say I need to find *.txt. Normally, this command would suffice:

Get-ChildItem -Path 'C:\mysearchdir\' -Filter '*.txt' -Recurse

But I have a major problem. There's a node_modules directory buried somewhere inside C:\mysearchdir\, and NPM creates extremely deep nested directories. (The detail of it being an NPM managed directory is only important because this means the depth is beyond my control.) This results in the following error:

Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

I believe this error bubbles up from the limitations in the .NET IO libraries.

I can't search in the other directories around it very easily. It's not at the top of the directory; it's deeper in, say at C:\mysearchdir\dir1\dir2\dir3\node_modules, and there are directories I need to search at all those levels. So just searching the other directories around it is going to be cumbersome and not very maintainable as more files and directories are added.

I've tried to -Exclude parameter without any success. That isn't surprising since I just read that -Exclude is only applied after the results are fetched. I can't find any real info on using -Filter (as is noted in this answer).

Is there any way I can get Get-ChildItem to work, or am I stuck writing my own recursive traversal?

Upvotes: 8

Views: 2103

Answers (2)

Rob H
Rob H

Reputation: 1849

Oh, man, I feel dumb. I was facing the same problem as you. I was working with @DarkLite1's answer, trying to parse it, when I got to the "-EA SilentlyContinue" part.

FACEPALM

FACEPALM!

That's all you need!

This worked for me, try it out:

Get-ChildItem -Path 'C:\mysearchdir\' -Filter '*.txt' -Recurse -ErrorAction SilentlyContinue

Note: This will not exclude node_modules from a search, just hide any errors generated by traversing the long paths. If you need to exclude it entirely, you're going to need a more complicated solution.

Upvotes: 6

DarkLite1
DarkLite1

Reputation: 14705

Maybe you could try something like this:

$Source = 'S:\Prod'
$Exclude = @('S:\Prod\Dir 1', 'S:\Prod\Dir 2')

Get-ChildItem -LiteralPath $Source -Directory -Recurse -PipelineVariable Dir -EV e -EA SilentlyContinue | 
    Where {($Exclude | Where {($Dir.FullName -eq "$_") -or ($Dir.FullName -like "$_\*")}).count -eq 0}

Upvotes: 0

Related Questions