为什么我的变量在Job中会有这样的行为?

问题描述 投票:1回答:1

在我的Powershell脚本中,我面临着Job中XmlElements的奇怪行为。$CommandConfiguration 是一个XML元素,里面有嵌套的元素。这些元素存在于Job范围之外的脚本中,这一点已经过测试和调试。考虑这段代码。

if($CommandConfiguration.ChildNodes.Name -contains "DomainCheck"){
    Write-Host ChildNode exists                            # this is executed
}
$Jobs += Start-Job -Name "WMI-Job" -ScriptBlock {
    $th = $Using:TargetHost
    $cc = $Using:CommandConfiguration                     
    $creds = $Using:Creds

    if($cc.ChildNodes.Name -contains "DomainCheck"){
        Write-Host ChildNode exists                        # this is NOT executed
    }

...

为什么childnode存在于作业之外,而不是在作业内部?我是不是遗漏了什么?

谢谢你帮我解决这个问题

xml powershell jobs using
1个回答
0
投票

tl;dr

作为 Jeroen Mostert 状态,你必须从调用者的作用域中引用XML元素。作为字符串 并在那里再次将它们解析成一个XML DOM。

Start-Job -Name 'WMI-Job' -ScriptBlock {
  # ...
  # Use .OuterXml to get the XML element's string representation
  # from the caller's scope, and parse it into an XML document,
  # which makes $cc.ChildNodes work as expected.
  [xml] $cc = $Using:CommandConfiguration.OuterXml
  # ...
}

您试图直接引用 System.Xml.XmlElement 从工作中调用者的作用域出发,由于跨流程边界的会话之间传输的值必须经过序列化,导致类型标识丢失,而反序列化的 仿真XmlElement 输入对象缺少 ChildNodes 属性 - 请继续阅读。


语境

一般来说,当数据被传输到进程外的会话或从进程外的会话中传输时,例如用以下方式启动的后台作业。Start-Job只有少数著名的类型能以类型保真度反序列化。

所有其他类型的实例都是无方法的。仿真 原有对象的,实际上 [pscustomobject]的静态副本,并使用PowerShell ETS(扩展类型系统)类型名,该类型名反映了原始类型的全名,前缀为 Deserialized.

请看 本回答 以获取更多信息。


也许令人惊讶的是。

请注意,在 XmlElement 只不过 改编 中反映了原始实例的属性。Deserialized.System.Xml.XmlElement (pscustomobject)属性。

也就是说,该模拟具有 只是 的特性 新增PowerShell 的属性,即直接将底层 XML DOM 的子元素和属性浮出水面的属性,它可以方便地使用通常的点符号--见 本回答.

.NET XmlElement 类型的真实属性,如 ChildNodes 存在于反序列化仿真中,这就是为什么你的代码会失败。

如上图所示,变通的方法是将下面的 绳子 的代表 XmlElement 实例到后台作业--可通过下面的 OuterXml 属性--并在那里将该字符串重新解析为一个XML DOM(注意,严格来说,投向 [xml] 创建一个 System.Xml.XmlDocument 例如,但就你要做的事情而言,这应该不重要)。)

© www.soinside.com 2019 - 2024. All rights reserved.