HashTable PowerShell - Всё, что вам нужно знать
Хэш-таблицы в PowerShell можно использовать для хранения информации структурированным образом. Это делается с помощью пар ключ/значение, что позволяет легко извлекать нужную информацию из хэш-таблицы. Вы можете сравнить хэш-таблицу в PowerShell с ассоциативным массивом, если хотите.
Хэш-таблицы довольно часто используются в PowerShell, потому что это отличный способ хранения и обработки информации. Прекрасное в хэш-таблицах заключается в том, что ключ и значение могут быть любым типом объекта. Таким образом, вы не ограничены целыми числами и строками, но также можете создавать вложенные хэш-таблицы, например.
В этой статье мы рассмотрим хэш-таблицы и то, как использовать их в ваших скриптах PowerShell.
Хеш-таблица против массива
Прежде чем мы начнем рассматривать хеш-таблицы, давайте сначала объясним разницу между хеш-таблицами и массивами. Это вопрос, который часто задают, и люди часто путаются между этими двумя понятиями.
Массив - это индексированный список значений. Индекс автоматически генерируется, когда вы добавляете значения в массив. Поэтому вы не контролируете, где храните информацию в массиве.
$array = @('apple','raspberry','kiwi')
Мы можем получить доступ к элементам массива, перебирая их или обращаясь к элементам по их индексу:
$array | Foreach { Write-Host $_ }
Result
apple
raspberry
kiwi
Or by index number
write-host $array[1]
Result
raspberryМы также можем добавлять или обновлять значения в массиве, но мы не можем изменять или определять номер индекса элемента:
Replace the raspberry with melon
$array[1] = 'melon'
Add a fruit to the array
$array += 'banana'Хэш-таблица
Как мы видели, массив — это просто список (коллекция) элементов, которые мы можем добавлять, изменять или удалять из списка. Индекс автоматически генерируется, когда вы добавляете элементы в него. Напротив, в HashTable PowerShell мы должны определить индекс (ключи) значения, которое мы хотим добавить.
Чтобы создать хэш-таблицу, мы используем {} вместо ():
Creating a hashtable
$serverIps= @{}
Or creating a pre-populate hashtable
$serverIps= @{
'la-srv-lab02' = '192.168.10.2'
'la-srv-db01' = '192.168.10.100'
}Чтобы добавить IP-адрес сервера в хеш-таблицу, нам нужно определить ключ. Мы не можем просто $hashtable.add('value'), потому что хеш-таблица не создаст индекс автоматически.
$key = 'la-srv-lab01'
$value = '192.168.10.1'
$serverIps.add($key,$value)
Or simply
$serverIps.add('la-srv-lab03','192.168.10.3')
Result:
$serverips
Name Value
---- -----
la-srv-lab03 192.168.10.3
la-srv-lab01 192.168.10.1Ключом в этом случае является имя сервера, а значением - IP-адрес сервера. Если нам нужен IP-адрес сервера lab03, мы можем просто сделать следующее:
Извлечение данных из хэш-таблицы
Чтобы извлечь данные из хэш-таблицы в PowerShell, мы можем просто указать ключ, который вернет значение этого ключа:
$serverIps['la-srv-lab03']
Result
192.168.10.3Другой вариант - пройти по хеш-таблице, но это работает немного иначе, чем с массивом. Если мы просто подключим цикл foreach к хеш-таблице, вы заметите, что он возвращает только объект хеш-таблицы:
$serverIps | foreach {write-host $_}
System.Collections.HashtableЧтобы получить только значения из хэш-таблицы, мы можем использовать свойство .value:
Return only the values
$serverIps.values
Or pipe them in a foreach to ping the servers for example:
$serverIps.values | foreach {ping $_}При работе с хеш-таблицей вы, вероятно, также захотите извлекать данные в виде пар ключ/значение. Для этого мы можем использовать функцию GetEnumerator:
$serverIps.GetEnumerator() | ForEach-Object {
$result = '{0} IP address is {1}' -f $_.key, $_.value
write-host $result
}
Result
la-srv-lab03 IP address is 192.168.10.3
la-srv-lab01 IP address is 192.168.10.1Обновление значений
Обновление значений в хэш-таблице можно выполнить, используя ключ для выбора правильной пары ключ/значение:
$serverIps['la-srv-lab03'] = '192.168.10.5'Если вам нужно обновить несколько значений в хеш-таблице, вы не можете просто использовать цикл ForEach для перебора хеш-таблицы. Например, это не сработает:
$serverIps.Keys | ForEach-Object {
$serverIps[$_] = '192.168.10.20'
}Сначала вам нужно скопировать ключи, прежде чем вы сможете обновить значения:
$serverIps.Keys.Clone() | ForEach-Object {
$serverIps[$_] = '192.168.10.20'
}Удаление ключей или значений
Чтобы полностью удалить пару ключ/значение из хэш-таблицы, вы можете использовать функцию .remove. Вам нужно будет указать ключ, который вы хотите удалить:
$serverIps.Remove('la-srv-lab03')Также возможно удалить только значение из ключа:
$serverIps['la-srv-lab03'] = $nullЧтобы полностью очистить хэш-таблицу, у вас есть два варианта: вы можете воссоздать экземпляр хэш-таблицы или использовать функцию clear. Последний вариант предпочтителен, так как он делает ваш код более читаемым.
Recreate the hashtable instance
$serverIps = @{}
Better option for readability, use the clear function
$serverIps.clear()Разбиение хеш-таблиц
Некоторые cmdlet в PowerShell требуют много свойств, которые мы обычно все пишем в одной строке. Это может сделать ваши скрипты PowerShell трудночитаемыми, потому что вам, возможно, придется прокручивать горизонтально, чтобы увидеть полную команду.
Например, когда вы хотите отправить электронное письмо из PowerShell, у вас получится длинная строка параметров.
Send-MailMessage -SmtpServer smtp.contoso.com -To johndoe@a-d.site -From info@contoso.com -Subject 'super long subject goes here' -Body 'Test email from PowerShell' -Priority HighЧтобы сделать это более читаемым, мы можем использовать хэш-таблицу и распаковать ее. Распаковка заменяет все параметры и значения одной переменной. Обратите внимание, что мы используем символ @ для распаковки переменной вместо $.
$mail = @{
SmtpServer = 'smtp.contoso.com'
To = 'johndoe@a-d.site'
From = 'info@contoso.com'
Subject = 'super long subject goes here'
Body = 'Test email from PowerShell'
Priority = High
}
Note the @ infront of mail, instead of $
Send-MailMessage @mailКак вы можете видеть, распаковка делает ваш код более понятным и легким для сопровождения вместо длинной строки параметров.
Создание объектов из хэш-таблиц
Хеш-таблицы отличны, когда вам нужно структурировать данные для одного объекта или для распаковки, но они не являются настоящими объектами. Хеш-таблицы имеют только два столбца: ключ и значение. Мы можем создать хеш-таблицу со спецификациями одного сервера, но когда нам нужно хранить данные о нескольких серверах, мы сталкиваемся с ограничениями (например, мы не можем повторно использовать имена столбцов).
Таким образом, лучший способ структурировать данные, когда у вас есть несколько записей, — это использовать объекты. Самый простой способ создать объекты в PowerShell — это преобразовать хеш-таблицу в пользовательский объект PowerShell. Мы делаем это, добавив [pscustomobject] перед хеш-таблицей.
Возьмем следующий пример, сначала мы создаем хеш-таблицу с характеристиками сервера:
$servers = @{
'name' = 'la-srv-db01'
'ip' = '192.168.10.100'
'model' = 'Hp DL380 G10'
'memory' = '96Gb'
}
Result
Name Value
---- -----
memory 96Gb
ip 192.168.10.100
name la-srv-db01
model Hp DL380 G10Как вы видите, у нас только два столбца: имя и значение. Хэш-таблица представляет собой один сервер, и мы не можем использовать её для создания списка серверов.
Однако, если мы преобразуем таблицу хешей в пользовательский объект PowerShell, мы получим настоящую таблицу, где у нас есть несколько столбцов.
$servers = [pscustomobject]@{
'name' = 'la-srv-db01'
'ip' = '192.168.10.100'
'model' = 'Hp DL380 G10'
'memory' = '96Gb'
}
Result
name ip model memory
---- -- ----- ------
la-srv-db01 192.168.10.100 Hp DL380 G10 96Gb Теперь мы можем добавить еще один сервер к pscustomobject:
function servers {
[pscustomobject]@{
'name' = 'la-srv-db01'
'ip' = '192.168.10.100'
'model' = 'Hp DL380 G10'
'memory' = '96Gb'
}
[pscustomobject]@{
'name' = 'la-srv-lab03'
'ip' = '192.168.10.3'
'model' = 'Hp DL180 G9'
'memory' = '32Gb'
}
}
servers
Result
name ip model memory
---- -- ----- ------
la-srv-db01 192.168.10.100 Hp DL380 G10 96Gb
la-srv-lab03 192.168.10.3 Hp DL180 G9 32GbЭкспорт Hashtable в CSV
Когда вы экспортируете хэш-таблицу в CSV, вы заметите, что по умолчанию ключи и значения не экспортируются. В выводе будет содержаться только информация о объекте хэш-таблицы, а не о данных внутри хэш-таблицы.
Чтобы фактически экспортировать содержимое хэш-таблицы, вам нужно использовать метод GetEnumerator, так же как мы это делали для просмотра содержимого хэш-таблицы. Нам нужны только ключ и значение из хэш-таблицы, поэтому вам также нужно будет добавить оператор select в команду.
$serverIps= @{
'la-srv-lab02' = '192.168.10.2'
'la-srv-db01' = '192.168.10.100'
'la-srv-lab03' = '192.168.10.3'
}
$serverIps.GetEnumerator() | Select Key, Value | Export-CSV -path c:\temp\hash.csv -NoЗаключение
Хеш-таблицы в PowerShell - это отличный способ структурировать данные или использовать их в сочетании с сплаттингом. Однако имейте в виду, что они предназначены для использования только для одного элемента. Мы не можем создать пользовательский столбец или сохранить несколько строк с одним и тем же ключом. Для этого вам действительно нужно использовать пользовательские объекты PowerShell.
Надеюсь, вы нашли эту статью полезной. Если у вас есть вопросы, просто оставьте комментарий ниже.
Если вы хотите узнать больше о PowerShell, убедитесь, что вы также прочитали о 10 основных командах PowerShell, которые вы должны знать.
