tl;dr
As Jeroen Mostert states, you must reference the XML elements from the caller's scope as strings in your background job and parse them into an XML DOM again there.
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
# ...
}
Your attempt to directly reference System.Xml.XmlElement
from the caller's scope in the job resulted in loss of the type identity due to the serialization that values transferred between sessions across process boundaries must undergo, and the deserialized emulations of the XmlElement
input objects lack the ChildNodes
property - read on for more.
Context
Generally, when data is transferred to and from out-of-process sessions, such as background jobs started with Start-Job
, only a handful of well-known types deserialize with type fidelity.
Instances of all other types are method-less emulations of the original objects, effectively [pscustomobject]
s with static copies of the original object's property values, and with a PowerShell ETS (Extended Type System) type name that reflects the original type's full name prefixed with Deserialized.
See this answer for more information.
Perhaps surprisingly,
Note that in the case of XmlElement
only the so-called adapted properties of the original instance are reflected in the Deserialized.System.Xml.XmlElement
(pscustomobject
) property.
That is, the emulation has only the properties that PowerShell added to the original instance, namely properties that directly surface the child elements and attributes of the underlying XML DOM, which enables convenient use of the usual dot notation - see this answer.
The .NET XmlElement
type's true properties, such as ChildNodes
are not present on the deserialized emulation, which is why your code fails.
The workaround, as shown at the top, is to pass the string representation of the XmlElement
instances to the background job - available via the OuterXml
property - and re-parse that string into an XML DOM there (note that, strictly speaking, casting to [xml]
creates a System.Xml.XmlDocument
instance, but with respect to what you're trying to do that shouldn't matter).