Delete files first before transferring new files

Advertisement

Ch33s3
Donor
Joined:
Posts:
10
Location:
World

Delete files first before transferring new files

Hi everyone,
I'm using a scripted batch automation to sync files from a local storage to a FTP location - it works like a charm since months! Thank you very much for your great tool and this great forum!
My Question would be if it is possible for WinSCP to first check remote files against local storage assets and delete obsolete remote files FIRST before transferring new files to the remote location?
This is my current setup, maybe you guys could help me out? ;
%winscp% /command ^
    "option batch on" ^
    "option confirm on" ^
    "open %FTPTARGET%" ^
    "synchronize remote -delete -mirror %destWF% %destDF%" ^
    "exit" ^
    /log=%destDL%\Sync_%datestamp%.log ^
    /loglevel=-1
Cheers, have a nice day! :)

Reply with quote

Advertisement

martin
Site Admin
martin avatar
Joined:
Posts:
40,567
Location:
Prague, Czechia

Re: Delete files first before transferring new files

No, there's no such option in scripting.

It is not that difficult to implement this e.g. in PowerShell with help of .NET assembly Session.CompareDirectories method.
https://winscp.net/eng/docs/library_session_comparedirectories

It will be even easier, once this is implemented:
Issue 1802 – .NET assembly functionality to process individual ComparisonDifference instances

Reply with quote

Ch33s3
Donor

Thanks for the fast reply Martin!
Alrighty then, maybe I'll just call some PowerShell instance how you've described it.
Cheers, have a good day!

Reply with quote

Ch33s3
Donor
Joined:
Posts:
10
Location:
World

I finally took some time and assembled some code to work in PowerShell with .NET assembly the usual sync task already works and is very fast, thanks!
Currently the compare files section still doesn't work. In PowerShell ISE it's telling me that
"[WinSCP.ComparisonDifference] no Method with name "Check" contained.

Maybe someone is able to find the error (session options are stored seperatelly and work with sync)
# Compare Files
$comparisonDifferenceCollection = $session.CompareDirectories(
    [WinSCP.SynchronizationMode]::Remote, "C:\Users\XXX\Desktop\WATCHFOLDER", "/DESTINATION", $True ,$False)
 
# Synchronize files #<---WORKING ALREADY!
# $synchronizationResult = $session.SynchronizeDirectories(
#     [WinSCP.SynchronizationMode]::Remote, "C:\Users\Christoph\Desktop\WATCHFOLDER", "/DESTINATION", $True ,$True)
Greetings, have a great weekend!
Last edited by Ch33s3 on 2019-12-01 22:52; edited 1 time in total

Reply with quote

martin
Site Admin
martin avatar

I do not think you can get that error in the code you have posted – There's no Check call. The error must be from some other part of your code.

Reply with quote

Advertisement

Ch33s3
Donor
Joined:
Posts:
10
Location:
World

Thanks! It seems that:
# Throw on any error
#$synchronizationResult.Check()
Caused the error before, sorry I'm new to PowerShell. But I like it already, like an "unlocked" version of WinSCP :)
Now it seems to spool through that part without any error so far.
I think I'm close, I just have to tell the script that it should check with local and if FileX is not present there, delete FileX on remote location..., (then proceed to the sync routine)
The return value ComparisonDifferenceCollection should probably be utilized somehow I assume?
Edit: here is my "frankensteined" build so far: https://pastebin.com/D9HtwWhJ
Cheers!

Reply with quote

martin
Site Admin
martin avatar
Joined:
Posts:
40,567
Location:
Prague, Czechia

$localPath = "C:\Users\XXXX\Desktop\WATCHFOLDER"
$remotePath = "/DESTINATION"
$diffs = $session.CompareDirectories(
    [WinSCP.SynchronizationMode]::Remote, $localPath, $remotePath, $True)
foreach ($diff in $diffs)
{
    if ($diff.Action -eq [WinSCP.SynchronizationAction]::DeleteRemote)
    {
        Write-Host "Deleting $($diff.Remote.FileName)..."
        $session.RemoveFiles(
            [WinSCP.RemotePath]::EscapeFileMask($diff.Remote.FileName)).Check()
    }
}
 
foreach ($diff in $diffs)
{
    if (($diff.Action -eq [WinSCP.SynchronizationAction]::UploadNew) -or
        ($diff.Action -eq [WinSCP.SynchronizationAction]::UploadUpdate))
    {
        Write-Host "Uploading $($diff.Local.FileName)..."
        $session.PutFiles(
            $diff.Local.FileName, $remotePath + "/*", $False).Check()
    }
}

Reply with quote

Ch33s3
Donor

Aaah, thats it!
For testing, I just quickly merged the deleting part and it works like a charm!
Cheers, have a good day and thanks for all your help !!!

Reply with quote

martin
Site Admin
martin avatar
Joined:
Posts:
40,567
Location:
Prague, Czechia

With WinSCP 5.16.5 ComparisonDifference.Resolve, the code can be simplified to:
$diffs = $session.CompareDirectories(
    [WinSCP.SynchronizationMode]::Remote, $localPath, $remotePath, $True)
foreach ($diff in $diffs)
{
    if ($diff.Action -eq [WinSCP.SynchronizationAction]::DeleteRemote)
    {
        Write-Host "Deleting $($diff.Remote.FileName)..."
        $diff.Resolve($session) | Out-Null
    }
}
 
foreach ($diff in $diffs)
{
    if (($diff.Action -eq [WinSCP.SynchronizationAction]::UploadNew) -or
        ($diff.Action -eq [WinSCP.SynchronizationAction]::UploadUpdate))
    {
        Write-Host "Uploading $($diff.Local.FileName)..."
        $diff.Resolve($session) | Out-Null
    }
}

Reply with quote

Advertisement

You can post new topics in this forum