Syncing to FTP Archive (SFTP) using PowerShell and WinSCP

This has simply been one of those really great weeks. I’ve been doing volunteer work for the Gathering 2015 (#TG15, the biggest LAN party in Norway) as an AV technician. During the party all events on the Main stage and TV Studio are streamed live, and also recorded. For the recording storage we used a Windows Server 2012 R2 server with lots of disks, and of course storage spaces. For backup purposes the team wanted to sync the content to a FTP archive, and at some point I said, I can probably write a PowerShell script for that 🙂

Update 2016-03-22: Post updated with SFTP configuration

TG_w800
The Vikingskipet venue in Hamar, Norway (just before the lights were turned off).

The Script

So here it is: a PowerShell script that uses the WinSCP automation library (to sync files to a FTP archive using SFTP):

# This script requires the WinSCP .NET assembly
# Download from http://winscp.net/download/winscp571automation.zip
# Creds: Main part of the script "stolen" from the WinSCP documentation library
#
# Note: There is also a third party WinSCP PowerShell Wrapper available at: http://dotps1.github.io/WinSCP/
 
# Set path to log file
$Logfile = "D:\Scripts\TG15Sync.log"
 
Function LogWrite
{
   Param ([string]$logstring)
 
   Add-content $Logfile -value "[$([DateTime]::Now)] $logstring"
}
 
LogWrite "Sync Started"
 
# Load WinSCP .NET assembly
Add-Type -Path "C:\Setup\winscp571automation\WinSCPnet.dll"
 
# Remote FTP Server settings
$FTPHostName = "FQDN_of_ftp_server"
$FTPPortNumber = "22"
$FTPUserName = "ftpuser"
$FTPPassword = "ftppassword"
 
# Directories to sync (Local to Remote)
$FTPSourceFolder = "D:\Data\Produced_ReadyForTransfer"
$FTPDestionationFolder = "/Video_Archive"
 
# Session.FileTransferred event handler
  
function FileTransferred
{
    param($e)
  
    if ($e.Error -eq $Null)
    {
        LogWrite ("Upload of {0} succeeded" -f $e.FileName)
    }
    else
    {
        LogWrite ("Upload of {0} failed: {1}" -f $e.FileName, $e.Error)
    }
  
    if ($e.Chmod -ne $Null)
    {
        if ($e.Chmod.Error -eq $Null)
        {
            #LogWrite ("Permisions of {0} set to {1}" -f $e.Chmod.FileName, $e.Chmod.FilePermissions)
        }
        else
        {
            LogWrite ("Setting permissions of {0} failed: {1}" -f $e.Chmod.FileName, $e.Chmod.Error)
        }
  
    }
    else
    {
        #LogWrite ("Permissions of {0} kept with their defaults" -f $e.Destination)
    }
  
    if ($e.Touch -ne $Null)
    {
        if ($e.Touch.Error -eq $Null)
        {
            #LogWrite ("Timestamp of {0} set to {1}" -f $e.Touch.FileName, $e.Touch.LastWriteTime)
        }
        else
        {
            LogWrite ("Setting timestamp of {0} failed: {1}" -f $e.Touch.FileName, $e.Touch.Error)
        }
  
    }
    else
    {
        # This should never happen during "local to remote" synchronization
        LogWrite ("Timestamp of {0} kept with its default (current time)" -f $e.Destination)
    }
}
  
# Main script
  
try
{
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::sftp
    $sessionOptions.HostName = $FTPHostName
    $sessionOptions.PortNumber = $FTPPortNumber
    $sessionOptions.UserName = $FTPUserName
    $sessionOptions.Password = $FTPPassword

    # Replace below with your certificate key
    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
  
    $session = New-Object WinSCP.Session
    try
    {
        # Will continuously report progress of synchronization
        $session.add_FileTransferred( { FileTransferred($_) } )
  
        # Connect
        $session.Open($sessionOptions)
  
        # Synchronize files
        $synchronizationResult = $session.SynchronizeDirectories(
            [WinSCP.SynchronizationMode]::Remote, $FTPSourceFolder, $FTPDestionationFolder, $False)
  
        # Throw on any error
        $synchronizationResult.Check()
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
  
    LogWrite "Sync Stopped"
    exit 0
}
catch [Exception]
{
    LogWrite $_.Exception.Message
    LogWrite "Sync Stopped"
    exit 1
}

Happy Syncing

/ Johan

About the author

Johan Arwidmark

5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

>