Downloading files from multiple file paths with Powershell + WinSCP

Welcome Forums General PowerShell Q&A Downloading files from multiple file paths with Powershell + WinSCP

Viewing 2 reply threads
  • Author
    Posts
    • #218883
      Participant
      Topics: 6
      Replies: 8
      Points: 76
      Rank: Member

      Hi everyone!

      I have made a script for downloading files and giving them a random name-extension (as i need to download alot of files with the same name, from different remote domain directories, in order to search among their data).

      My issue is, that i have to download from several domains, and that part is not working out.
      An example of what i need to accomplish:

      I need to download wp-config-sample.php from several domains.
      *Server root*:/
      jonatantest/wp-config-sample-php
      jonatantest2/wp-config-sample.php

      (the files are then given an extension, allowing me to download several files with the same name to the one folder locally).

      $remotePath = “jonatantest/” works fine, but this only lets me download from one domain folder..
      $remotePath = (“jonatantest/”,”jonatantest2/”), does not seem to want to work, still trying to merge both paths into one.

      Am i approaching this in a stupid way? – Am i missing some way to use Foreach?

      Also, my print function of what files have been downloadet does not seem to work, and does not give me an error either?.

      I would really appreciate some feedback!

      Script:
      https://gist.github.com/Jonatantwn/c6e40989061721057c52ef2814653bb2

    • #218997
      Participant
      Topics: 12
      Replies: 1622
      Points: 2,560
      Helping Hand
      Rank: Community Hero

      Yes, you need a loop. Regardless if you see a loop, Powershell is looping for you.

      PS C:\Users\rasim> $services = Get-Service | Select -First 5
      
      PS C:\Users\rasim> $services.Name #Implicit Loop
      
      AarSvc_b1099
      AESMService
      AJRouter   
      ALG        
      AppIDSvc   
      PS C:\Users\rasim> $services | foreach{$_.Name} #Explicit Loop
      
      AarSvc_b1099
      AESMService
      AJRouter   
      ALG        
      AppIDSvc   
      PS C:\Users\rasim> Get-Service | Select -First 5 | Stop-Service -WhatIf
      
      What if: Performing the operation "Stop-Service" on target "Agent Activation Runtime_b1099 (AarSvc_b1099)".
      What if: Performing the operation "Stop-Service" on target "IntelĀ® SGX AESM (AESMService)".
      What if: Performing the operation "Stop-Service" on target "AllJoyn Router Service (AJRouter)".
      What if: Performing the operation "Stop-Service" on target "Application Layer Gateway Service (ALG)".
      What if: Performing the operation "Stop-Service" on target "Application Identity (AppIDSvc)".
      PS C:\Users\rasim> 
      

      If you looked at the documentation for Set-Service, Name is using ByValue:

      -Name
      Specifies the service name of the service to be changed. Wildcard characters aren't permitted. You can use the pipeline to send a service name to Set-Service.
      
      TABLE 7
      Type:	String
      Aliases:	ServiceName, SN
      Position:	0
      Default value:	None
      Accept pipeline input:	True (ByPropertyName, ByValue)
      Accept wildcard characters:	False
      

      If you look at the code (https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs), line 1306 to be exact, there is a loop that processes each Name from the pipeline. Here is something to start:

      param (
          $localPath = "C:\Users\Dern\Desktop\WINSCP PS DOWNLOAD\",
          $remotePath = ("jonatantest/","jonatantest2/"),
          $fileName = "wp-config-sample.php"
      )
               
      try
      {
          # Load WinSCP .NET assembly
          Add-Type -Path "C:\Users\Dern\Desktop\WINSCP PS\WinSCPnet.dll"
      
          # Setup session options
          $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
              Protocol = [WinSCP.Protocol]::ftp
              HostName = "xxx"
              UserName = "xxxx"
              Password = "xxxx"
           }
       
          $session = New-Object WinSCP.Session
       
          try
          {
              # Connect
              $session.Open($sessionOptions)
      
              foreach ($rp in $remotePath) {
                  # Download files
                  $transferOptions = New-Object WinSCP.TransferOptions
                  $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
          
                  # Format timestamp
                  $stamp = $(Get-Random)
          
                  # Download the file and throw on any error
                  $transferResult =
                  $session.GetFiles(
                      ($rp + $fileName),
                      ($localPath + $fileName + "." + $stamp)).Check()
      
      
                  # Print results
                  foreach ($transfer in $transferResult.Transfers)
                  {
                      Write-Host "Download of $($transfer.FileName) succeeded"
                  }
          }
      
          }
          finally
          {
              # Disconnect, clean up
              $session.Dispose()
          }
       
          exit 0
      }
      catch
      {
          Write-Host "Error: $($_.Exception.Message)"
          exit 1
      }
      

      As far as the print “not working”, you’re enumerating $transferResult.Transfers. Is there anything in $transferResult? Is there a property Transfers? You should be able to run this code in ISE or VSCode and see what is in $transferResult.

    • #219021
      Participant
      Topics: 6
      Replies: 8
      Points: 76
      Rank: Member

      Hi Rob!

      Thank you a whole bunch for your swift answer, i really appreciate it.

      Got me right back on track and i now finished the script intirely!

      For anyone else wondering how the final script might look, have a look at:
      https://gist.github.com/Jonatantwn/e1b166aea7c0b3a0897f896f80cb5349

Viewing 2 reply threads
  • You must be logged in to reply to this topic.