Одной из способных привести в замешательство особенностей Windows PowerShell является разнообразие возможностей работы с текстовыми форматами. Ответьте на вопрос: какая разница между этими тремя командами?
Get-Service | Out-File services.txt
Get-Service | Export-CSV services.csv
Get-Service | Export-CliXML services.xml
С технической точки зрения все три команды вернут текстовый файл. Любой из этих файлов можно открыть в Блокноте Windows и прочитать содержимое. Однако в двух из этих файлов текст представляет данные в формате с разделителями. У файлов определенная структура, которая позволяет отделить информацию.
Следующие три команды вполне корректны и выполняются без ошибок:
Get-Content services.txt
Get-Content services.csv
Get-Content services.xml
Но только одна из этих команд имеет смысл. А именно ─ первая. Она просто считывает простой, без разделителей текстовый файл. Нельзя сказать, что текст неформатированный, чтобы убедиться, в этом достаточно взглянуть на сам файл.
Но файл отформатирован для удобства читателя-человека. Текст представлен в удобной таблице со столбцами. Данные представлены в виде, приятном глазу и понятном для наших мозгов. В таком представлении компьютеру сложно найти отдельные элементы данных.
Такая ситуация приводит в замешательство многих новичков, пытающихся использовать Windows PowerShell. Существует простое мнемоническое правило, которое я использую для разрешения проблемы. Полученное из оболочки командой Export нужно возвращать в оболочку командой Import. Если вы не использовали Export, не применяйте Import. Import и Export всегда ходят парой. Поэтому если вы сделали это…:
Get-Service | Export-CSV services.csv
…тогда надо сделать это:
Import-CSV services.csv
Команда Export-CSV получает данные — в данном случае информацию о службах — и записывает их в файл. Отдельные части данных разделены запятыми, потому что так устроен формат CSV. Это означает, что имена сервисов, статусы и все остальное отделено запятыми. При чтении данных с помощью Import-CSV оболочка Windows PowerShell анализирует эти запятые, перераспределяет и восстанавливает данные. Сравните свои результаты с результатами этой команды:
Get-Content services.csv
Эта команда считывает текст, но ничего не делает с ним. Экран заполняется значениями, разделенными запятыми, но Windows PowerShell не отделяет значения. Вы получили сырой, неразобранный текст, который всегда возвращает команда Get-Content. С технической точки зрения Get-Content создает по одному объекту String для каждой строки текстового файла. Это бывает полезным в некоторых ситуациях, но не совсем то, что нужно делать с CSV-файлом.
Вся эта ситуация похожа на то, с чем нам уже приходилось сталкиваться в Windows. Что вы получите, если откроете CSV в Блокноте? Просто много текста. В сущности, именно это и делает Get-Content. А теперь откройте этот же CSV-файл в Excel и посмотрите, что получилось? Приложение разбивает файл, разнося данные по столбцам электронной таблицы. Это очень похоже на то, что делает Import-CSV.
Почему это так важно? Представьте, что вы создали собственный CSV-файл. Создайте в Блокноте примерно такой файл:
Name,SamAccountName,Department,Title,City
DonJ,DonJ,IT,CTO,Las Vegas
GregS,GregS,Custodial,Janitor,Denver
Сохраните файл под именем Users.csv и перейдите в окно Windows PowerShell. Как вы думаете, что сделают эти две команды?
Get-Content Users.csv | New-ADUser
Import-CSV Users.csv | New-ADUser
В обоих случаях предполагается, что вы уже выполнили Import-Module ActiveDirectory для загрузки модуля Microsoft Active Directory, поставляемого в составе Windows Server 2008 R2, а также доступного в пакете средств удаленного администрирования сервера Windows 7 (Remote Server Administration Tools).
Первая команда ничего не будет делать, потому что Get-Content не разбирает файл, а отправляет набор «сырых» строк в New-ADUser. А New-ADUser не сможет сделать с ними ничего полезного.
Вторая команда будет работать, потому что оболочка разберет CSV-файл, разобьет на составляющие и передаст их в New-ADUser. Так как имена элементов данных — Name, samAccountName, Department, Title и City — совпадают с именами параметров New-ADUser, на основе информации из CSV-файла второй командлет создает двух новых пользователей.
Вот чем отличается работа с простым текстом (Out-File и Get-Content) и данными с разделителями (Import/Export). Еще лучше работать с XML-файлами (Export-CliXML и Import-CliXML), потому что они представляют более сложные, в том числе иерархические структуры данных. CSV-файлы представляют собой плоский формат, содержащий только один уровень данных.
Понимание описанных особенностей исключительно важно для понимания того, что можно делать в оболочке. Возможность манипулировать данными в конвейере — вот что делает Windows PowerShell таким мощным инструментом. Обязательно выделите время на то, чтобы разобраться с этими тонкими и не очень различиями.