Post a reply

Before posting, please read how to report bug or request support effectively.

Bug reports without an attached log file are usually useless.

Options
Add an Attachment

If you do not want to add an Attachment to your Post, please leave the Fields blank.

(maximum 10 MB; please compress large files; only common media, archive, text and programming file formats are allowed)

Options

Topic review

Stay_happy

I did it and i managed it to get it running but then i noticed a problem. If there is an error during the sync. and it saves the file list then it will delete everything on the pc that was not sucessfully copied to the server.
So i tried to get my first approach running without the error skipping to avoid this hazard.
And this is the code i posted.
martin

You didn't add the code I've suggested.
You still didn't replace the $difference.Resolve($session) line with the code from my earlier post.
Stay_happy

My code:
# @name         Two-Way Synchronization with Delete...
# @command      powershell.exe -ExecutionPolicy Bypass -File "%EXTENSION_PATH%" ^
#                   -sessionUrl "!E" -localPath "%LocalPath%" -remotePath "%RemotePath%" ^
#                   -listPath "%ListPath%" -refresh -pause -sessionLogPath "%SessionLogPath%"
# @description  Synchronizes files on local and remote directories including file deletions ^
#                   by remembering a list of previous local files
# @version      2
# @homepage     https://winscp.net/eng/docs/library_example_two_way_synchronize_delete
# @require      WinSCP 5.18.1
# @option       - -run group "Directories"
# @option         LocalPath -run textbox "&Local directory:" "!\"
# @option         RemotePath -run textbox "&Remote directory:" "!/"
# @option       - -run group "Options"
# @option         ListPath -run textbox "Re&member previous local files in:" ^
#                     "%LOCALAPPDATA%\WinSCP\TwoWayDelete\!N.txt"
# @option       - -config group "Logging"
# @option         SessionLogPath -config sessionlogfile
# @optionspage  https://winscp.net/eng/docs/library_example_two_way_synchronize_delete#options
 
