如何安全地阅读PowerShell .PSD1文件

时间:2014-08-20 15:32:54

标签: powershell

PowerShell模块清单文件格式(.psd1)本质上是一个具有预期某些键的Hashtable文字。这是PowerShell脚本的配置文件的理想选择。我最终想要做的是读取一个.psd1文件,其中包含一组特定于该脚本的键。

例如(MyScriptConfig.psd1):

@{
    FTPHost = "ftp.blah.com"
    FTPUserName = "blah"
    FTPPassword = "blah"
}

我没有理由不能使用XML,INI,JSON等来获取这些信息,但我宁愿使用与PowerShell模块清单相同的基本数据格式。

显然,最简单的方法是阅读文本并将其传递给Invoke-Expression,这会返回一个Hashtable,但是它会调用文件中的任何内容,这很容易出错并且可能不安全。

我以为我召回了一个用于使用PowerShell cmdlet的“安全”子集读取此数据的cmdlet,但我想到的是ConvertFrom-StringDataDATA部分,这些部分都不允许我读取任意文件包含Hashtable文字。

PowerShell中是否有内置功能可以让我这样做?如果没有内置任何东西,那么我可能会使用ConvertFrom-StringData去JSON或Key = Value的路线。

3 个答案:

答案 0 :(得分:25)

Powershell版本5添加了Cmdlet Import-PowershellDataFile以安全地解析PSD1文件。

在第5版之前,至少有三种解决方案:

  1. Cmdlet 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
    
  2. 也可以使用Data Section处理内联数据(内联类型会失败)。

    # Safely parse data
    $Data2 = DATA {
        @{
            a1 = 'a1'
            a2 = 2
            a3 = @{
              b1 = 'b1'
            }
        }
    }
    
    # Use the data
    $Data2.a1
    $Data2.a3.b1
    
  3. 第三个是PowerShell DSC parameter transformation attribute mentioned by @Jakub Berezanski

答案 1 :(得分:13)

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

属性实现调用内部帮助程序,该辅助程序在受限语言上下文中评估文件的内容,其中只允许以下cmdlet:

Import-LocalizedData
ConvertFrom-StringData
Write-Host
Out-Host
Join-Path

答案 2 :(得分:1)

模块清单专门设计为仅使用PSH的受限子集,但是 1 没有直接的方式来处理该模式中的内容(并获取所有数据)。但是,您可以使用Test-ModuleManifest 2 验证清单,然后仅评估文件的内容。


1 至少就 PowerShell In Action 第二版Ed所涵盖的那样。

2 不幸的是,本书的在线副本使用图像作为源代码(允许注释),所以不能在这里复制。