locked
Looping through Foreach RRS feed

  • Question

  • Hi.

    I have a XML config file which contains data as below.

    <Config>
    <Test>
    <SourceDBBackupPath>\\server\D$\BACKUP</SourceDBBackupPath>
    <DestinationRestorePath>\\server1\e$\BACKUP\;\\server2\e$\BACKUP\</DestinationRestorePath>
    <DestinationServer>server1;server2</DestinationServer>
    </Test>

    Destination tags have multiple values seperated by a semicolon. I am trying to copy files recursively from SourceDBBackupPath and paste in multiple destination path.

    I have tried the below, but not knowing how to do multiple loop

    function CopyBackupDB($Region)
    {
        if($Region -ieq "Test" )
        {
            $XPath = "Config/Test"
            $Xvalues =   Select-Xml -Path $configFile -XPath $Xpath | Select-Object -ExpandProperty Node
    
          $CharArray = $Xvalues.DestinationServer 
          $SourcePath = $Xvalues.SourceDBBackupPath
          $DestinationPath = $Xvalues.DestinationRestorePath
          
          $($CharArray.split(';')).foreach{
          
            $Session = New-PSSession -ComputerName "$_" -Credential "domain\id"
         
              Copy-Item $SourcePath -Destination $DestinationPath  -Recurse
            }
           }
    }

    How to loop for each of the destinationrestore path ?

    Thanks

    Tuesday, July 7, 2020 10:20 AM

Answers

  • 1 you have unclear variable naming. CharArray variable for some reasone contain destination servers

    2 Each variable can alredy contain more than 1 values

    3 You r creating sessions that not used in any place

    4 Copying files does not have any dependencies with destination servers, so you do not need 1 loop inside another one

    5 ConfigFile variable is not defined inside your function. Better way is storing all inputs in the param block

    function CopyBackupDB($Region){ if($Region -eq "Test" ){ $XPath = "Config/Test" $Xvalues = Select-Xml -Path $configFile -XPath $Xpath | Select-Object -ExpandProperty Node $DestinationServers = $Xvalues.DestinationServer -Split ";" $SourcePath = $Xvalues.SourceDBBackupPath $DestinationPaths = $Xvalues.DestinationRestorePath -Split ";" # Do not know for what this block needed but ok foreach ($DestinationServer in $DestinationServers){ $Session = New-PSSession -ComputerName $DestinationServer -Credential "domain\id" }

    foreach ($DestinationPath in DestinationPaths){

    Copy-Item $SourcePath -Destination $DestinationPath -Recurse }

    } }


    The opinion expressed by me is not an official position of Microsoft


    • Edited by Vector BCO Tuesday, July 7, 2020 11:44 AM
    • Marked as answer by Venkatzeus Tuesday, July 7, 2020 12:25 PM
    Tuesday, July 7, 2020 11:40 AM

All replies

  • ASsumed you fix your XML by closing the "Config" tag you could iterate over the values seperated by semikolon like this:

    $configFile = 'D:\sample\configFile.xml'
    $XPath = "Config/Test"
    $Xvalues = Select-Xml -Path $configFile -XPath $Xpath | Select-Object -ExpandProperty Node
    
    foreach ($DestinationPath in ($Xvalues.DestinationRestorePath -split ';')){
        $DestinationPath
    }
    foreach ($DestinationServer in ($Xvalues.DestinationServer -split ';')) {
        $DestinationServer
    }
    You know that the elements you save in that way are unrealted to each other. If you want to have a relation between "Server1" and "\\server1\e$\BACKUP" you should save these data as structured data ... CSV for example. Or you will have to save them in XML as related.


    Live long and prosper!

    (79,108,97,102|%{[char]$_})-join''

    • Edited by BOfH-666 Tuesday, July 7, 2020 11:29 AM
    Tuesday, July 7, 2020 11:28 AM
  • 1 you have unclear variable naming. CharArray variable for some reasone contain destination servers

    2 Each variable can alredy contain more than 1 values

    3 You r creating sessions that not used in any place

    4 Copying files does not have any dependencies with destination servers, so you do not need 1 loop inside another one

    5 ConfigFile variable is not defined inside your function. Better way is storing all inputs in the param block

    function CopyBackupDB($Region){ if($Region -eq "Test" ){ $XPath = "Config/Test" $Xvalues = Select-Xml -Path $configFile -XPath $Xpath | Select-Object -ExpandProperty Node $DestinationServers = $Xvalues.DestinationServer -Split ";" $SourcePath = $Xvalues.SourceDBBackupPath $DestinationPaths = $Xvalues.DestinationRestorePath -Split ";" # Do not know for what this block needed but ok foreach ($DestinationServer in $DestinationServers){ $Session = New-PSSession -ComputerName $DestinationServer -Credential "domain\id" }

    foreach ($DestinationPath in DestinationPaths){

    Copy-Item $SourcePath -Destination $DestinationPath -Recurse }

    } }


    The opinion expressed by me is not an official position of Microsoft


    • Edited by Vector BCO Tuesday, July 7, 2020 11:44 AM
    • Marked as answer by Venkatzeus Tuesday, July 7, 2020 12:25 PM
    Tuesday, July 7, 2020 11:40 AM
  • HI.

    Thanks for the response. I have corrected the XML with the closing tag.

    when copying to remote server, i need to establish the session and then transfer the data. So i need to have both the loops together.

    The xml can have 1 server, 2 server , 3 server.. it can change

    If I have to restructure the XML, which allows single or multiple server, how should i change it. In that change, what should be the change in powershell to take the data from xml


    • Edited by Venkatzeus Tuesday, July 7, 2020 11:42 AM
    Tuesday, July 7, 2020 11:40 AM
  • Do not know why you create new topic but not continue previous one

    In any case you need to have clear algorithm what to do before doing something more or less complicated.

    If you already have some huge XML with some structure - this is one question, but if you will create such XML manually and you can change it it`s something totally diferent thing.

    Optimal way for storing data will be splitted this data by some logical types (sample in your previous topic)

    Like, regions in which you have servers that might be 1 or more destination points and so on.

    Then you can siply iterate through all regions, inside this first loop you can iterate through all destination points and in this way unify you script (sample in previous topic)

    Also as BOfH-666 mentioned, mb would be siplier store your parameters in a CSV, or JSON format (not so important but may be more human readeble)


    The opinion expressed by me is not an official position of Microsoft

    • Edited by Vector BCO Tuesday, July 7, 2020 12:24 PM
    Tuesday, July 7, 2020 12:20 PM