Differences
This shows you the differences between the selected revisions of the page.
library_example_two_way_synchronize_delete 2020-12-18 | library_example_two_way_synchronize_delete 2022-06-16 (current) | ||
Line 1: | Line 1: | ||
- | ====== Two-Way Synchronization with Delete with SFTP/FTP server====== | + | ====== Two-way synchronization with delete with SFTP/FTP server·====== |
WinSCP [[task_synchronize_full|synchronization functionality]] is state-less. So when there is a file on one side, which is absent on the opposite side, WinSCP is not able to determine, if the file was added on the first side, or removed on the latter. For this reason in the [[task_synchronize_full#direction|//Both// direction]], WinSCP does not support the //Delete files// option. | WinSCP [[task_synchronize_full|synchronization functionality]] is state-less. So when there is a file on one side, which is absent on the opposite side, WinSCP is not able to determine, if the file was added on the first side, or removed on the latter. For this reason in the [[task_synchronize_full#direction|//Both// direction]], WinSCP does not support the //Delete files// option. | ||
Line 9: | Line 9: | ||
<code batch> | <code batch> | ||
- | powershell.exe -File C:\path\SynchronizeTwoWayDelete.ps1 -sessionUrl "sftp://user:password@example.com/" -localPath "C:\local" -remotePath "/remote" -listPath "C:\cache\example.txt" | + | powershell.exe -File C:\path\SynchronizeTwoWayDelete.ps1 -sessionUrl "sftp://user:password;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/" -localPath "C:\local" -remotePath "/remote" -listPath "C:\cache\example.txt" |
</code> | </code> | ||
Line 19: | Line 19: | ||
# @description Synchronizes files on local and remote directories including file deletions ^ | # @description Synchronizes files on local and remote directories including file deletions ^ | ||
# by remembering a list of previous local files | # by remembering a list of previous local files | ||
- | # @version 1 | + | # @version 2 |
# @homepage ~~SELF~~ | # @homepage ~~SELF~~ | ||
- | # @require WinSCP 5.17 | + | # @require WinSCP 5.18.1 |
# @option - -run group "Directories" | # @option - -run group "Directories" | ||
# @option LocalPath -run textbox "&Local directory:" "!\" | # @option LocalPath -run textbox "&Local directory:" "!\" | ||
Line 31: | Line 31: | ||
# @option SessionLogPath -config sessionlogfile | # @option SessionLogPath -config sessionlogfile | ||
# @optionspage ~~SELF~~#options | # @optionspage ~~SELF~~#options | ||
- | · | + | |
param ( | param ( | ||
# Use Generate Session URL function to obtain a value for -sessionUrl parameter. | # Use Generate Session URL function to obtain a value for -sessionUrl parameter. | ||
- | $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xx-xx-xx@example.com/", | + | $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/", |
[Parameter(Mandatory = $True)] | [Parameter(Mandatory = $True)] | ||
$localPath, | $localPath, | ||
Line 47: | Line 47: | ||
$refresh | $refresh | ||
) | ) | ||
- | · | + | |
try | try | ||
{ | { | ||
Line 57: | Line 57: | ||
$sessionOptions = New-Object WinSCP.SessionOptions | $sessionOptions = New-Object WinSCP.SessionOptions | ||
$sessionOptions.ParseUrl($sessionUrl) | $sessionOptions.ParseUrl($sessionUrl) | ||
- | · | + | |
$listPath = [Environment]::ExpandEnvironmentVariables($listPath) | $listPath = [Environment]::ExpandEnvironmentVariables($listPath) | ||
$listDir = (Split-Path -Parent $listPath) | $listDir = (Split-Path -Parent $listPath) | ||
Line 74: | Line 74: | ||
$needRefresh = $False | $needRefresh = $False | ||
+ | · | ||
$session = New-Object WinSCP.Session | $session = New-Object WinSCP.Session | ||
- | ···· | + | |
try | try | ||
{ | { | ||
$session.SessionLogPath = $sessionLogPath | $session.SessionLogPath = $sessionLogPath | ||
- | · | + | |
Write-Host "Connecting..." | Write-Host "Connecting..." | ||
$session.Open($sessionOptions) | $session.Open($sessionOptions) | ||
- | · | + | |
Write-Host "Comparing files..." | Write-Host "Comparing files..." | ||
$differences = | $differences = | ||
Line 104: | Line 104: | ||
if ($previousFiles -contains $difference.Local.FileName) | if ($previousFiles -contains $difference.Local.FileName) | ||
{ | { | ||
- | $path = $difference.Local.FileName | + | $difference.Reverse() |
- | Write-Host "Removing local file $path..." | + | |
- | Remove-Item -Recurse $path | + | |
} | } | ||
else | else | ||
{ | { | ||
- | Write-Host "Uploading new $($difference.Local.FileName)..." | ||
- | $difference.Resolve($session) | Out-Null | ||
$needRefresh = $True | $needRefresh = $True | ||
} | } | ||
Line 122: | Line 118: | ||
if ($previousFiles -contains $localFilePath) | if ($previousFiles -contains $localFilePath) | ||
{ | { | ||
- | $path = $difference.Remote.FileName | + | $difference.Reverse() |
- | Write-Host "Removing remote file $path..." | + | |
- | $path = [WinSCP.RemotePath]::EscapeFileMask($path) | + | |
- | $session.RemoveFiles($path).Check() | + | |
$needRefresh = $True | $needRefresh = $True | ||
} | } | ||
else | else | ||
{ | { | ||
- | Write-Host "Downloading new $($difference.Remote.FileName)..." | + | # noop |
- | $difference.Resolve($session) | Out-Null | + | |
} | } | ||
} | } | ||
elseif ($action -eq [WinSCP.SynchronizationAction]::DownloadUpdate) | elseif ($action -eq [WinSCP.SynchronizationAction]::DownloadUpdate) | ||
{ | { | ||
- | Write-Host "Downloading updated $($difference.Remote.FileName)..." | + | # noop |
- | $difference.Resolve($session) | Out-Null | + | |
} | } | ||
elseif ($action -eq [WinSCP.SynchronizationAction]::UploadUpdate) | elseif ($action -eq [WinSCP.SynchronizationAction]::UploadUpdate) | ||
{ | { | ||
- | Write-Host "Uploading updated $($difference.Local.FileName)..." | ||
- | $difference.Resolve($session) | Out-Null | ||
$needRefresh = $True | $needRefresh = $True | ||
} | } | ||
Line 148: | Line 137: | ||
{ | { | ||
throw "Unexpected difference $action" | throw "Unexpected difference $action" | ||
+ | } | ||
+ | |||
+ | Write-Host -NoNewline "$difference ..." | ||
+ | try | ||
+ | { | ||
+ | $difference.Resolve($session) | Out-Null | ||
+ | Write-Host -NoNewline " Done." | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | Write-Host | ||
} | } | ||
} | } | ||
Line 172: | Line 172: | ||
Write-Host "Done." | Write-Host "Done." | ||
- | ···· | + | |
$result = 0 | $result = 0 | ||
} | } | ||
Line 180: | Line 180: | ||
$result = 1 | $result = 1 | ||
} | } | ||
- | · | + | |
# Pause if -pause switch was used | # Pause if -pause switch was used | ||
if ($pause) | if ($pause) | ||
Line 187: | Line 187: | ||
[System.Console]::ReadKey() | Out-Null | [System.Console]::ReadKey() | Out-Null | ||
} | } | ||
- | · | + | |
exit $result | exit $result | ||
</code> | </code> |