• Interesting article, but I chose a slightly different path in handling things. I am using the portable version of WinSCP, meaning there is no installation needed. They also expose Command Line arguments, meaning that all the stuff stored in the batch file is passed along as variables in the package. So I can store the variables in a database somewhere, call them when the package loads, then pass them along to the command line options. Consider the following:(written in C#...)

    //Attaching the debugger in a 64-bit instance of SSIS will not work.

    //MessageBox.Show("Attach the Debugger", "Attach the Debugger");

    // TODO: Add your code here

    ScriptResults TaskResult;

    //jf 04132010 Created objects to hold variables set at package level

    String WinSCPPath = Dts.Variables["WinSCPPath"].Value.ToString();

    String WinSCPCom = Dts.Variables["WinSCPCom"].Value.ToString(); ;

    String WinSCPini = Dts.Variables["WinSCPini"].Value.ToString();

    String WinSCPLoggingPath = Dts.Variables["WinSCPLoggingPath"].Value.ToString();

    String WinSCPLogFileName = Dts.Variables["WinSCPLogFileName"].Value.ToString();

    String LoginName = Dts.Variables["LoginName"].Value.ToString();

    String LoginPassword = Dts.Variables["LoginPassword"].Value.ToString();

    String SiteURI = Dts.Variables["SiteURI"].Value.ToString();

    String HostKey = Dts.Variables["HostKey"].Value.ToString();

    String FileToPush = Dts.Variables["FileToPush"].Value.ToString();

    String UploadDirectory = Dts.Variables["UploadDirectory"].Value.ToString();//UploadDirectory

    //jf 04132010 Created object to hold reference for FireAgain of the FireProgress Control

    bool fireAgain = false;

    try

    {

    //jf 04132010 Attach winscp to the process within the Package

    System.Diagnostics.Process winscp = new System.Diagnostics.Process();

    Dts.Events.FireProgress("WinSCP process Created", 0, 0, 100, "WinSCP", ref fireAgain);

    //jf 04132010 Pass variables into the Process object

    //Tell the Process where to find the WinSCP object for loading

    winscp.StartInfo.FileName = String.Format("{0}{1}"

    , WinSCPPath

    , WinSCPCom);

    //Pass the location of the ini file and the logging xml file to the Process

    winscp.StartInfo.Arguments = String.Format("/log={3}{1}"

    , WinSCPPath

    , WinSCPLogFileName

    , WinSCPini

    , WinSCPLoggingPath);

    Dts.Events.FireProgress("Assigned Logging File", 10, 0, 100, "WinSCP", ref fireAgain);

    //Do not launch a new shell "cmd" window

    winscp.StartInfo.UseShellExecute = false;

    //Redirect the input and output to the Logging Component

    winscp.StartInfo.RedirectStandardInput = true;

    winscp.StartInfo.RedirectStandardOutput = true;

    //Do not show a cmd window

    winscp.StartInfo.CreateNoWindow = true;

    //Start the Process Thread

    winscp.Start();

    Dts.Events.FireProgress("WinSCP process Launched", 20, 0, 100, "WinSCP", ref fireAgain);

    //Pass configuration information to WinSCP

    winscp.StandardInput.WriteLine("option batch abort");

    winscp.StandardInput.WriteLine("option confirm off");

    //Pass Login information to WinSCP for Authentication

    winscp.StandardInput.WriteLine(String.Format("open {0}:{1}@{2} -hostkey=\"{3}\""

    , LoginName

    , LoginPassword

    , SiteURI

    , HostKey));

    Dts.Events.FireProgress("Remote SFTP Connection Established", 40, 0, 100, "WinSCP", ref fireAgain);

    //Execute WinSCP Commands

    winscp.StandardInput.WriteLine("ls");

    //--change to the needed directory

    winscp.StandardInput.WriteLine(String.Format("cd {0}", UploadDirectory));

    Dts.Events.FireProgress("Remote SFTP File Action", 60, 0, 100, "WinSCP", ref fireAgain);

    //--List the directory

    winscp.StandardInput.WriteLine("ls");

    //--push the file to the server

    winscp.StandardInput.WriteLine(String.Format("put {0}", FileToPush));

    Dts.Events.FireProgress("Process Finished", 80, 0, 100, "WinSCP", ref fireAgain);

    Dts.Events.FireProgress(String.Format("put {0}", FileToPush), 0, 0, 0, "WinSCP", ref fireAgain);

    //Close input to the file

    winscp.StandardInput.Close();

    Dts.Events.FireProgress("Remote SFTP Disconnected, WinSCP Closed", 100, 0, 100, "WinSCP", ref fireAgain);

    //wait for WinSCP to Exit

    winscp.WaitForExit();

    MessageBox.Show(winscp.StandardOutput.ReadToEnd(), "WinSCP Output");

    TaskResult = ScriptResults.Success;

    }

    catch (Exception e)

    {

    //If there is problem, fail the event and output the exception Message...

    Dts.Events.FireError(999, e.Message, "WinSCP", string.Empty, 0);

    TaskResult = ScriptResults.Failure;

    //MessageBox.Show(e.Message);

    }

    Dts.TaskResult = (int)TaskResult;

    Dts.TaskResult = (int)TaskResult;

    Notice that we can also fire events that bubble up a message within the context of the package. This means no third party installation on the server, no batch file to be overwritten and most important of all, everything is saved in a script task in the package.