Using WinSCP to move files to a local path

1.1k Views Asked by At

I am currently using WinSCP to synchronize files between a remote path and a local path to a desktop computer. I would like to change this so that either of the following occurs:

  1. Move files from the remote path to the local path
  2. Copy files from the remote path to the local path, then delete only the files that were downloaded to the local path - on the remote server.

Is this possible?

Here is my current script, any assistance is very much appreciated.

@echo on
cls
:SetFileLogVariables
SET localdir=C:\Users\User1\Received
SET remotedir=\folder_1
SET logfile=C:\Users\Users1\Logs\Syncanddelete.log

:SetPrgVariables
SET 
prgwinscp=C:\Users\Users1\AppData\Local\Programs\WinSCP\WinSCP.com
SET winscplogin="SyncandDelete"
SET winscpfile=%temp%\~tmpWinSCPFTPSyncT_%~N0.txt
IF EXIST "%winscpfile%" DEL /Q /F "%winscpfile%"

:SetWinSCPSyncCommand
REM synchronize command: 
https://winscp.net/eng/docs/scriptcommand_synchronize
SET ftpcmd=synchronize local -delete -mirror "%localdir%\"
   
:ftpout
>>"%logfile%" ECHO.
>>"%logfile%" ECHO ***************************  FTP OUT  
***************************
     >>"%logfile%" ECHO Synchronizing files to %winscplogin% 
server  on 
%date% at %time%

>>"%winscpfile%" ECHO option batch on
>>"%winscpfile%" ECHO option confirm off
>>"%winscpfile%" ECHO option transfer binary
>>"%winscpfile%" ECHO open %winscplogin%
>>"%winscpfile%" ECHO cd "%remotedir%"
>>"%winscpfile%" ECHO %ftpcmd%
>>"%winscpfile%" ECHO close
>>"%winscpfile%" ECHO exit

>>"%logfile%" ECHO %winscpfile%                                
TYPE "%winscpfile%" >> %logfile%
>>"%logfile%" ECHO ------------------------------------------ 
"%prgwinscp%" /script="%winscpfile%" >>"%logfile%" 2>&1
>>"%logfile%" ECHO ------------------------------------------
IF EXIST "%winscpfile%" DEL /Q /F "%winscpfile%"
>>"%logfile%" ECHO Transmission complete on %date% at %time%

ping -n 2 -w 1000 127.0.0.1 > nul
2

There are 2 best solutions below

0
ecuso On

Based on https://winscp.net/eng/docs/library_example_delete_after_successful_download

param (
    $localPath = "C:\Users\Users1\Folder1",
    $remotePath = "/foldersource/"
)
  
try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property 
    @{
        Protocol = [WinSCP.Protocol]::Sftp
        HostName = "*****"
        UserName = "*****"
        Password = "*****"
        SshHostKeyFingerprint = "ssh-rsa ********************"
        PortNumber = "****"
    }
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        # Synchronize files to local directory, collect results
        $synchronizationResult = $session.SynchronizeDirectories(
            [WinSCP.SynchronizationMode]::Local, $localPath, 
            $remotePath, $False)
 
        # Deliberately not calling $synchronizationResult.Check
        # as that would abort our script on any error.
 
        # Iterate over every download
        foreach ($download in $synchronizationResult.Downloads)
        {
            # Success or error?
            if ($download.Error -eq $Null)
            {
                Write-Host "Download of $($download.FileName) succeeded, removing from source"
                # Download succeeded, remove file from source
                $filename = 
                    [WinSCP.RemotePath]::EscapeFileMask($download.FileName)
                $removalResult = $session.RemoveFiles($filename)

                if ($removalResult.IsSuccess)
                {
                    Write-Host "Removing of file $($download.FileName) succeeded"
                }
                else
                {
                    Write-Host "Removing of file $($download.FileName) failed"
                }
            }
            else
            {
                Write-Host (
                    "Download of $($download.FileName) failed: $($download.Error.Message)")
            }
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }

    exit 0
}
catch
{
    Write-Host "Error: $($_.Exception.Message)"
    exit 1
}
0
Martin Prikryl On

While the code in your self-answer (copied verbatim from WinSCP website) solves the problem, it's imo overkill for most purposes.

See:


Once you have a working WinSCP script, you can easily achieve moving remote files to local folder using -delete switch of the get command:

get -delete /source/remote/path/* C:\target\local\path\

And If you choose to use PowerShell, you can simply call Session.GetFilesToDirectory with remove parameter set to true:

$session.GetFilesToDirectory($remotePath, $localPath, $null, $true).Check()

The above line replaces about 40 lines of your code.