Заметки сисадмина » Особенности использования командлета Get-ChildItem

Заметки сисадмина о интересных вещах из мира IT, инструкции и рецензии. Настраиваем Компьютеры/Сервера/1С/SIP-телефонию в Москве

Особенности использования командлета Get-ChildItem

2020-08-03 · Posted in PowerShell

Командлет Get-ChildItem предназначен для получения списка папок и файлов, находящихся на диске. Он имеет множество алиасов (gci, dir, ls) и является одним из наиболее популярных командлетов для работы с файловой системой. Get-ChildItem достаточно прост в применении, но имеет некоторые особенности, знание которых может помочь более эффективно его использовать.

Для тестирования возьмем папку C:\Files, накидаем в нее мусора разных файлов и папок и проверим на ней работу командлета с различными параметрами.

Путь

Суть работы командлета Get-ChildItem заключается в том, что он берет заданный объект (диск или директорию) и выводит список его дочерних элементов. Путь к нужному объекту указывается с помощью параметра -Path. Например, для просмотра содержимого папки C:\Files надо выполнить команду:

Само название параметра указывать не обязательно, можно указать только его значение:

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

Путь может быть как абсолютным, так и относительным. Например просмотреть содержимое папки Books, находящейся внутри C:\Files, можно такой командой:

а можно такой:

В параметре -Path допускается использование подстановочных символов (wildcards), что позволяет отфильтровывать нужные результаты. Так следующая команда выводит все файлы с расширением .txt, находящиеся в текущей директории:

А так мы получим все файлы и папки, имеющие в названии слово Book:

С помощью подстановочных символов можно реализовать и более сложные фильтры. Для примера выведем содержимое всех папок в текущей директории, имеющих в своем имени слово Book:

И еще усложним задачу и запросим файлы с расширением .pdf из подпапок, находящихся в папках, имеющих в своем имени слово Book:

Кроме -Path командлет Get-ChildItem имеет параметр -LiteralPath, с помощью которого также можно указывать путь. Это параметр отличается от -Path тем, что при его использовании все служебные символы интерпретируются как обычные, т.е. символы подстановки использовать нельзя. Например при использовании -LiteralPath такая команда отработает корректно:

а такая вызовет ошибку:

Имена

По умолчанию командлет Get-ChildItem выводит данные в следующем формате — имя объекта, размер (для файлов), дата и время последнего изменения и список атрибутов. Если весь этот набор не нужен, то можно задействовать специальный параметр -Name, который возвращает только имена найденных объектов. Например так выведем имена всех файлов и папок, находящихся в папке Books:

Параметр -Name может принимать определенное значение и позволяет использование подстановочных символов. Немного модифицируем предыдущую команду и выведем только имена объектов, находящихся в папке Books и имеющих в своем имени слово Bible:

Рекурсия

По умолчанию Get-ChildItem выводит только объекты, находящиеся в корне указанной директории. Для просмотра содержимого всех дочерних элементов необходимо использовать командлет с параметром -Recurse. Например, вывести содержимое папки Books, включая содержимое всех находящихся в ней подпапок, можно командой:

Сравните с выводом команды без -Recurse и ощутите разницу.

При использовании рекурсии командлет производит поиск по всем вложенным директориям, независимо от глубины вложения. Ограничить уровень вложения можно с помощью параметра -Depth, появившегося в PowerShell 5.0. Для примера выведем содержимое папки Books и всех вложенных подпапок до второго уровня вложения:

Атрибуты

Каждый объект файловой системы может иметь один или несколько атрибутов. Атрибуты используются для определения типа объекта (файл или директория) и прочих его особенностей (скрытый, системный, архивный и т.п.).

Для работы с атрибутами у командлета Get-ChildItem есть несколько различных способов. Так если нам требуется вывести только директории из нашей папки C:\Files, то можно воспользоваться параметром -Directory:

Ограничить вывод только файлами можно получить с помощью параметра -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

Например для вывода только директорий подойдет такая команда:

а для показа скрытых объектов такая:

