.

Как работает форматирование

Если не углубляться в технические подробности, можно сказать, что форматирование в PowerShell работает следующим образом: в конце конвейера оболочка PowerShell анализирует оставшиеся объекты и определяет их тип. Затем оболочка PowerShell просматривает набор настроек XML в поисках инструкций по форматированию каждого из типов объектов. В ходе поиска может быть обнаружен заданный по умолчанию формат отображения таблицы или списка. В этом случае оболочка PowerShell передает объекты соответствующей команде форматирования, которая выводит результаты на экран. В других случаях оболочка PowerShell может найти только заданный по умолчанию список свойств. Исходя из количества свойств оболочка PowerShell определит, какой формат отображения — таблица или список – ей нужен, и вызовет соответствующую команду форматирования. В крайнем случае, если инструкции не найдены, PowerShell отобразит все свойства объекта.

Вы можете изменить эту последовательность, напрямую задавая команды форматирования. Скорее всего, вы будете использовать следующие команды форматирования: Format-Wide, Format-Table и Format-List.

Как применять команду Format-Wide

Команда Format-Wide, имеющая псевдоним fw, будет отображать по одному свойству в широком формате. Работая в оболочке Windows Cmd.exe, вы могли использовать такую команду как dir /w, чтобы увидеть список каталогов в широком формате. Команда Format-Wide позволяет делать то же самое для объектов любого типа. Например, следующая команда выводит результаты команды Get-Process в широком формате:

Get-Process | Format-Wide

Результаты показаны на экране 1.

 

Результаты команды Get-Process в широком формате
Экран 1. Результаты команды Get-Process в широком формате

При работе с командой Format-Wide большинство объектов возвращают заданное по умолчанию свойство, и обычно оно содержит имя. Однако вы можете указать другие свойства. Например, вместо того, чтобы в широком формате отображать имена служб, можно отобразить свойство DisplayName с помощью команды:

Get-Service | Where-Object {$_.status -eq 'running'} |
Format-Wide -Property DisplayName

Команда Format-Wide обычно неплохо справляется с задачей отображения максимального количества информации, но при желании вы можете выполнить тонкую настройку. Так, когда в нашем первом примере выходные данные команды Get-Process были переданы команде Format-Wide, результаты отображались на экране в виде двух столбцов (см. экран 1). Вы можете заставить команду Format-Wide задействовать большее количество столбцов, используя параметр -Column:

Get-Process | Format-Wide -Column 3

Теперь, как показано на экране 2, результаты распределены по трем столбцам.

 

Вывод Format-Wide в три столбца
Экран 2. Вывод Format-Wide в три столбца

Вы можете заставить команду Format-Wide сжать результаты настолько, насколько она сможет, используя параметр -AutoSize. Например, следующая команда возвращает имена служб, которые начинаются с буквы m, выводя на экран максимально возможное количество данных:

Get-Service m* | fw -AutoSize

Обратите внимание, что в данном примере я использую псевдоним fw. Результаты приведены на экране 3.

 

Результаты работы параметра -AutoSize
Экран 3. Результаты работы параметра -AutoSize

Возможно, вы захотите объединить в команде Format-Wide функции автоматического определения размера и группировки. При использовании параметра -GroupBy PowerShell отформатирует информацию на выходе на основе указанных свойств. Но будьте осторожны. Посмотрите на эту команду:

Get-Service | fw -GroupBy Status -AutoSize

Можно подумать, что она получает имена служб и выводит их в широком формате, сгруппировав по свойству Status. Но взгляните на результат на экране 4. Думаю, вы ожидали увидеть совсем другое. Оболочка PowerShell получала объекты служб и форматировала их. Эта проблема легко решается путем предварительной сортировки с помощью команды Sort-Object, имеющей псевдоним sort:

Get-Service w* | sort Status | fw -GroupBy Status -AutoSize

 

Форматирование по мере получения данных
Экран 4. Форматирование по мере получения данных

Данная команда возвращает только те службы, которые начинаются на букву w, так что вы можете просмотреть все результаты (экран 5). Анализируя результаты, обратите внимание, что остановленные службы выводятся в пять столбцов, а для отображения работающих служб используются всего четыре столбца. Результаты выполнения функции автоматического определения размера будут различаться в зависимости от длины каждого свойства.

 

Форматирование с предварительной сортировкой
Экран 5. Форматирование с предварительной сортировкой

