从 PowerShell 对象生成 CLIXML 字符串,而无需先序列化到磁盘
Generate CLIXML string from a PowerShell object without serializing to disk first
我有以下代码将对象导出到 XML 文件,然后将其读回并将其打印在信息流上。
try{
# Sample object
$Person = @{
Name = 'Bender'
Age = 'At least 1074'
}
$Person | Export-CliXml obj.xml
$cliXml = Get-Content -Raw ./obj.xml
Write-Host $cliXml
} finally {
if( Test-Path ./obj.xml ) {
Remove-Item -Force ./obj.xml -EV rError -EA SilentlyContinue
if( $rError ) {
Write-Warning "Failed to remove ./obj.xml: $($rError.Exception.Message)"
}
Remove-Variable -Force $rError -EA Continue
}
}
有一个系统本地父会话,它监视此输出的 STDOUT 并将其重建为自己会话中的对象。
NOTE: I know a local PSRemoting session would work, but I need this to also work on systems which PSRemoting has either not yet been configured or will not be.
我想去掉中间人而不是将对象写入磁盘。不幸的是,
Import-CliXMl
和 Export-CliXml
是仅有的名称中带有 CliXml
的 cmdlet,到目前为止,进行一些 .NET 文档调查没有任何结果。
有没有一种方法可以简单地将对象序列化为 CliXml 字符串,而无需先写入磁盘?我考虑过使用 $Person | ConvertTo-Json -Compress -Depth 100
但这有两个问题:
仅捕获最多 100 层深的嵌套对象。这是一个边缘案例,但仍然是我想避免的限制。我总是可以使用其他库或其他格式,但是;
我希望将它们重构为与序列化之前相同类型的 .NET 对象。使用 CliXml 重新创建对象是我知道可以做到这一点的唯一方法。
CliXml 序列化程序通过 [PSSerializer]
class:
公开
$Person = @{
Name = 'Bender'
Age = 'At least 1074'
}
# produces the same XML ouput as `Export-CliXml $Person`
[System.Management.Automation.PSSerializer]::Serialize($Person)
要反序列化 CliXml,请使用 Deserialize
方法:
$cliXml = [System.Management.Automation.PSSerializer]::Serialize($Person)
$deserializedPerson = [System.Management.Automation.PSSerializer]::Deserialize($cliXml)
补充:
引入内存等同于基于文件的Export-CliXml
和Import-CliXml
cmdlets - 以新 ConvertTo-CliXml
和 ConvertFrom-CliXml
cmdlets 的形式 - 原则上已获批准,但仍在等待社区实施(从 PowerShell 7.2.1 开始) - 请参阅 GitHub issue #3898 and the associated pending, but seemingly stalled community PR #12845
注意[System.Management.Automation.PSSerializer]::Serialize()
默认递归深度为1
,而Export-CliXml
默认为2
;如果需要,使用允许明确指定递归深度的重载(例如,[System.Management.Automation.PSSerializer]::Serialize($Person, 2)
)
我有以下代码将对象导出到 XML 文件,然后将其读回并将其打印在信息流上。
try{
# Sample object
$Person = @{
Name = 'Bender'
Age = 'At least 1074'
}
$Person | Export-CliXml obj.xml
$cliXml = Get-Content -Raw ./obj.xml
Write-Host $cliXml
} finally {
if( Test-Path ./obj.xml ) {
Remove-Item -Force ./obj.xml -EV rError -EA SilentlyContinue
if( $rError ) {
Write-Warning "Failed to remove ./obj.xml: $($rError.Exception.Message)"
}
Remove-Variable -Force $rError -EA Continue
}
}
有一个系统本地父会话,它监视此输出的 STDOUT 并将其重建为自己会话中的对象。
NOTE: I know a local PSRemoting session would work, but I need this to also work on systems which PSRemoting has either not yet been configured or will not be.
我想去掉中间人而不是将对象写入磁盘。不幸的是,Import-CliXMl
和 Export-CliXml
是仅有的名称中带有 CliXml
的 cmdlet,到目前为止,进行一些 .NET 文档调查没有任何结果。
有没有一种方法可以简单地将对象序列化为 CliXml 字符串,而无需先写入磁盘?我考虑过使用 $Person | ConvertTo-Json -Compress -Depth 100
但这有两个问题:
仅捕获最多 100 层深的嵌套对象。这是一个边缘案例,但仍然是我想避免的限制。我总是可以使用其他库或其他格式,但是;
我希望将它们重构为与序列化之前相同类型的 .NET 对象。使用 CliXml 重新创建对象是我知道可以做到这一点的唯一方法。
CliXml 序列化程序通过 [PSSerializer]
class:
$Person = @{
Name = 'Bender'
Age = 'At least 1074'
}
# produces the same XML ouput as `Export-CliXml $Person`
[System.Management.Automation.PSSerializer]::Serialize($Person)
要反序列化 CliXml,请使用 Deserialize
方法:
$cliXml = [System.Management.Automation.PSSerializer]::Serialize($Person)
$deserializedPerson = [System.Management.Automation.PSSerializer]::Deserialize($cliXml)
补充
引入内存等同于基于文件的
Export-CliXml
和Import-CliXml
cmdlets - 以新ConvertTo-CliXml
和ConvertFrom-CliXml
cmdlets 的形式 - 原则上已获批准,但仍在等待社区实施(从 PowerShell 7.2.1 开始) - 请参阅 GitHub issue #3898 and the associated pending, but seemingly stalled community PR #12845注意
[System.Management.Automation.PSSerializer]::Serialize()
默认递归深度为1
,而Export-CliXml
默认为2
;如果需要,使用允许明确指定递归深度的重载(例如,[System.Management.Automation.PSSerializer]::Serialize($Person, 2)
)