Особенности использования командлета Get-ChildItem
Командлет Get-ChildItem предназначен для получения списка папок и файлов, находящихся на диске. Он имеет множество алиасов (gci, dir, ls) и является одним из наиболее популярных командлетов для работы с файловой системой. Get-ChildItem достаточно прост в применении, но имеет некоторые особенности, знание которых может помочь более эффективно его использовать.
Для тестирования возьмем папку C:\Files, накидаем в нее мусора разных файлов и папок и проверим на ней работу командлета с различными параметрами.
Путь
Суть работы командлета Get-ChildItem заключается в том, что он берет заданный объект (диск или директорию) и выводит список его дочерних элементов. Путь к нужному объекту указывается с помощью параметра -Path. Например, для просмотра содержимого папки C:\Files надо выполнить команду:
1 |
Get-ChildItem -Path ″C:\Files″ |
Само название параметра указывать не обязательно, можно указать только его значение:
1 |
Get-ChildItem ″C:\Files″ |
А если перейти в нужную папку, то путь можно вообще не указывать. В качестве пути по умолчанию используется текущая директория, поэтому для получения списка объектов достаточно выполнить команду:
1 |
Get-ChildItem |
Путь может быть как абсолютным, так и относительным. Например просмотреть содержимое папки Books, находящейся внутри C:\Files, можно такой командой:
1 |
Get-ChildItem -Path ″C:\Files\Books″ |
а можно такой:
1 |
Get-ChildItem -Path ″Books″ |
В параметре -Path допускается использование подстановочных символов (wildcards), что позволяет отфильтровывать нужные результаты. Так следующая команда выводит все файлы с расширением .txt, находящиеся в текущей директории:
1 |
Get-ChildItem -Path ″*.txt″ |
А так мы получим все файлы и папки, имеющие в названии слово Book:
1 |
Get-ChildItem -Path ″Book*″ |
С помощью подстановочных символов можно реализовать и более сложные фильтры. Для примера выведем содержимое всех папок в текущей директории, имеющих в своем имени слово Book:
1 |
Get-ChildItem -Path ″Book*\*″ |
И еще усложним задачу и запросим файлы с расширением .pdf из подпапок, находящихся в папках, имеющих в своем имени слово Book:
1 |
Get-ChildItem -Path ″Book*\*\*.pdf″ |
Кроме -Path командлет Get-ChildItem имеет параметр -LiteralPath, с помощью которого также можно указывать путь. Это параметр отличается от -Path тем, что при его использовании все служебные символы интерпретируются как обычные, т.е. символы подстановки использовать нельзя. Например при использовании -LiteralPath такая команда отработает корректно:
1 |
Get-ChildItem -LiteralPath ″Books″ |
а такая вызовет ошибку:
1 |
Get-ChildItem -LiteralPath ″Book*″ |
Имена
По умолчанию командлет Get-ChildItem выводит данные в следующем формате — имя объекта, размер (для файлов), дата и время последнего изменения и список атрибутов. Если весь этот набор не нужен, то можно задействовать специальный параметр -Name, который возвращает только имена найденных объектов. Например так выведем имена всех файлов и папок, находящихся в папке Books:
1 |
Get-ChildItem -Path ″Books″ -Name |
Параметр -Name может принимать определенное значение и позволяет использование подстановочных символов. Немного модифицируем предыдущую команду и выведем только имена объектов, находящихся в папке Books и имеющих в своем имени слово Bible:
1 |
Get-ChildItem -Path ″Books″ -Name ″*Bible*″ |
Рекурсия
По умолчанию Get-ChildItem выводит только объекты, находящиеся в корне указанной директории. Для просмотра содержимого всех дочерних элементов необходимо использовать командлет с параметром -Recurse. Например, вывести содержимое папки Books, включая содержимое всех находящихся в ней подпапок, можно командой:
1 |
Get-ChildItem -Path ″Books″ -Recurse |
Сравните с выводом команды без -Recurse и ощутите разницу.
При использовании рекурсии командлет производит поиск по всем вложенным директориям, независимо от глубины вложения. Ограничить уровень вложения можно с помощью параметра -Depth, появившегося в PowerShell 5.0. Для примера выведем содержимое папки Books и всех вложенных подпапок до второго уровня вложения:
1 |
Get-ChildItem -Path ″Books″ -Recurse -Depth 2 |
Атрибуты
Каждый объект файловой системы может иметь один или несколько атрибутов. Атрибуты используются для определения типа объекта (файл или директория) и прочих его особенностей (скрытый, системный, архивный и т.п.).
Для работы с атрибутами у командлета Get-ChildItem есть несколько различных способов. Так если нам требуется вывести только директории из нашей папки C:\Files, то можно воспользоваться параметром -Directory:
1 |
Get-ChildItem -Directory |
Ограничить вывод только файлами можно получить с помощью параметра -File:
1 |
Get-ChildItem -File |
А для выбора скрытых и системных объектов служат соответственно параметры -Hidden и -System. Эти параметры можно использовать совместно, например получить все скрытые и системные файлы можно командой:
1 |
Get-ChildItem -File -Hidden -System |
Также для указания атрибутов можно использовать параметр -Attributes. Поддерживаются следующие атрибуты:
• Archive
• Compressed
• Device
• Directory
• Encrypted
• Hidden
• Normal
• NotContentIndexed
• Offline
• ReadOnly
• ReparsePoint
• SparseFile
• System
• Temporary
Полный список и подробное описание атрибутов файловой системы можно найти здесь
https://learn.microsoft.com/en-us/dotnet/api/system.io.fileattributes?view=net-7.0
Например для вывода только директорий подойдет такая команда:
1 |
Get-ChildItem -Attributes Directory |
а для показа скрытых объектов такая:
1 |
Get-ChildItem -Attributes Hidden |
Для наиболее популярных атрибутов имеются сокращения:
D — (Directory)
H — (Hidden)
R — (Read-only)
S — (System)
При указании нескольких атрибутов можно использовать логические операторы:
• Запятая — оператор ИЛИ (OR)
• Плюс — оператор И (AND)
• Восклицательный знак — оператор НЕ (NOT)
Для примера возьмем три атрибута — D (директория), H (скрытый) и S (системный). Следующая команда выдаст все объекты, имеющие хотя бы один из перечисленных атрибутов:
1 |
Get-ChildItem -Attributes D,H,S |
Если требуется вывести объекты, имеющие в наличии все три атрибута (скрытые системные директории) можно воспользоваться такой командой:
1 |
Get-ChildItem -Attributes D+H+S |
А теперь немного модифицируем предыдущую команду с помощью оператора НЕ и получим только скрытые и системные файлы:
1 |
Get-ChildItem -Attributes !D+H+S |
Здесь атрибут !D значит не директория, соответственно команда выводит все объекты кроме директорий, т.е. только файлы.
И еще один параметр, имеющий некое отношение к атрибутам. По умолчанию Get-ChildItem не показывает файлы и папки, имеющие атрибуты скрытый и системный. Поэтому, если требуется показать все без исключения, необходимо использовать командлет с параметром -Force:
1 |
Get-ChildItem -Force |
Фильтры
Задача Get-ChildItem заключается в том, чтобы вывести только нужные объекты и отфильтровать ненужные. Для фильтрации результатов у него имеются три специальных параметра.
Параметр -Filter предназначен для фильтрации выводимых результатов и в качестве значения может принимать имя элемента, также допускается использование подстановочных символов. Для примера выведем список всех объектов, находящихся в папке C:\Files и имеющих в своем имени слово book:
1 |
Get-ChildItem -Path ″C:\Files″ -Filter ″*book*″ -Recurse |
А так получим все файлы с расширением .docx:
1 |
Get-ChildItem -Path ″C:\Files″ -Filter ″*.docx″ -Recurse |
Стоит заметить, что получить нужный результат можно различными способами. Например следующая команда выдаст такой же результат, что и предыдущая:
1 |
Get-ChildItem -Path ″C:\Files\*.docx″ -Recurse |
В PowerShell 2.0 (и более ранних версий) рекурсия работает только в том случае, если путь указывает на объект, имеющий дочерние элементы (напр. C:\Files), и не работает, если в пути указан объект без дочерних элементов (напр. C:\Files\*.docx). Т.е. команда, приведенная выше, работает только в PowerShell 3.0 и выше.
Способы фильтрации можно совмещать. Например так получим все файлы с расширением .docx, имеющие в своем имени слово book:
1 |
Get-ChildItem -Path ″C:\Files\*.docx″ -Filter ″*book*″ -Recurse |
Также как и -Filter, парметры -Include и -Exclude предназначены для фильтрации вывода и понимают символы подстановки. Но между ними есть одно фундаментальное отличие: при использовании -Filter результаты отфильтровываются непосредственно в процессе получения данных (папок и файлов), а -Include и -Exclude применяются уже после того, как все данные получены. Соответственно в одинаковой ситуации команда с использованием -Filter отработает более быстро и эффективно. Впрочем, заметить разницу получится только при достаточно большом объеме данных.
Параметр -Include предназначен для вывода только указанных в нем элементов. Однако у него есть одна ″интересная″ особенность, о которой нужно знать — в качестве значения параметра должны быть указаны все элементы, включая директорию, в которой производится поиск. Для примера попробуем вывести все файлы с расширением .pdf, находящиеся в папке C:\Files\Books:
1 |
Get-ChildItem -Path ″C:\Files\Books″ -Include ″*.pdf″ |
Как видите, команда не дает никакого результата, хотя нужные файлы там есть. Для получения результата команду необходимо изменить, например так:
1 |
Get-ChildItem -Path ″C:\Files\Books\*″ -Include ″*.pdf″ |
или так:
1 |
Get-ChildItem -Path ″C:\Files\Books″ -Include ″books″,″*.pdf″ |
Также в данной ситуации может помочь использование рекурсии:
1 |
Get-ChildItem -Path ″C:\Files\Books″ -Include ″*.pdf″ -Recurse |
Одним из преимуществ -Enclude (и -Exclude) является то, что в отличии от -Filter они могут принимать множественные значения. К примеру, вывести все архивные файлы из C:\Files можно такой командой:
1 |
Get-ChildItem -Path ″C:\Files″ -Include ″*.zip″,″*.rar″,″*.7z″ -Recurse |
Параметр -Exclude имеет действие, обратное -Include, т.е. исключает указанные элементы из выводимых данных. Например так получим все объекты в текущей директории кроме файлов и папок, имеющих в своем названии слово IIS:
1 |
Get-ChildItem -Path ″C:\Files″ -Exclude ″*IIS*″ |
а так выведем все файлы из C:\Files\Books, кроме PDF-файлов:
1 |
Get-ChildItem -Path ″C:\Files\Books″ -Exclude ″*.pdf″ -File -Recurse |
Как я уже говорил, способы фильтрации можно комбинировать. Например выведем все исполняемые файлы, находящиеся в C:\Files, включая скрытые и системные:
1 |
Get-ChildItem -Path ″C:\Files\Books\*.exe″ -Force |
А затем отбросим результаты, у которых в имени имеется IIS:
1 |
Get-ChildItem -Path ″C:\Files\Books\*.exe″ -Force -Exclude ″*IIS*″ |
Еще вариант — возьмем все объекты с именем IIS:
1 |
Get-ChildItem -Include ″*IIS*″ -Recurse |
и выкинем из результата исполняемые файлы:
1 |
Get-ChildItem -Include ″*IIS*″ -Exclude ″*.exe″ -Recurse |
Ну и напоследок запросим все файлы с расширением .pdf, имеющие в названии слово Windows без слова Server:
1 |
Get-ChildItem -Path ″C:\Files\*.pdf″ -Filter ″*windows*″ -Exclude ″*server*″ -Recurse |
Как видите, Get-ChildItem позволяет очень гибко управлять выдаваемыми результатами, и даже без использования регулярных выражений.