Параметр -GroupBy поддерживается многими командами форматирования. Параметр -AutoSize поддерживается как командой Format-Wide, так и командой Format-Table, которую мы рассмотрим далее.

Как применять команду Format-Table

Судя по имени, команда Format-Table, имеющая псевдоним ft, форматирует данные в виде таблицы. В большинстве случаев форматирование результатов в виде таблицы производится администраторами, но оболочка PowerShell нередко выполняет форматирование «по умолчанию». Например, запуская команду

Get-Process

мы получаем тот же результат, что и при запуске команды

Get-Process | Format-Table

Оболочка PowerShell с помощью набора файлов конфигурации определяет, что выводить на экран и каким образом. Некоторые типы объектов имеют предопределенные форматы вывода данных. В данном случае файлы конфигурации сообщают оболочке PowerShell, что нужно обрабатывать объекты как таблицы. Теоретически, это означает, что вам не придется добавлять команду Format-Table при использовании команды Get-Process, если требуется, чтобы результаты были сформатированы в виде таблицы. Однако сколько раз придется запустить команду, чтобы понять, что формат выходных данных не оптимален? Возьмем, например, команду Select-Object (псевдоним select), чтобы получить значения таких свойств, как ID, Name и WorkingSet (WS):

Get-Process | Select ID, Name, WS

Как мы видим на экране 6, данные выведены в виде таблицы, но ее расположение и размеры не идеальны. Оболочка PowerShell сделала все возможное, но выбрать свойства — еще не значит отформатировать их. Вы можете помочь, передав результаты команде Format-Table с параметром –AutoSize и заставив оболочку PowerShell автоматически настроить размер результатов в таблице:

Get-Process | select ID,Name,WS |
Format-Table -AutoSize

 

Результаты работы Select-Object
Экран 6. Результаты работы Select-Object

Как мы видим на экране 7, вид выходных данных улучшился.

 

Новый вид результатов работы Select-Object
Экран 7. Новый вид результатов работы Select-Object

Если вы с самого начала знаете, что выходные данные должны быть отформатированы в виде таблицы, то можете пропустить шаг с использованием команды Select-Object и просто указать свойства при вызове команды Format-Table:

Get-Process | Format-Table ID,Name,WS -AutoSize

Выходные данные будут иметь такой же вид. Если вам нужно лишь проанализировать результаты, то такой подход – идеальное решение. Но в форматировании есть подводные камни, с которыми сталкивается большинство новичков при работе с PowerShell. Мы рассмотрим их чуть позже.

Помимо параметра -AutoSize, есть еще один параметр команды Format-Table, которую вы будете часто использовать — это –View. Под «представлением» в данном случае понимается альтернативная структура. При использовании данного параметра оболочка PowerShell будет применять один из альтернативных форматов вывода. Например, если вы запустите следующую команду, то получите на выходе другой набор свойств, автоматически сгруппированных по свойству PriorityClass:

Get-Process | sort PriorityClass | ft -View Priority

Обратите внимание, что я использую псевдоним ft, который в итоге вы, скорее всего, будете применять часто. Кроме того, отметьте, что я провел предварительную сортировку, чтобы улучшить внешний вид выходных данных, по аналогии с тем, как я поступил при работе с командой Format-Wide. Экран 8 позволит вам представить, как будут выглядеть результаты. Возможно, вы получите сообщения об ошибках, так как некоторые процессы, такие как Idle и System, защищены. Можете проигнорировать их.

 

Альтернативный формат вывода
Экран 8. Альтернативный формат вывода

Вот еще один пример, который я оставлю вам для изучения:

Get-Process | sort StartTime | ft -View StartTime

Как и предыдущая, эта команда может генерировать ошибки, так как для некоторых процессов не будет прописано время запуска.

Изучение альтернативных представлений потребует небольшого расследования. Для определения типа объекта используется команда Get-Member. В случае последнего примера с командой Get-Process необходимо запустить команду:

Get-Process | Get-Member

Результаты показывают, что объект имеет тип System.Diagnostics.Process. Далее для раскрытия свойства определения запускается следующая команда:

Get-FormatData System.Diagnostics.Process |
Select -ExpandProperty FormatViewDefinition

