'How to read PowerShell .PSD1 files safely
The PowerShell module manifest file format (.psd1) is essentially a Hashtable literal with certain keys expected. This is ideal for a configuration file for a PowerShell script. What I ultimately want to do is read a .psd1 file that contains a set of keys specific to the script.
For example (MyScriptConfig.psd1):
@{
FTPHost = "ftp.blah.com"
FTPUserName = "blah"
FTPPassword = "blah"
}
There's no reason I can't use XML, INI, JSON or whatever for this information, but I'd rather it use the same basic data format as PowerShell's module manifests.
Obviously the easiest thing would be to read the text and pass it to Invoke-Expression which would return a Hashtable, but then it would invoke anything that's in the file, which is error prone and potentially unsafe.
I thought I recalled a cmdlet for reading this data using a "safe" subset of PowerShell cmdlets, but I was thinking of ConvertFrom-StringData and DATA sections, neither of which let me read an arbitrary file containing a Hashtable literal.
Is there something built into PowerShell that lets me do this? If there's nothing built in, then I would probably go the route of JSON or Key=Value with ConvertFrom-StringData.
Solution 1:[1]
PowerShell DSC defines a parameter transformation attribute, used to support passing a path to a .psd1 file as the value of the ConfigurationData parameter when invoking a Configuration. This attribute is public and can be used in a custom function, such as:
function Parse-Psd1
{
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)]
[Microsoft.PowerShell.DesiredStateConfiguration.ArgumentToConfigurationDataTransformation()]
[hashtable] $data
)
return $data
}
Parse-Psd1 C:\MyData.psd1
The attribute implementation calls an internal helper that evaluates the contents of the file in a restricted language context, where only the following cmdlets are permitted:
Import-LocalizedData
ConvertFrom-StringData
Write-Host
Out-Host
Join-Path
Solution 2:[2]
Module manifests are specifically designed to use only a restricted subset of PSH, however there isn't1 a direct way to process the content (and get all the data) in that mode. However you can validate a manifest with Test-ModuleManifest2 and only then evaluate the contents of the file.
1 At least as far as PowerShell In Action 2nd Ed covers it.
2 Unfortunately the online copy of the book uses images for source code (to allow annotations), so can't copy here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Richard |
