Массивы и таблицы хеширования – две наиболее важных структуры данных, доступные в современных языках написания сценариев. Оболочка Windows PowerShell (http://www.windowsitpro.com/topics/powershell-scripting) поддерживает обе эти структуры. Массив, который иногда называют «коллекцией», содержит список элементов. Таблица хеширования, которую еще называют «словарем» или «массивом ассоциаций», содержит списки пар элементов. Далее в статье я покажу, как создавать массивы и таблицы хеширования, а также получать доступ к их элементам.

Создание массива

Массивы полезны в тех случаях, когда вы собираетесь хранить и просматривать список или коллекцию элементов. Один из простейших способов создать массив – использовать команду PowerShell, которая выводит более одного объекта. Например, в результате простого запуска команды Get-ChildItem будет выведен список объектов в текущем расположении. Этот список может быть сохранен в переменной. Если текущее расположение содержит более одного объекта, переменная, в которой вы сохранили список, становится массивом. Это действительно просто. Например, рассмотрим следующую команду PowerShell:

$list = Get-ChildItem $ENV:SystemRoot

После выполнения этой команды переменная $list содержит массив объектов FileInfo и DirectoryInfo.

Другой способ создать массив – указать объекты, разделив их запятыми, и присвоить их переменной:

$list = «A",»B«,"C»,«1",»2«,"3»

Доступ к элементам массива

Существует три способа обращения к элементам массива.

  • Использование инструкции foreach. Инструкция foreach оболочки PowerShell предоставляет удобный способ обращения к любому элементу массива. Например, чтобы вывести на экран элемент массива $list, нужно запустить команду:
foreach ( $item in $list ) { $item }
  • Использование команды ForEach-Object. Команда ForEach-Object рассматривает массив как входные данные из конвейера и передает каждый объект массива в блок сценария для обработки. Текущий элемент массива представлен специальной переменной $_. Чтобы вывести на экран элемент массива $list с помощью команды ForEach-Object, используйте команду:
$list | ForEach-Object { $_ }
  • Применение инструкции с номером индекса. К каждому объекту (элементу) массива можно обратиться по соответствующему номеру, начиная с 0. Например, выражение $list[0] ссылается на первый элемент в массиве, выражение $list[1] ссылается на второй элемент, и так далее. Так, чтобы вывести на экран каждый член массива с помощью инструкции for и номера индекса, запустите команду:
for ( $i = 0; $i -lt $list.Count; $i++ ) {
$list[$i]
}

Из этих трех подходов способ с индексами используется реже всего. Основная причина в том, что инструкция foreach и команда ForEach-Object обеспечивают более быстрое выполнение задачи.

При изучении этих трех подходов основной вопрос звучит так: в чем разница между использованием инструкции foreach и команды ForEach-Object? Разница в первую очередь в том, что при использовании инструкции foreach необходимо извлечь все элементы массива, прежде чем вы сможете получить доступ к ним. И наоборот, команда ForEach-Object использует преимущества конвейера PowerShell, позволяя получить доступ сразу к отдельному элементу.

Какой же из подходов выбрать? Ответ зависит от элементов массива. Если у вас сравнительно небольшое количество элементов массива и извлечение не займет много времени, инструкция foreach будет работать отлично. Если же у вас большой список элементов и извлечение элементов требует значительного времени (например, файлы на удаленном файловом сервере), вы, скорее всего, захотите использовать команду ForEach-Object. Также стоит подумать о применении команды Write-Progress. Если вы хотите задействовать эту команду в сценарии, чтобы информировать пользователя о ходе выполнения операции, вам придется предварительно извлечь все объекты с помощью инструкции foreach – это необходимо для расчета процента выполненной работы.

Есть еще один момент, из-за которого могут возникнуть затруднения при выборе между инструкцией foreach и командой ForEach-Object: псевдонимом команды ForEach-Object является ключевое слово foreach! Не забывайте, что при использовании выражения foreach после вертикальной черты (|) в конвейере PowerSh ell на самом деле вы вызываете команду ForEach-Object.

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

Создание таблицы хеширования

Таблицы хеширования полезны в том случае, когда вам нужно хранить и извлекать объекты, обращаясь к ним по именам. Например, вы можете использовать таблицу хеширования, чтобы хранить список серверов и соответствующих им IP-адресов.

Вы можете создать таблицу хеширования путем указания имени и значения между символами @{ и }. Например, чтобы создать таблицу хеширования, которая содержит имена трех серверов и их IP-адреса, следует выполнить команду:

$hash = @{«server1» = «192.168.17.21»;
«server2» = «192.168.17.22»;
«server3» = «192.168.17.23»}

Если вывести эту таблицу хеширования на экран (просто написать $hash в строке PowerShell и нажать клавишу ввода), вы увидите результаты, приведенные на рисунке. Заметьте, что оболочка PowerShell выводит данные столбца Name в произвольном порядке. Одна из особенностей таблицы хеширования заключается в том, что именованные элементы не имеют определенного порядка.

 

Таблица хэширования
Рисунок. Таблица хэширования

Доступ к элементам таблицы хеширования

Чтобы получить значение из таблицы хеширования, вы можете указать имя таблицы хеширования и далее имя элемента, значение которого вы хотите получить, заключенное в квадратные скобки. Либо вы можете поставить точку между именем таблицы и именем элемента, значение которого вы хотите получить. Например, для созданной ранее переменной $hash любая из приведенных ниже команд вернет значение 192.168.17.21:

$hash[«server1»]
$hash.server1
$hash.«server1»

Имейте в виду, что кавычки в команде $hash[«server1»] необходимы. Без них оболочка PowerShell не сможет получить информацию о том, каким образом обрабатывать ключ server1. Однако если имя сервера хранится в переменной (например, $serverName), вы можете применить команду:

$hash[$serverName]

Некоторые команды PowerShell используют таблицы хеширования в качестве значений для параметров. Например, команда Select-Object задействует таблицы хеширования для вывода на экран вычисляемых свойств. Чтобы использовать таблицу хеширования при создании вычисляемого свойства для команды Select-Object, она должна иметь два парных значения: Name, которое задает имя вычисляемого свойства, и Expression, которое содержит блок сценариев, отвечающий за вычисление свойства. Например, возьмем команду:

Get-ChildItem $ENV:SystemRoot | select-object Name,
LastWriteTime, @{Name=«Day»;
Expression={$_.LastWriteTime.DayOfWeek}}

В этом случае команда Select-Object выведет имя, время последней записи и день недели для каждого файла и каталога в установочной папке Windows. Как и в случае с командой ForEach-Object, специальная переменная $_ ссылается на текущий объект.

.