Как исключить определенные папки при рекурсивном поиске

#powershell

#powershell

Вопрос:

У меня есть скрипт, который будет рекурсивно выполнять поиск по сетевому пути и извлекать имена файлов. Однако первые 5 папок необходимо исключить из поиска, потому что, ну, он устарел, и они еще не удалили их (у меня нет доступа для удаления папок).

Что мне нужно сделать, так это исключить некоторые папки с именами: - BOOT MEDIA , 1_Do_not_use , 1_lync , и еще пару.

Как я могу выполнить рекурсивный поиск в каталоге и исключить правильные папки из поиска?

Что у меня есть до сих пор:

 param(
  [string]$gather = "PACKAGE"
)

function say($info){ Write-Host $info }

function searchDir($path = "<removed for security>") 
{ 
    foreach ($item in Get-ChildItem $path)
    {

        $package = Test-Path $item.FullName -PathType Container

        if ($package) 
        {
            $item 
            searchDir $item.FullName
        } 
        else 
        { 
            $item
        }
    } 
}
  

Изображение каталога:

Каталог

Изображение для отображения выходных данных, приведенных в ответе:

вывод

Ответ №1:

Исключение устаревших папок, которые могут существовать где угодно рекурсивно, PS2.0 :

 function searchDir($path = "<removed for security>") 
{
    $deprecated = '- BOOT MEDIA', '1_Do_not_use', '1_lync'
    Get-ChildItem $path | ForEach {
        if ($_ -is [IO.FileInfo]) {
            $_
        } elseif ($deprecated -notcontains $_.Name) {
            $_
            searchDir $_.FullName
        }
    }
}
  

И гораздо более быстрая версия .NET4 , которая выводит только полные имена файлов, а не объекты.
Каталоги находятся в конце, чтобы их было легко различить.

 function searchDir($path = "<removed for security>") 
{
    $deprecated = '- BOOT MEDIA', '1_Do_not_use', '1_lync', 'default'
    [IO.Directory]::EnumerateFiles($path)
    [IO.Directory]::EnumerateDirectories($path) | ForEach {
        if ($deprecated -notcontains $_.Name) {
            "$_"
            searchDir $_
        }
    }
}
  

Другим подходом было бы перечислить все с помощью всего одного Get-ChildItem и впоследствии отфильтровать устаревшие папки из результата, но поскольку доступ к сети медленный, я избегаю ненужного перечисления в пользу саморекурсивной функции, также используемой OP.

Важное замечание.

Теперь функция удобна для конвейера, так что ее результат может быть передан и обработан немедленно.
Принимая во внимание, что функция OP остановила дальнейшее выполнение вызываемого объекта до тех пор, пока не будут извлечены все файлы, потому foreach что оператор накапливает весь массив перед его перечислением. При медленной сети или большом дереве каталогов это может занять несколько минут.

Комментарии:

1. При этом все равно будут отображаться устаревшие папки, это в 100 раз быстрее, но все равно отображает их

2. Я прошу прощения за это, но устаревшие папки — это первые 5 в пути.

3. Другой способ исключить эти имена из любого места пути — использовать Where-Object предложение. gci $path | where { $_.Name -notin $deprecated } | foreach { ... }

4. @wOxxOm смотрите Добавленное изображение для лучшего понимания, возможно, я неправильно говорю.

5. @wOxxOm Это только начало, оно не исключает каталоги и все еще проходит через них, но я думаю, что смогу разобраться. Причина, по которой я исключил каталоги, заключается в том, что это каталог изображений (где они перезагружают все изображения), и в нем есть все файлы, необходимые для успешной загрузки образа, около 10 000 файлов. Так что это просто делает его намного медленнее, чем должно быть.