我有一个包含 PowerShell 对象表示法中的一些数据的文件:
@{ X = 'x'; Y = 'y' }
我想将其加载到文件中的变量中。
(我在整理复制品时发现了它)
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 是一个内置的 cmdlet。我在这里创建了相应的 ConvertTo-StringData 函数http://poshcode.org/1986
如果你可以给这个文件扩展名.ps1
,比如说,data.ps1
那么它不能比这段代码更简单:
$data = <path>\data.ps1
正如@Chad 建议的那样,我在使用 ConvertFrom-StringData 时遇到了麻烦。如果你这样做:
$hash = get-content .\test.txt | ConvertFrom-StringData
我发现我有一个对象数组而不是哈希表。事实上,我似乎有一组哈希表,每个都有一个条目。我确认了:
$hash.GetType()
看起来您需要加入 slurped 输入文件的每一行,以确保它形成一个字符串供 ConvertFrom.. 使用:
$hash = ((get-content .\test.txt) -join '`n') | ConvertFrom-StringData
从 PowerShell 5.0 开始,您拥有
Import-PowerShellDataFile
它从 .psd1 文件中导入值。因此,您唯一需要做的就是将文件重命名为 *.psd1
官方帮助在这里。
这是一篇较旧的帖子,但是,这与您接受的解决方案有点不同,也许更“安全”,请记住不受信任的文件。
从您的笔记中,您有一个包含使用 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 文件)只是一个哈希表,所以这个概念可以帮助你也拉入脚本块或其他东西。