在我的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存在于作业之外,而不是在作业内部?我是不是遗漏了什么?
谢谢你帮我解决这个问题
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.
请看 本回答 以获取更多信息。
也许令人惊讶的是。
System.Xml.XmlDocument
是 反序列化为原始类型。
不过 System.Xml.XmlElement
是 不,这就解释了你的问题。
请注意,在 XmlElement
只不过 改编 中反映了原始实例的属性。Deserialized.System.Xml.XmlElement
(pscustomobject
)属性。
也就是说,该模拟具有 只是 的特性 新增PowerShell 的属性,即直接将底层 XML DOM 的子元素和属性浮出水面的属性,它可以方便地使用通常的点符号--见 本回答.
.NET XmlElement
类型的真实属性,如 ChildNodes
是 不 存在于反序列化仿真中,这就是为什么你的代码会失败。
如上图所示,变通的方法是将下面的 绳子 的代表 XmlElement
实例到后台作业--可通过下面的 OuterXml
属性--并在那里将该字符串重新解析为一个XML DOM(注意,严格来说,投向 [xml]
创建一个 System.Xml.XmlDocument
例如,但就你要做的事情而言,这应该不重要)。)