Для наиболее популярных атрибутов имеются сокращения:

D — (Directory)
H — (Hidden)
R — (Read-only)
S — (System)

При указании нескольких атрибутов можно использовать логические операторы:

• Запятая — оператор ИЛИ (OR)
• Плюс — оператор И (AND)
• Восклицательный знак — оператор НЕ (NOT)

Для примера возьмем три атрибута — D (директория), H (скрытый) и S (системный). Следующая команда выдаст все объекты, имеющие хотя бы один из перечисленных атрибутов:

Если требуется вывести объекты, имеющие в наличии все три атрибута (скрытые системные директории) можно воспользоваться такой командой:

А теперь немного модифицируем предыдущую команду с помощью оператора НЕ и получим только скрытые и системные файлы:

Здесь атрибут !D значит не директория, соответственно команда выводит все объекты кроме директорий, т.е. только файлы.

И еще один параметр, имеющий некое отношение к атрибутам. По умолчанию Get-ChildItem не показывает файлы и папки, имеющие атрибуты скрытый и системный. Поэтому, если требуется показать все без исключения, необходимо использовать командлет с параметром -Force:

Фильтры

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

Параметр -Filter предназначен для фильтрации выводимых результатов и в качестве значения может принимать имя элемента, также допускается использование подстановочных символов. Для примера выведем список всех объектов, находящихся в папке C:\Files и имеющих в своем имени слово book:

А так получим все файлы с расширением .docx:

Стоит заметить, что получить нужный результат можно различными способами. Например следующая команда выдаст такой же результат, что и предыдущая:

В PowerShell 2.0 (и более ранних версий) рекурсия работает только в том случае, если путь указывает на объект, имеющий дочерние элементы (напр. C:\Files), и не работает, если в пути указан объект без дочерних элементов (напр. C:\Files\*.docx). Т.е. команда, приведенная выше, работает только в PowerShell 3.0 и выше.

Способы фильтрации можно совмещать. Например так получим все файлы с расширением .docx, имеющие в своем имени слово book:

 

Также как и -Filter, парметры -Include и -Exclude предназначены для фильтрации вывода и понимают символы подстановки. Но между ними есть одно фундаментальное отличие: при использовании -Filter результаты отфильтровываются непосредственно в процессе получения данных (папок и файлов), а -Include и -Exclude применяются уже после того, как все данные получены. Соответственно в одинаковой ситуации команда с использованием -Filter отработает более быстро и эффективно. Впрочем, заметить разницу получится только при достаточно большом объеме данных.

Параметр -Include предназначен для вывода только указанных в нем элементов. Однако у него есть одна ″интересная″ особенность, о которой нужно знать — в качестве значения параметра должны быть указаны все элементы, включая директорию, в которой производится поиск. Для примера попробуем вывести все файлы с расширением .pdf, находящиеся в папке C:\Files\Books:

Как видите, команда не дает никакого результата, хотя нужные файлы там есть. Для получения результата команду необходимо изменить, например так:

или так:

Также в данной ситуации может помочь использование рекурсии:

Одним из преимуществ -Enclude (и -Exclude) является то, что в отличии от -Filter они могут принимать множественные значения. К примеру, вывести все архивные файлы из C:\Files можно такой командой:

Параметр -Exclude имеет действие, обратное -Include, т.е. исключает указанные элементы из выводимых данных. Например так получим все объекты в текущей директории кроме файлов и папок, имеющих в своем названии слово IIS:

а так выведем все файлы из C:\Files\Books, кроме PDF-файлов:

Как я уже говорил, способы фильтрации можно комбинировать. Например выведем все исполняемые файлы, находящиеся в C:\Files, включая скрытые и системные:

А затем отбросим результаты, у которых в имени имеется IIS:

Еще вариант — возьмем все объекты с именем IIS:

и выкинем из результата исполняемые файлы:

Ну и напоследок запросим все файлы с расширением .pdf, имеющие в названии слово Windows без слова Server:

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

Leave a Reply