Differences

This shows you the differences between the selected revisions of the page.

2022-06-16 2023-10-31
5.20 Change: SHA-256 fingerprints are not padded anymore (martin) synchronization (martin)
Line 1: Line 1:
-====== Automating transfers in parallel connections over SFTP/FTP protocol ======+====== Automating transfers or synchronization in parallel connections over SFTP/FTP protocol ======
===== Download ===== ===== Download =====
Line 395: Line 395:
} }
</code> </code>
 +
 +===== Synchronization =====
 +
 +==== [[synchronization_powershell]] PowerShell ====
 +
 +//Regarding ''Start-ThreadJob'' cmdlet, see the comment in [[#powershell|Download section]].//
 +
 +<code powershell>
 +param (
 +    $sessionUrl = "sftp://user:password;fingerprint=ssh-rsa-xxxxxxxxxxx...@example.com/",
 +    $remotePath = "/remote/path/",
 +    $localPath = "c:\local\path\",
 +    $removeFiles = $False,
 +    $connections = 3
 +)
 +
 +try
 +{
 +    $assemblyFilePath = "WinSCPnet.dll"
 +    # Load WinSCP .NET assembly
 +    Add-Type -Path $assemblyFilePath
 +
 +    # Setup session options
 +    $sessionOptions = New-Object WinSCP.SessionOptions
 +    $sessionOptions.ParseUrl($sessionUrl)
 +
 +    $started = Get-Date
 +    # Plain variables cannot be modified in job threads
 +    $stats = @{
 +        count = 0
 +    }
 +
 +    try
 +    {
 +        # Connect
 +        Write-Host "Connecting..."
 +        $session = New-Object WinSCP.Session
 +        $session.Open($sessionOptions)
 +       
 +        Write-Host "Comparing directories..."
 +        $differences =
 +            $session.CompareDirectories(
 +                [WinSCP.SynchronizationMode]::Both, $localPath, $remotePath, $removeFiles)
 +        if ($differences.Count -eq 0)
 +        {
 +            Write-Host "No changes found." 
 +        }
 +        else
 +        {
 +            if ($differences.Count -lt $connections)
 +            {
 +                $connections = $differences.Count;
 +            }
 +            $differenceEnumerator = $differences.GetEnumerator()
 +   
 +            for ($i = 1; $i -le $connections; $i++)
 +            {
 +                Start-ThreadJob -Name "Connection $i" -ArgumentList $i {
 +                    param ($no)
 +   
 +                    try
 +                    {
 +                        Write-Host "Starting connection $no..."
 +   
 +                        $syncSession = New-Object WinSCP.Session
 +                        $syncSession.Open($using:sessionOptions)
 +   
 +                        while ($True)
 +                        {
 +                            [System.Threading.Monitor]::Enter($using:differenceEnumerator)
 +                            try
 +                            {
 +                                if (!($using:differenceEnumerator).MoveNext())
 +                                {
 +                                    break
 +                                }
 +   
 +                                $difference = ($using:differenceEnumerator).Current
 +                                ($using:stats).count++
 +                            }
 +                            finally
 +                            {
 +                                [System.Threading.Monitor]::Exit($using:differenceEnumerator)
 +                            }
 +
 +                            Write-Host "$difference in $no..."
 +                            $difference.Resolve($syncSession) | Out-Null
 +                        }
 +   
 +                        Write-Host "Connection $no done"
 +                    }
 +                    finally
 +                    {
 +                        $syncSession.Dispose()
 +                    }
 +                } | Out-Null
 +            }
 +   
 +            Write-Host "Waiting for connections to complete..."
 +            Get-Job | Receive-Job -Wait
 +   
 +            Write-Host "Done"
 +        }
 +
 +        $ended = Get-Date
 +        Write-Host "Took $(New-TimeSpan -Start $started -End $ended)"
 +        Write-Host "Synchronized $($stats.count) differences"
 +    }
 +    finally
 +    {
 +        # Disconnect, clean up
 +        $session.Dispose()
 +    }
 +
 +    exit 0
 +}
 +catch
 +{
 +    Write-Host "Error: $($_.Exception.Message)"
 +    exit 1
 +}
 +</code>
 +

Last modified: by martin