Skip to content

Instantly share code, notes, and snippets.

@peaeater
Created December 12, 2022 18:03
Show Gist options
  • Select an option

  • Save peaeater/2b76b83cba9dd664edcacbd339238ba5 to your computer and use it in GitHub Desktop.

Select an option

Save peaeater/2b76b83cba9dd664edcacbd339238ba5 to your computer and use it in GitHub Desktop.

Revisions

  1. peaeater created this gist Dec 12, 2022.
    142 changes: 142 additions & 0 deletions ftp-dir-to-remote.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,142 @@
    <#
    Sync a directory to remote server in FTP mode
    Peter Tyrrell
    #>


    param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$logsrc = "",
    [Parameter(Mandatory = $true, Position = 1)]
    [string]$hostname,
    [Parameter(Mandatory = $true, Position = 2)]
    [string]$username,
    [Parameter(Mandatory = $true, Position = 3)]
    [string]$password,
    [Parameter(Mandatory = $true, Position = 4)]
    [string]$fingerprint,
    [Parameter(Mandatory = $false, Position = 5)]
    [int]$port = 21,
    [Parameter(Mandatory = $false, Position = 6)]
    [string]$remotePath = "/",
    [Parameter(Mandatory = $true, Position = 7)]
    [string]$localPath,
    [Parameter(Mandatory = $false, Position = 8)]
    [string]$winscp = "C:\Program Files (x86)\WinSCP\WinSCPNET.dll",
    [Parameter(Mandatory = $false, Position = 9)]
    [string]$ftpMode = "passive",
    [Parameter(Mandatory = $false, Position = 10)]
    [string]$ftpSecure = "explicit",
    [Parameter(Mandatory = $false, Position = 11)]
    [string]$filemask = $null
    )

    . .\helper.logging.ps1

    function fileTransferred {

    param($e)

    # file transfer status
    if ($null -eq $e.Error) {
    logInfo -logsrc $logsrc -msg ("INFO {0} upload OK" -f $e.FileName)
    }
    else {
    logError -logsrc $logsrc -msg ("ERROR {0} upload failure: {1}" -f $e.FileName, $e.Error)
    exit 1
    }

    # file permissions status
    if ($null -ne $e.Chmod) {
    if ($null -ne $e.Chmod.Error) {
    logError -logsrc $logsrc -msg ("ERROR {0} set permissions failure: {1}" -f $e.Chmod.FileName, $e.Chmod.Error)
    }
    }

    # timestamp status
    if ($null -ne $e.Touch) {
    if ($null -ne $e.Touch.Error) {
    logError -logsrc $logsrc -msg ("ERROR {0} set timestamp failure: {1}" -f $e.Touch.FileName, $e.Touch.Error)
    }
    }
    }


    <#
    Push files to remote server.
    #>

    try {

    # load winscp assembly
    Add-Type -Path $winscp

    # session options
    $sessionOptions = New-Object WinSCP.SessionOptions

    $sessionOptions.Protocol = [WinSCP.Protocol]::Ftp
    if ($ftpSecure -like "explicit") {
    $sessionOptions.FtpSecure = [WinSCP.FtpSecure]::Explicit
    }
    elseif ($ftpSecure -like "implicit") {
    $sessionOptions.FtpSecure = [WinSCP.FtpSecure]::Implicit
    }
    else {
    $sessionOptions.FtpSecure = [WinSCP.FtpSecure]::None
    }
    if ($ftpMode -like "active") {
    $sessionOptions.FtpMode = [WinSCP.FtpMode]::Active
    }
    else {
    $sessionOptions.FtpMode = [WinSCP.FtpMode]::Passive
    }
    $sessionOptions.TlsHostCertificateFingerprint = $fingerprint
    $sessionOptions.PortNumber = $port
    $sessionOptions.HostName = $hostname
    $sessionOptions.UserName = $username
    $sessionOptions.Password = $password

    $session = New-Object WinSCP.Session

    # sync dirs
    try {

    # continuously report sync progress
    $session.add_FileTransferred( { fileTransferred($_) } )

    # connect
    $session.Open($sessionOptions)

    # apply file mask
    $transferOptions = $null
    if ($null -ne $filemask) {
    $transferOptions = New-Object WinSCP.TransferOptions
    $transferOptions.FileMask = $filemask
    }

    # sync files 1 direction, from local => remote. Push all local files, newer and older, and delete obsolete remote files.
    $syncResult = $session.SynchronizeDirectories([WinSCP.SynchronizationMode]::Remote, $localPath, $remotePath, $true, $true, [WinSCP.SynchronizationCriteria]::Time, $transferOptions)

    # throw exception for any error
    $syncResult.Check()

    $uploadCount = $syncResult.Uploads.Count
    $downloadCount = $syncResults.Downloads.Count
    $removalCount = $syncResults.Removals.Count

    logInfo -logsrc $logsrc -msg (("File sync to {0} successful: {1} uploaded, {2} downloaded, {3} removed." -f $hostname, $uploadCount, $downloadCount, $removalCount))

    }
    finally {
    # disconnect, clean up
    $session.Dispose()
    }

    exit 0
    }
    catch [Exception] {
    # any uncaught exception bubbles up here
    logError -logsrc $logsrc -msg $_.Exception
    exit 1
    }