从 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-CliXMlExport-CliXml 是仅有的名称中带有 CliXml 的 cmdlet,到目前为止,进行一些 .NET 文档调查没有任何结果。

有没有一种方法可以简单地将对象序列化为 CliXml 字符串,而无需先写入磁盘?我考虑过使用 $Person | ConvertTo-Json -Compress -Depth 100 但这有两个问题:

  1. 仅捕获最多 100 层深的嵌套对象。这是一个边缘案例,但仍然是我想避免的限制。我总是可以使用其他库或其他格式,但是;

  2. 我希望将它们重构为与序列化之前相同类型的 .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-CliXmlImport-CliXml cmdlets - 以新 ConvertTo-CliXmlConvertFrom-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)