我将一个XmlElement
传递给一个函数,该函数又将XmlElement
传递给一个脚本块进行远程执行。发生的是只有部分元素通过foreach
循环读取。如果我使用$using
传递XML或将其作为ArrayList传递,这似乎无关紧要。
XML部分:
<task>
<apps>
<app name="Sample">
<db name="Basic"/>
<db name="Interntl"/>
<db name="Xchgrate"/>
</app>
<app name="Vision">
<db name="Plan1"/>
</app>
</apps>
</task>
PowerShell代码:
foreach ($App in $using:task.apps.app) {
$AppName = $App.name
foreach ($Db in $App.db) {
$DbName = $Db.name
$AppFolder = "$DestinationFolder\$AppName\$DbName"
$AppFolder
}
}
如果$DestinationFolder
设置为C:\ Staging:
C:\Staging\Objects\Applications\Sample\Basic C:\Staging\Objects\Applications\Sample\Interntl C:\Staging\Objects\Applications\Sample\Xchgrate
我很困惑为什么我没有看到Vision app和db条目?它就像它只是跳过它?更奇怪的是,如果我发表评论
<db name="Plan1"/>
输出中包含Vision应用程序。
C:\Staging\Objects\Applications\Sample\Basic C:\Staging\Objects\Applications\Sample\Interntl C:\Staging\Objects\Applications\Sample\Xchgrate C:\Staging\Objects\Applications\Vision\
答案 0 :(得分:0)
scriptblock中的对象变为Deserialized.System.Xml.XmlElement
对象,其显然与常规System.Xml.XmlElement
对象略有不同。您可以通过在scriptblock中运行类似的内容来查看对象类型:
$using:task | Get-Member
要避免此问题,请在scriptblock之外创建文件夹列表,并在调用远程主机上的scriptblock时将字符串数组作为参数传递:
$AppFolders = foreach ($App in $task.apps.app) {
foreach ($Db in $App.db) {
'{0}\{1}\{2}' -f $DestinationFolder, $App.name, $Db.name
}
}
Invoke-Command -Computer 'remotehost' -ScriptBlock {
Param($folders)
...
} -ArgumentList (,$AppFolders)
需要使用表达式,$AppFolders
来避免展开数组。没有它,只有列表的第一个元素会传递给$folders
。
答案 1 :(得分:0)
因此,根据此answer,您需要将节点包装到新的XML文档对象中并将其传递到脚本块中。因此,对我有用的就是这样做
$wrapper = New-Object System.Xml.XmlDocument
$wrapper.AppendChild($wrapper.ImportNode($task, $true)) | Out-Null
然后通过-ArgumentList(,$ wrapper)
传递$ wrapper$sb = {
param([object]$wrapper)
foreach ($App in $wrapper.task.apps.app) {
$AppName = $App.name
foreach ($Db in $App.db) {
$DbName = $Db.name
$AppFolder = "$DestinationFolder\$AppName\$DbName"
$AppFolder
}
}
}
像魅力一样工作!感谢您的帮助。