我将以下变量$Obj
设置为以下字符串值:
$Obj = '@{Version=1; Name=a;}'
如何将此值从字符串转换为自定义 ps对象?
我希望能够打电话
$Obj.Version
并获取值 1。目前,此调用不返回任何内容。
注意:由于我检索此变量的方式,如果没有单引号,我无法初始化它。
编辑:
这是当前代码:
$Command = "script.ps1 -ExtraInfo $_"
Write-Host $Command
Invoke-Expression -Command $Command
其中$_
@{Version=1; Name=a;}
(不带引号)
最初这段代码是写成
. script.ps1 -ExtraInfo $_
并且有效,但是当我添加单元测试时,我将其更改为使用 Invoke-Expression,以便可以使用 Pester 单元测试对其进行测试。有没有更好的方法?
编辑2:
事实证明,这可以通过在表达式前放置一个背部抽动来解决,这为我解决了问题。谢谢大家的投入。
$Command = "script.ps1 -ExtraInfo `$_"
Write-Host $Command
Invoke-Expression -Command $Command
[pscustomobject]
实例的字符串化版本类似于哈希表文本,不适合编程处理,如以下示例所示:
# Stringify a [pscustomobject] instance.
PS> "$([pscsutomobject] @{ Version=1; Name='a value' })"
@{Version=1; Name=a value} # !! Quoting of the .Name value was lost
对于本身是复杂对象的属性值,问题变得更糟。
由于您似乎有权访问原始[pscustomobject]
实例,因此解决方案不是字符串化。
为此,您只需通过使用逐字(单引号)字符串文字 ('...'
) 来避免前期字符串插值,并让Invoke-Expression
(通常应避免)将$_
变量解释为其原始类型:
# Use *single* quotes to prevent up-front expansion.
$Command = 'script.ps1 -ExtraInfo $_'
Write-Host $Command
Invoke-Expression -Command $Command
请注意,使用逐字(非内插)字符串文字使得Invoke-Expression
在这里使用是安全的,不过,正如圣地亚哥·斯夸尔松指出的那样,一般来说可能有更好的选择,特别是在 Pester 的上下文中。
一个基于脚本块的解决方案({ ... }
),它接收对象作为参数:
$Command = { script.ps1 -ExtraInfo $args[0] }
Write-Host "Calling { $Command } with argument $_"
. $Command $_
这不适用于Name=a
a
因为不是已知对象(或者至少没有在我的PS会话中定义)。但如果这是一个字符串,则可以使用以下脚本完成此操作:
$Obj = '@{Version=1; Name="a";}'
$s= [System.Management.Automation.ScriptBlock]::Create("New-Object -TypeName PSObject -Property $Obj")
$o = Invoke-Command -ScriptBlock $s
$o.Version
正如我在评论中所说,这很奇怪,应该在代码库中更早地解决。但是,如果无法做到这一点,请使用Invoke-Expression
这样
$newObj = Invoke-Expression $Obj
进一步阅读 调用表达式