Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Microsoft PowerShell Windows PowerShell: Такие разные пути к пользовательскому объекту RSS

Windows PowerShell: Такие разные пути к пользовательскому объекту

Текущий рейтинг: 4.5 (проголосовало 2)
 Посетителей: 2173 | Просмотров: 3236 (сегодня 0)  Шрифт: - +

Недавно я сделал запись в своем блоге, где изложил двенадцать рекомендаций по использованию Windows PowerShell. Двенадцатая рекомендация предлагает разработчикам выводить в результате работы сценариев и функций объекты, а не текст. Я предложил активно использующим командлет Write-Host разработчикам остановиться и подумать, что же они делают. Командлет Write-Host не возвращает текст.

Вскоре после публикации этой записи ко мне обратился один читатель с вопросом о коде, который я собственно использовал для создания пользовательского объекта. Он сказал, что никогда не еще не встречался с таким подходом. Это неудивительно, потому что Windows PowerShell предоставляет десятки способов выполнения одной и той же задачи. Читатель предложил мне написать статью о различных способах создания пользовательских объектов, и это именно эта статья.

Полноформатный способ

Скорее всего, именно этим способом большинство людей создают пользовательские объекты. Этот подход я называю «хрестоматийным». Его отличает максимальная четкость, но он предусматривает много работы по вводу текста. Если у меня есть по одному объекту в переменных $os и $bios, я могу скомбинировать имеющуюся информацию так:

$object = New-Object –TypeNamePSObject
$object | Add-Member –MemberTypeNoteProperty –Name OSBuild –Value $os.BuildNumber
$object | Add-Member –MemberTypeNoteProperty –Name OSVersion –Value $os.Version
$object | Add-Member –MemberTypeNoteProperty –Name BIOSSerial –Value $bios.SerialNumber
Write-Output $object

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

Короткий путь с -PassThru

Первый способ можно сделать чуть более лаконичным, заставив Add-Member вернуть объект в конвейер:

$object = New-Object –TypeNamePSObject
$object | Add-Member –MemberTypeNoteProperty –Name OSBuild –Value $os.BuildNumber –PassThru |
Add-Member –MemberTypeNoteProperty –Name OSVersion –Value $os.Version –PassThru |
Add-Member –MemberTypeNoteProperty –Name BIOSSerial –Value $bios.SerialNumber
Write-Output $object

Если строка заканчивается вертикальной чертой (|), Windows PowerShell ожидает увидеть в следующей физической строке следующую команду в конвейере. В сущности, это способ разбиения длинной команды на несколько строк. Этот прием вместе с параметром –PassThru превращает это в серию из трех разных команд.

Хеш-таблицы, вперед!

Описанные способы эффективны, но при этом «многословны». В сценарии бывает сложно визуально проследить, что происходит. New-Object предоставляет возможность решить задачу более лаконично. Это позволяет создать хеш-таблицу (или ассоциативный массив), содержащую имена свойств и значения, которые надо добавить ко вновь созданному объекту. Каждое из этих свойств автоматически создается как свойство NoteProperty:

$properties = @{'OSBuild'=$os.BuildNumber;
                'OSVersion'=$os.version;
                'BIOSSerial'=$bios.SerialNumber}
$object = New-Object –TypeNamePSObject –Prop $properties
Write-Output $object

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

$object = New-Object –TypeNamePSObject –Prop
(@{'OSBuild'=$os.BuildNumber;
                'OSVersion'=$os.version;
                'BIOSSerial'=$bios.SerialNumber})
Write-Output $object

Еще один шажок

Вы заметили, что во всех этих примерах перед передачей пользовательского объекта по конвейеру я сохраняю его в переменной $object. Причина проста: может потребоваться дополнительно поработать с объектом. Например, можно дать объекту имя пользовательского типа:

$object.PSObject.TypeNames.Insert(0,'My.Custom.Name')

Это позволяет создать пользовательский формат для отображения вашего объекта. Я использовал этот прием с замечательными результатами в «Windows PowerShell Scripting and Toolmaking» (Concentrated Technology and Interface Technical Training, 2011), краткой книге, которую я написал и в которой рассказал о таких вещах, как использование пользовательских объектов для вывода данных из пользовательских средств Windows PowerShell.

На любой вкус и цвет…

Не существует «неправильных» способов решения задач в Windows PowerShell, если в конечном итоге вы решаете поставленную задачу. Вместе с тем, есть ряд приемов, которые я стараюсь не использовать, в основном из-за того, что они менее читабельны и сложнее для преподавания, особенно для начинающих пользователей. Вот один из таких приемов, в котором, как и раньше, предполагается, что переменные $os и $bios содержат объекты, из которых мне нужно извлечь информацию:

$os | Select-Object –Property @{n='OSVersion';e={$_.Version}},
@{n='OSBuild';e={$_.BuildNumber}},
@{n='BIOSSerial';e={$bios.SerialNumber}}

Результат будет таким же, что и в предыдущих примерах, но синтаксис ужасен. Здесь масса пунктуации, структурных особенностей и нужно знать много других вещей о Select-Object, чтобы справиться с этими тремя хеш-таблицами.

Здесь фактически генерируются пользовательские свойства средствами синтаксиса, присущего этому конкретному командлету (и еще командлетам Format). Такой синтаксис обычно характерен для людей с программистским опытом. Для меня (и многих других) разбирать такой текст очень трудно, поэтому я стараюсь не писать в таком стиле.

Оболочка PowerShell ничто, если она не гибкая

Уникальность Windows PowerShell в том, что она позволяет делать некоторые по-настоящему дикие вещи. Вернемся к моему примеру с хеш-таблицами. Задачу можно решить и так:

$info = @{}
$info.OSBuild=$os.BuildNumber
$info.OSVersion=$os.version
$info.BIOSSerial=$bios.SerialNumber
$object = New-Object –TypeNamePSObject –Prop $info
Write-Output $object

Мы создаем пустую хеш-таблицу, а затем добавляем информацию, ссылающуюся на несуществующие свойства. Например, при попытке впервые обратиться к OSBuild оболочка Windows PowerShell понимает, что в объекте $info (которые представляет собой пустую хеш-таблицу) такого свойства не существует. Но она просто создает это свойство и присваивает ему значение. Совершенно безбашенная вещь, тем не менее работает.

Мораль: объекты, а не текст

Как бы вы не создавали свои пользовательские объекты, можно создавать объекты, а не возвращать в окно консоли простой текст. Объекты намного гибче и позволяют интегрировать код сценария или функции с любыми другими компонентами Windows PowerShell.

Автор: Дон Джонс  •  Иcточник: TechNet Magazine  •  Опубликована: 12.04.2012
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER
Теги:   Powershell.


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.