В результатах на экране 9 столбец Name содержит имена представлений. Столбец Control дает подсказку, какая команда форматирования применяется для построения соответствующего представления. Имейте в виду, что вы не обязательно сможете просмотреть список представлений для каждого типа объекта, так что, возможно, вам все равно придется провести немало тестов вручную.

 

Получение имен представлений
Экран 9. Получение имен представлений

Как применять команду Format-List

Еще один из возможных способов форматирования — список. Вы можете дать оболочке PowerShell указание организовать выходные данные в виде списка, используя команду Format-List, имеющую псевдоним fl. Например, если вы запустите следующую команду, то обнаружите, что PowerShell отформатировал результаты в виде таблицы:

Get-Process | select ID,Name,WS,VM

Если в качестве формата выходных данных вам больше подходит список, то вы можете передать результаты команде Format-List следующим образом:

Get-Process | select ID,Name,WS,VM | Format-List

Результаты приведены на экране 10.

 

Вывод в виде списка
Экран 10. Вывод в виде списка

Как и все команды форматирования, команда Format-List позволяет выбрать для отображения одно или несколько свойств. Вы даже можете использовать подстановочные знаки, например «звездочка» (*) позволяет выбрать все свойства.

Хотя передача выходных данных команды Get-Process в команду Get-Member может помочь определить свойства объекта, иногда этот подход помогает даже просмотреть значения свойств. Лучший способ использования команды Format-List – выбрать отдельный объект и отобразить все его свойства и их значения:

Get-Process winword | fl *

При таком формате выходных данных, как на экране 11, вы лучше поймете назначение каждого свойства и сможете построить более подробную команду.

 

Просмотр свойств отдельного объекта
Экран 11. Просмотр свойств отдельного объекта

Как и в случае с командой Format-Table, команда Format-List может иметь разные представления, определенные для разных типов объектов. Возьмем, например, команду:

Get-Service | fl

Результаты на экране 12 показывают, что оболочка PowerShell имеет представление, заданное для объектов служб при форматировании их выходных данных в виде списка.

 

Представление для объектов служб
Экран 12. Представление для объектов служб

Чтобы получить информацию обо всех доступных представлениях, вы можете попробовать задействовать команду Get-FormatData и поискать значение ListControl в столбце Control. С другой стороны, можно поэкспериментировать с передачей результатов команд Format-Table и Format-List.

Форматирование в конце

Как вы могли заметить, во всех моих примерах команды форматирования использовались в конце. В классах и на форумах я часто вижу новичков в PowerShell, которые пытаются сделать что-то вроде этого:

Get-ChildItem C:scripts*.ps1 |
ft name,length,LastWriteTime,CreationTime |
Export-CSV C:workfiles.csv

Однако просматривая результирующий. csv файл, они видят нечто бессвязное. Есть еще одна команда, которая будет выполнена неправильно, но, по крайней мере, появится сообщение об ошибке, объясняющее причины:

Get-ChildItem C:scripts*.ps1 |
ft name,length,LastWriteTime,CreationTime |
sort Length

На экране 13 приведено сообщение об ошибке. Как всегда, его сложно понять, поэтому я объясню, что к чему. Когда вы вызываете одну из команд форматирования, она создает еще один тип объектов и отсылает их обратно оболочке PowerShell. Итак, в ошибочной команде Format-Table прописал объекты директивы форматирования в конвейер, а оболочка PowerShell затем попыталась отсортировать их по свойству Length. Но в этот момент конвейер уже не работал с файловыми объектами, поэтому команда завершилась неудачно. Это сбивает с толку, так как если вы замените Format-Table на команду Select-Object, она отработает корректно.

 

Ошибочная команда
Экран 13. Ошибочная команда

Золотое правило гласит, что команда форматирования должна быть последней частью команды PowerShell. Пока вы не пытаетесь что-либо дописать после команды форматирования, проблем у вас быть не должно. Предполагается, что вы используете форматирование, чтобы сделать результаты более удобными для чтения — и ничего больше. Однако есть одно исключение. Вы можете передавать любые отформатированные результаты любой команде типа Out, такой как Out-File или Out-Printer. Например, следующая команда передает результаты команды Format-Table на вход команде Out-File:

Get-ChildItem C:scripts*.ps1 |
ft name,length,LastWriteTime,CreationTime |
Out-File C:workscripts.txt

Оболочка PowerShell перехватит выходные данные, которые вы видите на экране, и перенаправит их в файл.

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