2017-01-17 1 views
0

Ich übergebe eine XmlElement an eine Funktion, die wiederum diese XmlElement in einen Skriptblock für die Remoteausführung übergeben. Was passiert ist, dass nur einige der Elemente über die foreach Schleife gelesen werden. Dies scheint unabhängig davon zu sein, ob ich das XML mit $using übergebe oder es als ArrayList übergebe.Foreach-Schleife bei Verwendung von Xml.XmlElement in Remote-Skriptblock

Der XML-Abschnitt:

<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-Code:

foreach ($App in $using:task.apps.app) { 
    $AppName = $App.name 
    foreach ($Db in $App.db) { 
    $DbName = $Db.name 
    $AppFolder = "$DestinationFolder\$AppName\$DbName" 
    $AppFolder 
    } 
} 

Die resultierende Ausgabe ist dies, wenn $DestinationFolder auf C eingestellt ist: \ Inszenierung:

C:\Staging\Objects\Applications\Sample\Basic 
C:\Staging\Objects\Applications\Sample\Interntl 
C:\Staging\Objects\Applications\Sample\Xchgrate

Ich bin verwirrt, warum ich Vision-App und db-Einträge nicht sehe? Es ist wie es einfach überspringt? Was ist noch seltsamer ist, dass wenn ich auf Kommentar

<db name="Plan1"/> 

Der Ausgang der Vision-App in sich hat.

C:\Staging\Objects\Applications\Sample\Basic 
C:\Staging\Objects\Applications\Sample\Interntl 
C:\Staging\Objects\Applications\Sample\Xchgrate 
C:\Staging\Objects\Applications\Vision\

Antwort

0

Das Objekt innerhalb des Skript wird ein Deserialized.System.Xml.XmlElement Objekt, das offenbar von einem regulären System.Xml.XmlElement Objekt etwas anders verhält. Sie können den Objekttyp sehen, indem Sie in der Skript etwas wie folgt ausgeführt werden:

$using:task | Get-Member 

dieses Problem zu vermeiden, dass Ihre Ordnerliste außerhalb der Skript erstellen und den String-Array als Argument übergibt, wenn die Skript auf der Remote-Host-Aufruf:

$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) 

Der Ausdruck ,$AppFolders erforderlich, um das Array Abrollen zu vermeiden. Ohne es würde nur das erste Element der Liste an $folders übergeben werden.

0

Also nach dieser answer müssen Sie den Knoten in ein neues XML-Dokument-Objekt wickeln und diese in den Skriptblock übergeben. So einfach das, was für mich gearbeitet wurde, dies zu tun

$wrapper = New-Object System.Xml.XmlDocument 
$wrapper.AppendChild($wrapper.ImportNode($task, $true)) | Out-Null 

dann den $ Wrapper über -ArgumentList passieren (, $ 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 
    } 
} 
} 

wie ein Charme !!! Danke für die Hilfe.

Verwandte Themen