Как безопасно читать файлы PowerShell.PSD1
Формат файла манифеста модуля PowerShell (.psd1) - это, по существу, литерал Hashtable с определенными ключами. Это идеально подходит для файла конфигурации для PowerShell script. В конечном итоге я хочу прочитать файл .psd1, содержащий набор ключей, специфичных для script.
Например (MyScriptConfig.psd1):
@{
FTPHost = "ftp.blah.com"
FTPUserName = "blah"
FTPPassword = "blah"
}
Нет причин, по которым я не могу использовать XML, INI, JSON или что-то еще для этой информации, но я предпочел бы использовать тот же базовый формат данных, что и модуль PowerShell.
Очевидно, что проще всего прочитать текст и передать его в Invoke-Expression
, который вернет Hashtable, но затем он будет вызывать все, что в файле, которое подвержено ошибкам и потенциально опасно.
Я думал, что вспомнил командлет для чтения этих данных с помощью "безопасного" подмножества командлетов PowerShell, но я думал о разделах ConvertFrom-StringData
и DATA
, ни один из которых не позволяет мне читать произвольный файл, содержащий литерал Hashtable.
Есть ли что-то встроенное в PowerShell, которое позволяет мне это делать? Если ничего не встроено, то я, вероятно, поеду по маршруту JSON или Key = Value с ConvertFrom-StringData
.
Ответы
Ответ 1
Версия Powershell 5 добавила Cmdlet Import-PowershellDataFile для безопасного анализа файлов PSD1.
До версии 5 было по крайней мере три решения:
-
Командлет Import-LocalizedData. Который, хотя и предназначенный или обрабатывающий языковые файлы, будет читать любой файл в формате PSD1.
# Create a test PSD1 file
@'
@{
a1 = 'a1'
a2 = 2
a3 = @{
b1 = 'b1'
}
}
'@ | Set-Content -Path .path\example.psd1
# Read the file
Import-LocalizedData -BaseDirectory .\path -FileName example.psd1 -BindingVariable Data
# Use the data
$Data.a1
$Data.a3.b1
-
Также можно обрабатывать потоковые данные с помощью раздела данных (в некотором роде поражения целей).
# Safely parse data
$Data2 = DATA {
@{
a1 = 'a1'
a2 = 2
a3 = @{
b1 = 'b1'
}
}
}
# Use the data
$Data2.a1
$Data2.a3.b1
-
Третий - это атрибут преобразования параметра PowerShell DSC, упомянутый @Jakub Berezanski.
Ответ 2
PowerShell DSC определяет атрибут преобразования параметров, используемый для поддержки передачи пути к файлу .psd1 в качестве значения параметра ConfigurationData при вызове конфигурации. Этот атрибут является общедоступным и может использоваться в пользовательской функции, например:
function Parse-Psd1
{
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)]
[Microsoft.PowerShell.DesiredStateConfiguration.ArgumentToConfigurationDataTransformation()]
[hashtable] $data
)
return $data
}
Parse-Psd1 C:\MyData.psd1
Реализация атрибута вызывает внутренний помощник, который оценивает содержимое файла в контексте ограниченного языка, где разрешены только следующие командлеты:
Import-LocalizedData
ConvertFrom-StringData
Write-Host
Out-Host
Join-Path
Ответ 3
Модульные манифесты специально разработаны для использования только ограниченного подмножества PSH, однако нет прямого 1 прямого способа обработки содержимого (и получения всех данных) в этом режиме. Однако вы можете проверить манифест с помощью Test-ModuleManifest
2 и только затем оценить содержимое файла.
1 По крайней мере, насколько PowerShell In Action 2nd Ed охватывает его.
2 К сожалению, онлайн-копия книги использует изображения для исходного кода (чтобы разрешить аннотации), поэтому здесь не могу копировать.