Загрузка хеш-таблицы PowerShell из файла?

У меня есть файл, содержащий некоторые данные в нотации PowerShell:

@{ X = 'x'; Y = 'y' }

Я хотел бы загрузить это в переменную из файла.

5 ответов

Решение

(Я понял это, когда собирал репродукцию)

PS> $content = ( Get-Content .\foo.pson | Out-String )
PS> $data = ( Invoke-Expression $content )

Get-Content возвращает массив со строками в файле; Out-String используется, чтобы соединить их вместе.

Invoke-Expression затем запускает скрипт, и результат фиксируется. Это открыто для инъекционных атак, но это нормально в этом случае.

Или, если вы предпочитаете краткий PowerShell:

PS> $data = gc .\foo.pson | Out-String | iex

(Я не могу найти более короткую форму Out-String)

Я использовал ConvertFrom-StringData. Если вы хотите использовать этот подход, вам нужно изменить способ хранения пар ключ / значение, каждая из которых находится на отдельной строке и без кавычек:

#Contents of test.txt
X = x
Y = y

get-content .\test.txt | ConvertFrom-StringData

Name                           Value
----                           -----
X                              x
Y                              y

ConvertFrom-StringData - это встроенный командлет. Я создал соответствующую функцию ConvertTo-StringData, доступную здесь http://poshcode.org/1986

Начиная с PowerShell 5.0 у вас есть

Import-PowerShellDataFile

Который импортирует значения из.psd1-файла. Поэтому единственное, что вам нужно сделать, это переименовать ваш файл в *.psd1

Официальная помощь здесь.

Я столкнулся с проблемой при использовании ConvertFrom-StringData, как предложил @Chad. Если вы делаете:

$hash = get-content .\test.txt | ConvertFrom-StringData

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

$hash.GetType()

Похоже, что вам нужно присоединиться к каждой строке входного файла, чтобы гарантировать, что он формирует одну строку для использования ConvertFrom..:

$hash = ((get-content .\test.txt) -join '`n') | ConvertFrom-StringData

Если вы можете дать этому файлу расширение .ps1, сказать, data.ps1 тогда это не может быть проще, чем этот код:

$data = <path>\data.ps1

Это старый пост, но это своего рода поворот вашего принятого решения и, возможно, немного более "безопасный", помните о недоверенных файлах.

Из ваших заметок у вас есть файл, который содержит хеш-таблицу с использованием синтаксиса Powershell. Учитывая это ограничение, вы можете импортировать его напрямую:

$HashPath = ".\foo.pson"
# input file contents
$filecontent = Get-Content -Path $HashPath -Raw -ErrorAction Stop
# put the file in a script block
$scriptBlock = [scriptblock]::Create( $filecontent )
#check that the file contains no other Powershell commands
$scriptBlock.CheckRestrictedLanguage( $allowedCommands, $allowedVariables, $true )
#execute it to create the hashtable 
$hashtable = ( & $scriptBlock ) 

Обратите внимание на $scriptBlock.CheckRestrictedLanguage Вы могли бы заменить это на

$scriptBlock.CheckRestrictedLanguage([string[]]@(), [string[]]@(), $false)

Используйте пустой список строк, чтобы мы не разрешали использовать команды Powershell. При импорте хеш-таблицы это именно то, что мы хотим. Этот последний allowEnvironmentVariables поэтому мы ограничиваем это в этом примере $false,

Напомним, что модуль Powershell (файл psd1) - это просто хеш-таблица, поэтому эта концепция может помочь вам также включать блоки скриптов или другие вещи.

Ссылка: https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.scriptblock.checkrestrictedlanguage?view=powershellsdk-1.1.0

Другие вопросы по тегам