Как получить только каталоги с помощью Get-ChildItem?

Я использую PowerShell 2.0, и я хочу передать все подкаталоги определенного пути. Следующая команда выводит все файлы и каталоги, но я не могу понять, как отфильтровать файлы.

Get-ChildItem c:\mypath -Recurse

Я попытался использовать $_.Attributes для получения атрибутов, но затем я не знаю, как построить литеральный экземпляр System.IO.FileAttributes, чтобы сравнить его с. В cmd.exe это будет

dir /b /ad /s

Ответ 1

Для версий PowerShell менее 3.0:

Объект FileInfo возвращаемый Get-ChildItem имеет базовое свойство PSIsContainer. Вы хотите выбрать только эти элементы.

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }

Если вам нужны необработанные строковые имена каталогов, вы можете сделать

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

Для PowerShell 3.0 и выше:

dir -Directory

Ответ 2

В PowerShell 3.0 это проще:

Get-ChildItem -Directory #List only directories
Get-ChildItem -File #List only files

Ответ 3

Используйте

Get-ChildItem -dir #lists only directories
Get-ChildItem -file #lists only files

Если вы предпочитаете псевдонимы, используйте

ls -dir #lists only directories
ls -file #lists only files

или

dir -dir #lists only directories
dir -file #lists only files

Чтобы также найти подкаталоги, добавьте опцию -r.

ls -dir -r #lists only directories recursively
ls -file -r #lists only files recursively 

Протестировано в PowerShell 4.0, PowerShell 5.0 (Windows 10) и PowerShell Core 6.0 (Windows 10, Mac и Linux).

Примечание. В Powershell Core символические ссылки не используются при указании переключателя -r. Для перехода по символическим ссылкам укажите переключатель -FollowSymlink с помощью -r.

Документация Get-ChildItem: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem

Ответ 4

Более чистый подход:

Get-ChildItem "<name_of_directory>" | where {$_.Attributes -match'Directory'}

Интересно, имеет ли PowerShell 3.0 переключатель, который возвращает каталоги; это похоже на логическую вещь.

Ответ 5

Использование:

dir -r | where { $_ -is [System.IO.DirectoryInfo] }

Ответ 6

Из PowerShell v2 и new (k представляет собой папку, в которую вы начинаете поиск):

Get-ChildItem $Path -attributes D -Recurse

Если вам просто нужны только имена папок, и ничего больше, используйте это:

Get-ChildItem $Path -Name -attributes D -Recurse

Если вы ищете определенную папку, вы можете использовать следующее. В этом случае я ищу папку под названием myFolder:

Get-ChildItem $Path -attributes D -Recurse -include "myFolder"

Ответ 7

При таком подходе требуется меньше текста:

ls -r | ? {$_.mode -match "d"}

Ответ 8

Использование:

dir -Directory -Recurse | Select FullName

Это даст вам выход корневой структуры с именем папки только для каталогов.

Ответ 9

Использование:

Get-ChildItem \\myserver\myshare\myshare\ -Directory | Select-Object -Property name |  convertto-csv -NoTypeInformation  | Out-File c:\temp\mydirectorylist.csv

Что делает следующее

  • Получить список каталогов в целевом местоположении: Get-ChildItem \\myserver\myshare\myshare\ -Directory
  • Извлечь только имя каталогов: Select-Object -Property name
  • Преобразование вывода в формат CSV: convertto-csv -NoTypeInformation
  • Сохранить результат в файле: Out-File c:\temp\mydirectorylist.csv

Ответ 10

Более легкий и понятный подход может быть достигнут с помощью script ниже:

$Directory = "./"
Get-ChildItem $Directory -Recurse | % {
    if ($_.Attributes -eq "Directory") {
        Write-Host $_.FullName
    }
}

Надеюсь, это поможет!

Ответ 11

Вы хотите использовать Get-ChildItem, чтобы рекурсивно сначала получить все папки и файлы. А затем канал, который выводится в предложение Where-Object, которое принимает только файлы.

# one of several ways to identify a file is using GetType() which
# will return "FileInfo" or "DirectoryInfo"
$files = Get-ChildItem E:\ -Recurse | Where-Object {$_.GetType().Name -eq "FileInfo"} ;

foreach ($file in $files) {
  echo $file.FullName ;
}

Ответ 12

В принятом ответе упоминается

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

чтобы получить "сырую строку". Но на самом деле будут возвращены объекты типа Selected.System.IO.DirectoryInfo. Для необработанных строк можно использовать следующее:

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | % { $_.FullName }

Разница имеет значение, если значение конкатенируется со строкой:

  • с Select-Object suprisingly foo\@{FullName=bar}
  • с ForEach -оператором ожидаемый: foo\bar

Ответ 14

Используйте это:

Get-ChildItem -Path \\server\share\folder\ -Recurse -Force | where {$_.Attributes -like '*Directory*'} | Export-Csv -Path C:\Temp\Export.csv -Encoding "Unicode" -Delimiter ";"

Ответ 15

Чтобы ответить на исходный вопрос конкретно (используя IO.FileAttributes):

Get-ChildItem c:\mypath -Recurse | Where-Object {$_.Attributes -and [IO.FileAttributes]::Directory}

Я предпочитаю решение Марека, хотя (Where-Object { $_ -is [System.IO.DirectoryInfo] }).