У меня есть вложенная хеш-таблица с массивом, и я хочу просмотреть содержимое другого массива и добавить его во вложенную хеш-таблицу. Я пытаюсь создать блок сообщений Slack.
Вот вложенная хеш-таблица, которую я хочу добавить:
$msgdata = @{
blocks = @(
@{
type = 'section'
text = @{
type = 'mrkdwn'
text = '*Services Being Used This Month*'
}
}
@{
type = 'divider'
}
)
}
$rows = [ ['azure vm', 'centralus'], ['azure sql', 'eastus'], ['azure functions', 'centralus'], ['azure monitor', 'eastus2'] ]
$serviceitems = @()
foreach ($r in $rows) {
$servicetext = "*{0}* - {1}" -f $r[1], $r[0]
$serviceitems += @{'type'='section'}
$serviceitems += @{'text'= ''}
$serviceitems.text.Add('type'='mrkdwn')
$serviceitems.text.Add('text'=$servicetext)
$serviceitems += @{'type'='divider'}
}
$msgdata.blocks += $serviceitems
Код частично рабочий. Хэш-таблицы @{'type'='section'} и @{'type'='divider'} добавлены успешно. Попытка добавить вложенную хеш-таблицу @{'text' = @{ 'type'='mrkdwn' 'text'=$servicetext }} завершается с ошибкой:
Line |
24 | $serviceitems.text.Add('type'='mrkdwn')
| ~
| Missing ')' in method call.
Я пробовал просматривать различные посты Powershell и не смог найти ни одного, подходящего для моей конкретной ситуации. Я новичок в использовании хеш-таблиц в Powershell.
Кстати: $rows = [ ['azure vm', 'centralus'] ... также является синтаксической ошибкой, пожалуйста, исправьте это утверждение, чтобы не отвлекать.





Примечание:
Этот ответ касается вашего вопроса как спросил, в частности проблем с синтаксисом.
Лучшее решение, которое обходит исходных проблем в пользу оптимизированного кода, см. в разделе полезный ответ zett42.
$serviceitems.text.Add('type'='mrkdwn') вызывает синтаксическую ошибку.
В целом говорит, ЕСЛИ $serviceitems.text относится к хеш-таблице (словарю), вам нужно либо:
,:$serviceitems.text.Add('type', 'mrkdwn')
$serviceitems.text['type'] = 'mrkdwn'
PowerShell даже позволяет вам обращаться к записям хеш-таблицы (словаря) с помощью синтаксис доступа к членам (точечная запись):
$serviceitems.text.type = 'mrkdwn'
В вашем конкретном случае дополнительные соображения вступает в игру:
Вы обращаетесь к хеш-таблице через массив, а не напрямую.
Запись text, на которую вы пытаетесь настроить таргетинг, изначально не является вложенной хеш-таблицей, поэтому вы не можете вызвать для нее .Add(); вместо этого вы должны назначить ему хеш-таблицу новый.
Поэтому:
# Define an empty array
$serviceItems = @()
# "Extend" the array by adding a hashtable.
# Note: Except with small arrays, growing them with +=
# should be avoided, because a *new* array must be allocated
# every time.
$serviceItems += @{ text = '' }
# Refer to the hashtable via the array's last element (-1),
# and assign a nested hashtable to it.
$serviceItems[-1].text = @{ 'type' = 'mrkdwn' }
# Output the result.
$serviceItems
В дополнение к полезный ответ mklement0, который решает проблему с вашим существующим кодом, я предлагаю следующий рефакторинг с использованием встроенных хеш-таблиц:
$serviceitems = foreach ($r in $rows) {
@{
type = 'section'
text = @{
type = 'mrkdwn'
text = "*{0}* - {1}" -f $r[1], $r[0]
}
}
@{
type = 'divider'
}
}
$msgdata.blocks += $serviceitems
Это выглядит намного чище и, следовательно, проще в обслуживании, на мой взгляд.
Пояснения:
$serviceitems = foreach ... записывает весь вывод (в поток успех) цикла foreach в переменную $serviceitems. PowerShell автоматически создает массив из вывода, что более эффективно, чем добавление в массив вручную с помощью оператора +=. Использование += PowerShell должно воссоздать массива нового размера для каждого добавления, потому что массивы на самом деле имеют фиксированный размер. Когда PowerShell автоматически создает массив, он внутри использует более эффективная структура данных.$serviceitems.$serviceitems на итерацию цикла.
Неправильный синтаксис для вызова метода, вы хотите:
$serviceitems.text.Add('type', 'mrkdwn')