【发布时间】:2019-06-29 10:49:53
【问题描述】:
由于 PowerShell 表达式模式,PowerShell 有一些很好的方法来反序列化对象,例如:
-
Invoke-Expressioncmdlet -
Invoke-Commandcmdlet - 呼叫接线员
& - dot sourcing PowerShell 脚本文件
我的一般期望是给定表达式的结果应该与在该表达式的同一序列化版本上使用上面列出的反序列化命令之一相同(有关背景,请参阅'Save hash table in PowerShell object notation (PSON)' 上的ConvertTo-Expression 答案问题)。
换句话说:
<Expression> <=> Invoke-Command {<Expression>} <=> &([ScriptBlock]::Create('<Expression>'))
<Expression> <=> Invoke-Expression '<Expression>'
例子:
Get-ChildItem <=> &{Get-ChildItem}
Get-ChildItem <=> Invoke-Command {Get-ChildItem}
Get-ChildItem <=> Invoke-Expression 'Get-ChildItem'
1, 2, 3 <=> &{1, 2, 3}
1, 2, 3 <=> Invoke-Command {1, 2, 3}
1, 2, 3 <=> Invoke-Expression '1, 2, 3'
这确实主要适用于每个表达式,但由于 PowerShell 默认展开(枚举)输出,因此在表达式包含具有单个项目的数组的情况下,此定义会有所不同:
,1 <≠> Invoke-Command {,1}
,1 <≠> Invoke-Expression ',1'
,"Test" <≠> Invoke-Command {,"Test"}
,"Test" <≠> Invoke-Expression ',"Test"'
@("Test") <≠> Invoke-Command {@("Test")}
@("Test") <≠> Invoke-Expression '@("Test")'
,@("Test") <≠> Invoke-Command {,@("Test")}
,@("Test") <≠> Invoke-Expression ',@("Test")'
有没有办法防止表达式在被调用(反序列化)时展开?
我正在考虑为PowerShell GitHub 上的Invoke-Expression 请求-NoEnumerate 参数(类似于Write-Output cmdlet),但这仍然会给呼叫接线员留下问题/问题和不支持参数的点源...
【问题讨论】:
-
我知道 powershell 在某些情况下会使表达式变平。我不认为序列化是正确的词。那是为了从远程计算机返回对象。序列化的对象没有方法。
-
我能找到的唯一方法:
$a = @(&{,1}) -
@js2010,关于"serialization",所有三个命令都列出了命令:
Invoke-Expression、调用运算符 (&([ScriptBlock]::Create('<Expression>'))) 和点源接受纯文本作为描述对象的输入 (可能(或不)来自远程计算机)... -
@js2010,关于
$a = @(&{,1}),这适用于(单值)数组,但会破坏任何非数组的原始定义(例如`valuedtypes`和hashtables)例如'Test' <≠> @(&{'Test'})
标签: powershell expression deserialization unroll