param (
    # Use Generate Session URL function to obtain a value for -sessionUrl parameter.
    $sessionUrl = "sftp://user:mypassword;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/",
    [Parameter(Mandatory = $True)]
    $localPath,
    [Parameter(Mandatory = $True)]
    $remotePath,
    [Parameter(Mandatory = $True)]
    $listPath,
    $sessionLogPath = $Null,
    [Switch]
    $pause,
    [Switch]
    $refresh
)
 
 
try
{
    # Load WinSCP .NET assembly
    $assemblyPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { $PSScriptRoot }
    Add-Type -Path (Join-Path $assemblyPath "WinSCPnet.dll")
 
    # Setup session options from URL
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.ParseUrl($sessionUrl)
 
    $listPath = [Environment]::ExpandEnvironmentVariables($listPath)
    $listDir = (Split-Path -Parent $listPath)
    New-Item -ItemType directory -Path $listDir -Force | Out-Null
 
    if (Test-Path $listPath)
    {
        Write-Host "Loading list of previous local files..."
        [string[]]$previousFiles = Get-Content $listPath
    }
    else
    {
        Write-Host "No list of previous local files"
        $previousFiles = @()
    }
 
    $needRefresh = $False
 
    $session = New-Object WinSCP.Session
   $fileTransferOptions = New-Object WinSCP.TransferOptions($Null)
   $fileTransferOptions.FileMask = "*.* | Desktop.ini"
 
    try
    {
        $session.SessionLogPath = $sessionLogPath
 
        Write-Host "Connecting..."
        $session.Open($sessionOptions)
 
        Write-Host "Comparing files..."
        $differences =
            $session.CompareDirectories(
                [WinSCP.SynchronizationMode]::Both, $localPath, $remotePath, $False, $False, "Time", $fileTransferOptions)
 
        if ($differences.Count -eq 0)
        {
            Write-Host "No changes found."   
        }
        else
        {
            Write-Host "Synchronizing $($differences.Count) change(s)..."
   # options: new TransferOptions { FileMask = "|*.txt" });
 
 
            foreach ($difference in $differences)
            {
                $action = $difference.Action
                if ($action -eq [WinSCP.SynchronizationAction]::UploadNew)
                {
                    if ($previousFiles -contains $difference.Local.FileName)
                    {
                        $difference.Reverse()
                    }
                    else
                    {
                        $needRefresh = $True
                    }
                }
                elseif ($action -eq [WinSCP.SynchronizationAction]::DownloadNew)
                {
                    $localFilePath =
                        [WinSCP.RemotePath]::TranslateRemotePathToLocal(
                            $difference.Remote.FileName, $remotePath, $localPath)
                    if ($previousFiles -contains $localFilePath)
                    {
                        $difference.Reverse()
                        $needRefresh = $True
                    }
                    else
                    {
                        # noop
                    }
                }
                elseif ($action -eq [WinSCP.SynchronizationAction]::DownloadUpdate)
                {
                    # noop
                }
                elseif ($action -eq [WinSCP.SynchronizationAction]::UploadUpdate)
                {
                    $needRefresh = $True
                }
                else
                {
                    throw "Unexpected difference $action"
                }
 
                Write-Host -NoNewline "$difference ..."
                try
                {
               $transferOptions = New-Object WinSCP.TransferOptions
               $transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
               $transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
               $transferOptions.AddRawSettings("ExcludeHiddenFiles", "1")
                    $transferOptions.FileMask = "| printru.ini, desktop.ini, ntuser.dat, lockfile.lck"
                   
                   
                   
                       $difference.Resolve($session, $transferOptions) | Out-Null
                                       
                    Write-Host -NoNewline " Done."
                }
                finally
                {
                    Write-Host
                }
            }
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    # Refresh the remote directory in WinSCP GUI, if it was changed and -refresh switch was used
    if ($refresh -and $needRefresh)
    {
        Write-Host "Reloading remote directory..."
        & "$env:WINSCP_PATH\WinSCP.exe" "$sessionUrl" /refresh "$remotePath"
    }
 
    Write-Host "Saving current local file list..."
    $localFiles =
        Get-ChildItem -Recurse -Path $localPath |
        Select-Object -ExpandProperty FullName
    Set-Content $listPath $localFiles
 
    Write-Host "Done."
 
    $result = 0
}
catch
{
    Write-Host "Error: $($_.Exception.Message)"
    $result = 1
}
 
# Pause if -pause switch was used
if ($pause)
{
    Write-Host "Press any key to exit..."
    [System.Console]::ReadKey() | Out-Null
}
 
exit $result

I have no session log file.
martin

Re: I realised that it is not an option to skip the error, sorry that i did not believed it.

So please post your code and session log file (Session.SessionLogPath).
Stay_happy

I realised that it is not an option to skip the error, sorry that i did not believed it.

I tried it as i am supossed to do but get this error every time i try it.
when calling "Resolve" with 2 argument(s):
"The removed file "/29199214_219757.jpg" cannot be overwritten."$$
Select "Delete" to delete and recreate the file instead of overwriting it . $$
File or directory not found .
Error code: 2
Error message from server : NO such file /29199214_219757.jpg".

I spend several hours trying to solve it bye my own. But I was unsuccessful.
Could you please help me?
Thank you.
martin

Re: Could you please impelment it in the script? I do not know how

I do not know what else should I do for you.
What's so complicated about replacing the $difference.Resolve($session) line with the code from my previous post?
Stay_happy

Could you please impelment it in the script? I do not know how

I have no idea what I have to do regarding the $difference.Resolve.

Could you please implement it in the script for me? I do not know how.
Thank you a lot for your help.
martin

Re: Please help me out, i can not get it running

See how continueOnError is implemented in:
Keep local directory up to date (download changed files from remote SFTP/FTP server)
try
{
    $difference.Resolve($session) | Out-Null
}
catch
{
    Write-Host -ForegroundColor Red $_.Exception.Message
    [System.Console]::Beep()
}


Additionally, your code that sets FileMask three times makes no sense. You just overwrite the previous value. You have to set all your three exclusions in one mask:
$transferOptions.FileMask = "| printru.ini, Desktop.ini, ntuser.dat"
Stay_happy

Please help me out, i can not get it running

Could you please build it in this skript? Because i tried a lot but nothing works.
Please use this skript below because I added a exception for ntuser files.
I would be so happy if anyone would help me out because I invested soooo much time in this projekt but I can not get it running.
Thank you a lot.
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
$transferOptions.AddRawSettings("ExcludeHiddenFiles", "1")
$transferOptions.FileMask = "*.* | printru.ini"#habe ich nachträglich hinzugefügt
$transferOptions.FileMask = "*.* | Desktop.ini"; #habe (ich) nachträglich hinzugefügt
$transferOptions.FileMask = "*.* | ntuser.dat";    #habe ich nachträglich hinzugefügt
 
$difference.Resolve($session, $transferOptions) | Out-Null
martin

Re: Thank you a lot, but I have another error

Just wrap the $difference.Resolve call in try...catch, log the error and continue.
Stay_happy

Thank you a lot, but I have another error

Thank you a lot for the support.
Sometimes during the synchronisation there is a rest of an file that the software can not find. When I search for the file I can't find them too. Only when I copy the complete path from PowerShell and paste it in the Windows 11 explorer, my laptop tries to open the file (so I guess there is something). However it can not open the file and I can not find it in the Windows 11 Explorer.
So how can I modify the synchronisation, to save all errors in a txt and continue even when an error occurs? I want the software to skip the file it can not find. I do not think i can use a mask because I have many diffent files with the problem.

I am using script based on:
https://winscp.net/eng/docs/library_example_two_way_synchronize_delete
martin

Re: I can not find the pasage

That code snippet should go in the place of:
$difference.Resolve($session) | Out-Null
Stay_happy

I can not find the pasage

I can not find this passage
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
$difference.Resolve($session, $transferOptions) | Out-Null

in this script
martin

Re: I can not get it working, please help me

You do not want to ignore the error!
You want to disable the transfer to temporary file name.
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport = New-Object WinSCP.TransferResumeSupport
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off
 
$difference.Resolve($session, $transferOptions) | Out-Null
Stay_happy

I can not get it working, please help me

Thank you very much for your answere.

The error occurs when transferring .jpg files from the ssh server to my win laptop.
I don't think it is the anti vieren program because the error occurs even with the guard disabled.
I have tried unsuccessfully to modify this PowerShell script https://winscp.net/eng/docs/library_example_two_way_synchronize_delete properly. So that the sync skips the error and continues with the other files.
I have also tried these approaches without any success:
https://winscp.net/forum/viewtopic.php?t=26829
https://winscp.net/eng/docs/library_example_recursive_download_custom_error_handling
https://winscp.net/eng/docs/library_session_queryreceived
Would it be possible for you to please send me the modified PowerShell script? I would be very grateful for it.

Kind regards
martin

Re: Error 32 Two-way synchronisation with delete with powershell

There's likely some process on the server that picks the newly uploaded files for some inspection and locks them in the process. That prevents WinSCP from renaming them.
It might be the antivirus.
You might workaround that by disabling transfer to temporary file name. Use TransferOptions.ResumeSupport property.
See also Transfer was successfully finished, but temporary transfer file … could not be renamed to target file name …
Stay_happy

Error 32 Two-way synchronisation with delete with PowerShell

Hello,
I use this https://winscp.net/eng/docs/library_example_two_way_synchronize_delete for the synch with am SSH server and I keep getting the error 32.

Error: Exception when calling Resolve with 1 argument(s): "The transfer completed successfully, but the temporary file "Appointments Overview SS2017.pdf.filepart" could not be renamed to the target file "Appointments Overview SS2017.pdf". If the problem persists, try turning off transfer continuation support.
System error. Code: 32.
The process cannot access the file because it is used by another process

(Error message translated from German to English)

The Error occurs with pictures and maybe also with other files.
I don't know of any process that accesses the files and no write protection or similar has been set.
The error occurs on different laptops and also when I open PowerShell as admin and also with different folders that contain images.
Error also occurs with deactivated four program
It occurs sometimes after 10 files, sometimes after 30 or more files.
If anyone could help me I would be very grateful.