Wednesday, April 5, 2017

SFTP Transfer script with logging

We had a need to copy database dumbs from our data provider to our servers daily. Since I have already used WinSCP with Powershell, so I re-used that script and added logging and folder cleanup.

Requirements:
- WinSCP installed
- PowerShell Logging Module (https://gallery.technet.microsoft.com/scriptcenter/Enhanced-Script-Logging-27615f85)


param (
# Edited 30.03.2017 Miikka Kallberg /CSC - IT Center for Science Ltd.

$sftpserver = "", # SFTP hostname
$sftpuser = "", # SFTP Username
$sftppass = "", # SFTP Password
$sftpkeyfp = "", # SFP Host Key Finger Print
$winscppath = "C:\Program Files (x86)\WinSCP\WinSCPnet.dll", # Path to WinCSPnet.dll
$localPath = "", # Path where to sync
$remotePath = "", # SFTP Path
$filenumber = "", # Number of saved files
$sleepTime = "",  # sleep time in seconds between synchronizations
$logpath = "", # Synck log Path
$synclogfile = "" # Sync Log file
)

# This is a custom module and needs to be installed before running this script
# Default location for PowerShell Modules is: C:\Windows\System32\WindowsPowerShell\v1.0\Modules
# https://gallery.technet.microsoft.com/scriptcenter/Enhanced-Script-Logging-27615f85
#And WinSCP installed with automation package

#Add timestamp to script log
get-date | out-file -filePath (Join-Path $logpath $synclogfile) -Encoding ascii -Force

#Start logging
#Format date and time for the logfilename
$sdate = ((get-date).ToString("yyyyMMdd_HHmmss_"))

#Combine logfile name with time
$synclog =  $sdate + $synclogfile

Import-Module PowerShellLogging

#Define logfile
$LogFile = Enable-LogFile -Path (Join-Path $logpath $synclog)

# Note - it is necessary to save the result of Enable-LogFile to a variable in order to keep the object alive.  As soon as the $LogFile variable is reassigned or falls out of scope, the LogFile object becomes eligible for garbage collection.

$VerbosePreference = 'Continue'
$DebugPreference = 'Continue'

#Start syncin script
try
{
    # Load WinSCP .NET assembly
Add-Type -Path $winscppath

    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = $sftpserver
    $sessionOptions.UserName = $sftpuser
    $sessionOptions.Password = $sftppass
    $sessionOptions.SshHostKeyFingerprint = $sftpkeyfp

    $session = New-Object WinSCP.Session
 
     try
    {
        # Connect
        $session.Open($sessionOptions)

        # Download files
        $transferOptions = New-Object WinSCP.TransferOptions
        $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary

        $transferResult = $session.GetFiles( $remotePath, $localPath, $False, $transferOptions)

        # Throw on any error
        $transferResult.Check()

        # Print results
        foreach ($transfer in $transferResult.Transfers)
        {
            Write-Host ("Download of {0} succeeded" -f $transfer.FileName)
        }
    }

    finally
    {
        # Disconnect, clean up
        $session.Dispose()
   }
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}

#Delete files that are oldest based on $filenumber
Get-ChildItem $localPath | where{-not $_.PsIsContainer}| sort CreationTime -desc|  select -Skip $filenumber | Remove-Item -Force

# Disable logging before the script exits (good practice, but the LogFile will be garbage collected so long as this variable was not in the Global Scope, as a backup in case the script crashes or you somehow forget to call Disable-LogFile).

$LogFile | Disable-LogFile

No comments:

Post a Comment