File Transfer Automation with WinSCP
This is great vbscript script I wrote to automate file transfers using WinSCP. The script can also handle file transfers using the windows copy / move method. There is great deal of error checking and a good amount of time spent fine tuning the script. With conjunction of using scheduled tasks this script is fail proof way to tranfer files.
Overview
- The script checks a directory for files
- If files are not found, an email is sent stating so.
- If files are found an attempt to connect to the FTP site or a check to ensure the destination folder exists is made.
- If the connection is successful or the folder exists, the files are transferred.
- If the file transfer is successful, the files are moved to an archive folder with the date and time stamp appended to the file name.
- Based on the success or error, an email is sent out.
Requirements
The script does require the following items in order to run properly:
- WinSCP Installed
- WinSCP has two executables: winscp.exe and winscp.com. The script uses winscp.com, which is the command line interface.
- winscp.com Path must be added to Path Environmental Variable in Windows. This is achieved during the installation, if custom is selected.
- WinSCP must be configured to use INI file storage. http://winscp.net/eng/docs/ui_pref_storage#configuration_storage
- FTPS and SFTP connections require that the fingerprint of the host certificate be cached before the script is run. You can do this by connecting the FTP site first with the WinSCP GUI. The cached fingerprints are then stored in the winscp.ini file
Parameters
Required Arguments
- /Type -- Transfer Type (FileCopy or WinSCP), Not Case Sensitive
- /SourceFolder: -- Defines the source folder of the claims file
- /FTPSite: -- SFTP FTP site where the files will be uploaded"
- /FTPUser: -- FTP Username
- /FTPPass: -- FTP Password
- /FTPType: -- FTP Protocol
- /DestFolder: -- Destination Directory for File Copy Method
Optional Arguments
- /SFTPPvk: -- SFTP Private Key Path
- /FTPDir: -- If no FTP directory is specified the root directory is used (/)
- /ArchiveFolder: -- If no Archive folder is defined, a Archive folder will be created under the SourceFolder
- /LogFolder: -- If no Log folder is defined, a Log folder will be created under the SourceFolder
- /EmailTo: -- Email Address to Send To
- /EmailSubject: -- Email Subject Line. If Using Spaces Use Quotes
Execution
Usage
cscript FileTransfer.vbs /Type: /SourceFolder: /ArchiveFolder: /LogFolder: /FTPType: /FTPSite: /FTPDir: /FTPUser: /FTPPass: /SFTPPvk: /EmailTo: /EmailSubject
Examples
SFTP File Transfer
cscript FileTransfer.vbs /Type:winscp /SourceFolder:D:\Outgoing\Claims\ /FTPType:sftp /FTPSite: ftp.test.com /FTPUser:ap003 /FTPPass:Test! /EmailTo:test@test.com /EmailSubject:Daily Transfers
SFTP File Transfer with Private Key
cscript FileTransfer.vbs /Type:winscp /SourceFolder:D:\Outgoing\Claims\ /FTPType:sftp /FTPSite:ftp.test.com /FTPUser:ap003 /SFTPPvk:C:\key.ppk /EmailTo:test@test.com /EmailSubject:Daily Transfers
File Copy
cscript FileTransfer.vbs /Type:filecopy /SourceFolder:D:\Outgoing\test\ /DestFolder:\\server.test.com\Folder\ /EmailTo:test@test.com /EmailSubject:Daily File Transfers
Common Issues
The script accounts for a number of general errors that may be encountered during the winscp process. If the script fails and sends a successful alert, further review of the logs will need to be done; error catching will need to added to the script to account for these.
Example of Timeout catch in the script:
If InStr(strLine, "Timeout detected") Then
ErrVal = True
End If
The certificate fingerprint is not stored or the host updates their certificate:
You may get the following error in the WinSCP log file. This is due to the fact that WinSCP requires you to accept the certificate before connecting. There is no current method of automating this acceptance.
- Example WinSCP Log:
- . 2011-10-13 05:15:02.863 Fingerprint (SHA1): 1b:95:18:14:2b:e0:e8:12:09:3f:83:13:91:a0:2a:5c:01:b5:c6:c3
- . 2011-10-13 05:15:02.863
- . 2011-10-13 05:15:02.863 Summary: Unable to get local issuer certificate. The error occured at a depth of 2 in the certificate chain.
- . 2011-10-13 05:15:02.863
- . 2011-10-13 05:15:02.863 If you trust this certificate, press Yes. To connect without storing certificate, press No. To abandon the connection press Cancel.
- . 2011-10-13 05:15:02.863
- . 2011-10-13 05:15:02.863 Continue connecting and store the certificate? ()
- . 2011-10-13 05:15:02.863 Peer certificate rejected
- . 2011-10-13 05:15:02.863 Disconnected from server
- . 2011-10-13 05:15:02.863 Connection failed.
Additional Info
Errors are read from the logfiles the script creates, LogFiles are created for the winscp process and the script itself. They are located by default in the Log directory under the source directory specified.
- Script LogFile: date+time.log
- WinSCP LogFile: WinSCP+date+time.txt
The script also creates a temporary file in the log directory. This file contains the commands used to transfer the files with WinSCP. The file is deleted after the script has run.
- Temporary WinSCP File: SCPScript.tmp
Full Script
'#####================================================================================
'## Title: FileTransfer.vbs
'## Author: Sean Stark
'## Date: 05/04/2012
'##
'## Purpose: Tranfers files using WinSCP Console or Windows File Copy Method
'##
'## Prerequisites:
'## 1. The Script requires WinSCP to be installed on the machine where the script is being run.
'## 2. WinSCP Enviromental Variables must be defined as well
'## 3. Run the script with the appropriate permissions to the source folder and destination folder.
'## 4. WinSCP requires you to accept the certificate fingerprint before connecting via SFTP, FTPS, or SCP, there is no way of automatically accepting the certficate.
'## a. Change WinSCP to use INI file storage.
'## http://winscp.net/eng/docs/ui_pref_storage#configuration_storage
'## b. Connect to FTP Site To Save the Certiface fingerprint to the INI file before running the script
'##
'## Basic Logic:
'## 1. The script checks the directory for files
'## 2. If files are not found, an email is sent stating so.
'## 3. If files are found an attempt to connect to the FTP site is made.
'## 4. If the connection is successful, the files are uploaded.
'## 5. If the file transfer is successful, the files are moved to an archive folder with the date and time stamp appended to the file name.
'## 6. Based on the success or error, an email is sent out.
'##
'## Documentation: Read at the end of the script for documentation, Variable Defintions and Reference Section
'#####================================================================================
Option Explicit
'*********** Variables ********************
'Scripting Variables
Dim objShell, objFSO, objSourceFolder, objArgs, objArgNamed, objStdOut, objFile, objWMIService, objMessage, objLogFile, objSCPFile
'FTP Variables
Dim strFTPType, strFTPSite, strFTPUser, strFTPPass, strPVK, strFTPDir
'Data Variables
Dim LgFolder, SrcFolder, DestDir, ArchFolder, WinSCPLogName, WinSCPLog, WinSCPScript, LogFileX, strLogName, strFileName
'Email Variables
Dim strEmailFrom, strEmailServer, strEmailAddress, strEmailSubject, strCDOBody
'General Variables
Dim FileCount, ReturnVal, NoFiles, ErrVal, strScriptInfo, strStartTime, strStopTime, strCommand, strOutPut, strError, strComputer, strType, bolPVK, strLine
'************** Define Gerneral Scripting Objects / Variables ****************************
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objArgs = Wscript.Arguments
Set objArgNamed = WScript.Arguments.Named
Const ForAppending = 8
Const ForWriting = 2
Const ForReading = 1
FileCount = 0 'Count for Files Found Matching
strStartTime = Now
NoFiles = False
ErrVal = False
strLogName = CustomDateTimeFormat() & ".log"
'*** Email Settings
strEmailFrom = "FileTransfers@test.org"
strEmailServer = "email01.test.org"
'***************** Define and Check For Variables Passed Into The Script *********************
' If no Arguments are passed in show the help sub procedure.
If (objArgs.count = 0) or objArgs.Named.Exists("?") Then
ShowHelp()
End If
'Required Arguments, if not met, show help and quit script.
If objArgs.Named.Exists("Type") Then
strType = objArgs.Named("Type")
strType = LCase(strType)
If strType = "winscp" Then
WinSCPTransfer()
ElseIf strType = "filecopy" Then
FileCopyTransfer()
Else
Wscript.echo " Please use the correct syntax for specifying the Transfer Type, Not Case Sensitive"
Wscript.echo ""
Wscript.echo " Example:"
Wscript.echo " /Type:FileCopy"
Wscript.echo " /Type:WinSCP"
Wscript.quit
End If
Else
Wscript.echo " No Transfer Type Was Specified. Please Specify Transfer Type (FileCopy or WinSCP), Not Case Sensitive"
Wscript.echo ""
Wscript.echo " Example:"
Wscript.echo " /Type:FileCopy"
Wscript.echo " /Type:WinSCP"
Wscript.quit
End If
LogFileX.WriteLine ""
'################ Sub Procedures Section ################
'********* Provides information on how to run the script
Sub ShowHelp()
Wscript.echo "*********************************************************************************"
Wscript.echo "This script is used to tranfer files using WinSCP and Windows Copy Method."
Wscript.echo ""
Wscript.echo "Usage: "
Wscript.echo "cscript FileTransfer.vbs /Type: /SourceFolder: /ArchiveFolder: /LogFolder: /FTPType: /FTPSite: /FTPDir: /FTPUser: /FTPPass: /SFTPPvk: /EmailTo: /EmailSubject:"
Wscript.echo ""
Wscript.echo " Examples:"
Wscript.echo ""
Wscript.echo " SFTP File Transfer"
Wscript.echo "cscript FileTransfer.vbs /Type:winscp /SourceFolder:D:\Outgoing\Claims\ /FTPType:sftp /FTPSite:ftp.test.com /FTPUser:test /FTPPass:Test! /EmailTo:test@test.com /EmailSubject:Daily Transfers"
Wscript.echo ""
Wscript.echo " SFTP File Transfer with Private Key"
Wscript.echo "cscript FileTransfer.vbs /Type:winscp /SourceFolder:D:\Outgoing\Claims\ /FTPType:sftp /FTPSite:ftp.test.com /FTPUser:test /SFTPPvk:C:\key.ppk /EmailTo:test@test.com /EmailSubject:Daily Transfers"
Wscript.echo ""
Wscript.echo " File Copy"
Wscript.echo "cscript FileTransfer.vbs /Type:filecopy /SourceFolder:D:\Outgoing\Claims\ /DestFolder:\\server.test.com\Folder\ /EmailTo:test@test.com /EmailSubject:Daily File Transfers"
Wscript.echo ""
Wscript.echo "************************************* Required Arguments ********************************************"
Wscript.echo ""
Wscript.echo " /Type -- Transfer Type (FileCopy or WinSCP), Not Case Sensitive"
Wscript.echo " /SourceFolder: -- Defines the source folder of the claims file"
Wscript.echo " /FTPSite: -- SFTP FTP site where the files will be uploaded"
Wscript.echo " /FTPUser: -- FTP Username"
Wscript.echo " /FTPPass: -- FTP Password"
Wscript.echo " /FTPType: -- FTP Protocol"
Wscript.echo " /DestFolder: -- Destination Directory for File Copy Method"
Wscript.echo ""
Wscript.echo "************************************* Optional Arguments ********************************************"
Wscript.echo ""
Wscript.echo " /SFTPPvk: -- SFTP Private Key Path"
Wscript.echo " /FTPDir: -- If no FTP directory is specified the root directory is used (/)"
Wscript.echo " /ArchiveFolder: -- If no Archive folder is defined, a Archive folder will be created under the SourceFolder"
Wscript.echo " /LogFolder: -- If no Log folder is defined, a Log folder will be created under the SourceFolder"
Wscript.echo " /EmailTo: -- Email Address to Send To"
Wscript.echo " /EmailSubject: -- Email Subject Line. If Using Spaces Use Quotes"
Wscript.echo ""
Wscript.echo "*********************************************************************************"
wscript.quit(1)
End Sub
Sub WinSCPTransfer
'Check for FTP Arguments Passed In.
If objArgs.Named.Exists("SFTPPvk") Then
strPVK = objArgs.Named("SFTPPvk")
bolPVK = True
Else
Wscript.echo "No Private Key defined"
End If
If objArgs.Named.Exists("FTPType") Then
strFTPType = objArgs.Named("FTPType")
Else
LogFileX.close
Wscript.echo "No FTP Type defined, Please Define a FTP Protocol"
Wscript.quit
End If
If objArgs.Named.Exists("FTPSite") Then
strFTPSite = objArgs.Named("FTPSite")
Else
LogFileX.close
Wscript.echo "No FTP Site defined, Please Define a FTP Site"
Wscript.quit
End If
If objArgs.Named.Exists("FTPUser") Then
strFTPUser = objArgs.Named("FTPUser")
Else
Wscript.echo "No FTP User defined"
End If
If objArgs.Named.Exists("FTPPass") Then
strFTPPass = objArgs.Named("FTPPass")
Else
Wscript.echo "No FTP Password Defined"
End If
If objArgs.Named.Exists("FTPDir") Then
strFTPDir = objArgs.Named("FTPDir")
Else
Wscript.echo "No FTP Directory defined, Assuming / Path"
strFTPDir = ""
End If
'Check for Directories
DirChk()
LogFileX.WriteLine "FTP Protocol: " & strFTPType
LogFileX.WriteLine "FTP Site: " & strFTPSite
LogFileX.WriteLine "FTP Username: " & strFTPUser
LogFileX.WriteLine "FTP Password: " & strFTPPass
LogFileX.WriteLine "FTP Directory: " & strFTPDir
LogFileX.WriteLine "SFTP Private Key Path: " & strPVK
LogFileX.WriteLine ""
LogFileX.WriteLine "********************************************************************"
LogFileX.WriteLine ""
'**** First Verify if there are any files in the Source Folder
Set objSourceFolder = objFSO.GetFolder(SrcFolder)
FileCount = objSourceFolder.Files.Count
If FileCount = 0 Then
NoFiles = True
LogFileX.WriteLine "No Files Found, Exiting Script"
strCDOBody = SrcFolder
SendEmail()
Else
'Create the WinSCP Script File
Set WinSCPScript = objFSO.CreateTextFile(LgFolder & "\SCPScript.tmp")
'Set the WinSCPLog Location
WinSCPLogName = "WinSCP" & CustomDateTimeFormat() & ".txt"
WinSCPLog = LgFolder & "\" & WinSCPLogName
LogFileX.WriteLine "********** Files to be Sent ***************"
LogFileX.WriteLine ""
'***** Write to the script file ***********
WinSCPScript.WriteLine "option batch on"
WinSCPScript.WriteLine "option confirm off"
WinSCPScript.WriteLine "option batch continue"
'Check if a Private Key Was Provided.
If bolPVK = True Then
WinSCPScript.WriteLine "open " & strFTPType & "://" & strFTPUser & ":" & strFTPPass & "@" & strFTPSite & " -privatekey=" & strPVK
Else
WinSCPScript.WriteLine "open " & strFTPType & "://" & strFTPUser & ":" & strFTPPass & "@" & strFTPSite
End If
WinSCPScript.WriteLine "option transfer binary"
WinSCPScript.WriteLine "cd " & strFTPDir
'For Each File in the Source Folder, create a WinSCP Command to upload the file
For Each objFile in objSourceFolder.Files
LogFileX.WriteLine "Found File: " & objSourceFolder & "\" & objFile.Name
WinSCPScript.WriteLine "put " & chr(34) & objSourceFolder & "\" & objFile.Name & chr(34)
Next
WinSCPScript.WriteLine "ls" 'List the SFTP Directory Contents
WinSCPScript.WriteLine "Close" 'Close the connection
WinSCPScript.WriteLine "Exit" 'Exit WinSCP
WinSCPScript.Close
'*********** End Write to the script file ***********
LogFileX.WriteLine ""
LogFileX.WriteLine "********** Begin WinSCP Console Output Log ***************"
LogFileX.WriteLine ""
'************** Start the WinSCP process ***********
'Set the winscp.com command:
strCommand = "winscp.com /log=" & WinSCPLog & " /script=" & LgFolder & "\SCPScript.tmp"
'Run the Command
Set ReturnVal = objShell.Exec(strCommand)
'Check for runtime Errors
If Err.Number <> 0 Then
ErrVal = True
LogFileX.WriteLine "Error running winscp.com executable."
LogFileX.WriteLine ""
LogFileX.WriteLine "Error Number: " & Err.Number
LogFileX.WriteLine "Error Source: " & Err.Source
LogFileX.WriteLine "Error Description: " & Err.Description
LogFileX.WriteLine ""
End If
'Get the Output from the WinSCP command
Set objStdOut = ReturnVal.StdOut
strOutPut = objStdOut.ReadAll
LogFileX.WriteLine "WinSCP Console Output"
LogFileX.WriteLine ""
LogFileX.WriteLine strOutPut
'********************* Note that in case of fatal failure the log file may not exist at all *******************************
LogFileX.WriteLine ""
LogFileX.WriteLine "********** WinSCP Log End ***************"
LogFileX.WriteLine ""
'Temporarily Close the Log file.
LogFileX.Close
LogError()
'********* Re-open the Log File.
Set LogFileX = objFSO.OpenTextFile(LgFolder & "\" & strLogName, ForAppending, True)
'Open the WinSCP Log File for reading
Set objSCPFile = objFSO.OpenTextFile(WinSCPLog, ForReading)
'*************** Parse the WinSCPLog and look for any errors *********************
LogFileX.WriteLine "Searching " & WinSCPLog & " For Errors"
LogFileX.WriteLine ""
'****** Search the WinSCP Log file for connection Errors *************
If ErrVal = False Then
WinSCPError()
End If
strCDOBody = strCDOBody & vbCRLF & SrcFolder
strError = strError
If ErrVal = False Then
LogFileX.WriteLine "No WinSCP Errors Found"
'Archive Files
FileArchiver()
Else
LogFileX.WriteLine "WinSCP Connection Errors Found:"
LogFileX.WriteLine strError
End If
LogFileX.WriteLine ""
LogFileX.WriteLine "********** End WinSCP Log, For the Full log view the " & WinSCPLog & " file in the log folder ***********"
LogFileX.WriteLine ""
objFSO.DeleteFile(LgFolder & "\SCPScript.tmp")
SendEmail()
End If
End Sub
'Sub Procedure for Transfer Files Via VB Filecopy Method
Sub FileCopyTransfer
Err.Clear
'Check for Destination Directory Arugment
If objArgs.Named.Exists("DestFolder") Then
DestDir = objArgs.Named("DestFolder")
If not objFSO.FolderExists(DestDir) Then
ErrVal = True
strError = "Invalid Destination Directory"
SendEmail()
Wscript.quit
End If
Else
Wscript.echo "No Destination directory defined, Please Define a Destination directory"
LogFileX.close
Wscript.quit
End If
DirChk()
LogFileX.WriteLine "Destination Folder: " & DestDir
LogFileX.WriteLine ""
LogFileX.WriteLine "********************************************************************"
LogFileX.WriteLine ""
Set objSourceFolder = objFSO.GetFolder(SrcFolder)
FileCount = objSourceFolder.Files.Count
If FileCount = 0 Then
NoFiles = True
LogFileX.WriteLine "No Files Found, Exiting Script"
strCDOBody = SrcFolder
SendEmail()
Else
LogFileX.WriteLine "********** Begin File Transfer ***************"
LogFileX.WriteLine ""
'Copy Each File to the Destination Directory
For Each objFile in objSourceFolder.Files
LogFileX.WriteLine ""
LogFileX.WriteLine "Found File: " & objSourceFolder & "\" & objFile.Name
On Error Resume Next
objFSO.CopyFile objSourceFolder & "\" & objFile.Name, DestDir & "\"
'Check for Errors
If Err.Number <> 0 Then
LogFileX.WriteLine "Error Found Copying Files: " & vbCRLF & "Error: " & Err.Number & " " & vbCRLF & "Description: " & Err.Description & vbCRLF & "Source: " & Err.Source
strError = vbCRLF & "Errors Found During File Copy Process" & vbCRLF & "Error: " & Err.Number & " " & vbCRLF & "Description: " & Err.Description
ErrVal = True
Else
LogFileX.WriteLine ""
LogFileX.WriteLine "Copied File: " & objSourceFolder & "\" & objFile.Name & " to " & DestDir
LogFileX.WriteLine ""
End If
Next
If ErrVal = False Then
LogFileX.WriteLine "No File Transfer Errors Found"
LogFileX.WriteLine ""
'Archive Files
FileArchiver()
End If
SendEmail()
End If
End Sub
'Sub Procedure for Archiving Files Appeneded with Date Timestamp
Sub FileArchiver
LogFileX.WriteLine "Found a total of " & FileCount & " Files"
LogFileX.WriteLine ""
strCDOBody = strCDOBody & vbCRLF & "Sent File(s) "
For Each objFile in objSourceFolder.Files
strFileName = objFile.Name & "_" & CustomDateTimeFormat()
LogFileX.WriteLine "Archived File: " & objSourceFolder & "\" & objFile.Name & " to " & ArchFolder & "\" & strFileName
strCDOBody = strCDOBody & vbCRLF & objFile.Name
On Error Resume Next
objFSO.MoveFile objSourceFolder & "\" & objFile.Name, ArchFolder & "\" & strFileName
'Check for Errors
If Err.Number <> 0 Then
LogFileX.WriteLine "Error Found Archiving Files: " & Err.Number & " " & Err.Description
strError = vbCRLF & "Errors Found During Archiving Process" & vbCRLF & "Error: " & Err.Number & " " & vbCRLF & "Description: " & Err.Description
ErrVal = True
End If
Next
End Sub
'Sub Procedure for Checking that Directories Exists ********************
Sub DirChk
'Check that the Source Folder was Defined, if not quit.
If objArgs.Named.Exists("SourceFolder") Then
SrcFolder = objArgs.Named("SourceFolder")
Else
LogFileX.close
Wscript.echo "No source folder defined, Please Define a Source Folder"
Wscript.quit
End If
'Optional Archive and LogFolder Directories Location Arguments.
If objArgs.Named.Exists("ArchiveFolder") Then
ArchFolder = objArgs.Named("ArchiveFolder")
Else
Wscript.echo "No Archive folder defined, Using Source Folder Path"
ArchFolder = objArgs.Named("SourceFolder") & "\Archive"
End If
If objArgs.Named.Exists("LogFolder") Then
LgFolder = objArgs.Named("LogFolder")
Else
Wscript.echo "No log folder defined, Using Source Folder Path"
LgFolder = objArgs.Named("SourceFolder") & "\Logs"
End If
'Confirm Directories Exist, If not create them
If not objFSO.FolderExists(SrcFolder) Then
objFSO.CreateFolder(SrcFolder)
End If
If not objFSO.FolderExists(ArchFolder) Then
objFSO.CreateFolder(ArchFolder)
End If
If not objFSO.FolderExists(LgFolder) Then
objFSO.CreateFolder(LgFolder)
End If
'Create the Log File
Set LogFileX = objFSO.CreateTextFile(LgFolder & "\" & strLogName)
LogFileX.WriteLine "************ Begin Logging " & strStartTime & " *******************"
LogFileX.WriteLine "Script Ran By: " & GetUserName()
LogFileX.WriteLine ""
LogFileX.WriteLine "Source Folder: " & SrcFolder
LogFileX.WriteLine "Archive Folder: " & ArchFolder
LogFileX.WriteLine "Log Folder: " & LgFolder
End Sub
'Sub Procedure for Finding Errors in the Log File
Sub LogError
'Open the Log File for Reading
Set objLogFile = objFSO.OpenTextFile(LgFolder & "\" & strLogName, ForReading)
'****** Search the Log file for connection Errors *************
Do Until objLogFile.AtEndOfStream
strLine = objLogFile.ReadLine
If InStr(strLine, "Connection failed") Then
ErrVal = True
strError = strLine
End If
If InStr(strLine, "Failed to connect") Then
ErrVal = True
strError = strLine
End If
If InStr(strLine, "Network error: Connection refused.") Then
ErrVal = True
strError = strLine
End If
If InStr(strLine, "Host does not exist") Then
ErrVal = True
strError = strLine
End If
Loop
objLogFile.Close
End Sub
'Sub Procedure for Finding Errors When Transfering Files via WinSCP FTP Methods
Sub WinSCPError
Do Until objSCPFile.AtEndOfStream
strLine = objSCPFile.ReadLine
If InStr(strLine, "Access denied") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Network error: Connection refused.") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Disconnected: Unable to authenticate") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Network error: Connection timed out") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Network error: No route to host") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Network error: Software caused connection abort") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Timeout detected") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Host does not exist") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Permission Denied") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Host key wasn't verified!") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Error transferring file") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Error message from server") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Copying files to remote side failed") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "Copying files to remote side failed") Then
ErrVal = True
strError = strError & " " & strLine
End If
If InStr(strLine, "System Error") Then
ErrVal = True
strError = strError & " " & strLine
End If
Loop
End Sub
'Sub Procedure for Sending Email Notification Based on Error Conditions ***************************************************
Sub SendEmail()
'Check for Email Arguments
If objArgs.Named.Exists("EmailTo") Then
strEmailAddress = objArgs.Named("EmailTo")
Else
Wscript.echo "No Email Address defined, Please Define an Email Address"
End If
If objArgs.Named.Exists("EmailSubject") Then
strEmailSubject = objArgs.Named("EmailSubject")
Else
Wscript.echo "No Email Subject defined"
End If
'Define Script Info
strScriptInfo = "SFTP Site: " & strFTPSite & " SFTP User: " & strFTPUser & " Local Server: " & GetLocalComputerName() & " Script Run Time: " & GetRunTime()
'Setup Vbscript CDO Email Message Details
Set objMessage = CreateObject("CDO.Message")
objMessage.From = strEmailFrom
objMessage.To = strEmailAddress
'Define the CDO Email Configuration Details
'Set the method of sending. Set to cdoSendUsingPort (SMTP over the network)
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
'Set the name or IP of the remote SMTP server
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strEmailServer
'Set the connection timeout in seconds (the maximum time CDO will try to establish a connection to the SMTP server)
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60
'Activate the configuration
objMessage.Configuration.Fields.Update
'Send an Email based on errors found, no files found, or success
If NoFiles = True Then
objMessage.Subject = "File Transfer Warning Alert " & strEmailSubject
objMessage.TextBody = "There were no new files detected to send" & vbCRLF & strScriptInfo
On Error Resume Next
objMessage.Send
If Err.Number <> 0 Then
LogFileX.WriteLine "Error Sending Email: " & Err.Number & " " & Err.Description
End If
Wscript.quit
End If
If ErrVal = True Then
objMessage.Subject = "File Transfer Error Alert " & strEmailSubject
objMessage.TextBody = "There was an error detected during the File Transfer Process. Please review the Log Files for more information" & vbCRLF & "Error: " & strError & vbCRLF & strScriptInfo
On Error Resume Next
objMessage.Send
If Err.Number <> 0 Then
LogFileX.WriteLine "Error Sending Email: " & Err.Number & " " & Err.Description
End If
Else
objMessage.Subject = "File Transfer Success Alert " & strEmailSubject
objMessage.TextBody = vbCRLF & strCDOBody & vbCRLF & "Successful File Transfer Operation . Please review the Log Files for more information " & vbCRLF & strScriptInfo
On Error Resume Next
objMessage.Send
If Err.Number <> 0 Then
LogFileX.WriteLine "Error Sending Email: " & Err.Number & " " & Err.Description
End If
End If
End Sub
'###################################################
'################ Functions Section ################
Function CustomDateTimeFormat()
'DESC: Returns a custom date time format
On Error Resume Next
CustomDateTimeFormat = year(now) & Right("0" & month(now),2) & Right("0" & day(now),2) & Right("0" & hour(now),2) & Right("00" & minute(now),2) & Right("00" & second(now),2)
End Function
Function GetLocalComputerName()
'DESC: Returns local computer name
On Error Resume Next
Dim objWshNetwork: Set objWshNetwork = CreateObject ("WScript.Network")
GetLocalComputerName =UCase(objWshNetwork.ComputerName)
Set objWshNetwork = Nothing
End Function
Function GetScriptName()
'DESC: Returns script name
On Error Resume Next
Dim objFSO: Set objFSO = CreateObject("Scripting.FileSystemObject")
GetScriptName = UCase(objFSO.GetBaseName(WScript.ScriptName))
Set objFSO = Nothing
End Function
Function GetUserName()
'DESC: Returns user name
On Error Resume Next
Dim objWshNetwork: Set objWshNetwork = CreateObject ("WScript.Network")
GetUserName = UCase (objWshNetwork.UserName)
Set objWshNetwork = Nothing
End Function
Function GetDomainName()
'DESC: Returns domain name
On Error Resume Next
Dim objWshNetwork: Set objWshNetwork = CreateObject ("WScript.Network")
GetDomnainName = UCase (objWshNetwork.UserDomain)
Set objWshNetwork = nothing
End Function
Function GetRunTime()
'DESC: Calculates total script run time
On Error Resume Next
strStopTime = Now
Const SECONDS = "s"
Dim strSeconds: strSeconds = abs(dateDiff(SECONDS,strStartTime,strStopTime))
Dim intMinutes: intMinutes = strSeconds \ 60
Dim strHours: strHours = intMinutes \ 60
intMinutes = intMinutes mod 60
strSeconds = strSeconds mod 60
GetRunTime = strHours & ":" & _
Right("00" & intMinutes,2) & ":" & _
Right("00" & strSeconds,2)
End Function
'###################################################
LogFileX.WriteLine "Total Script RunTime: " & GetRunTime()
LogFileX.Close
'################ Reference ################
' Sending Mail Using Vbscript CDO Method
' * http://technet.microsoft.com/en-us/library/ee176585.aspx
' * The script uses anonymous authentication, this can be changed easily.
' Using WinSCP Scripting and the WinSCP.com
' * http://winscp.net/eng/docs/scripting
' * http://winscp.net/eng/docs/commandline
' Error Log Searching
' * The script accounts for a number of general errors that may be encountered during the winscp process and file transfer process.
' If the script fails and sends a successful alert, further review of the logs will need to be done;
' Error catching will need to added to the script to account for these. View the Sub WinSCPError and SubErroLog Procedures.
Sean