使用 SSIS 包下载 SFTP 文件

问题描述

我想创建一个需要自动下载文件并将其放置在我们本地的 SSIS 包。

注意:仅使用流程执行任务和批处理脚本文件

解决方法

在新的 SSIS 项目中,创建一个新包。导航到“参数”选项卡,我们将在其中创建一些运行时值,这些值将使 DownloadSFTP 包更具可重用性。 enter image description here

  • pFilename:这是要从服务器下载的文件名。笔记 我们也可以使用通配符(假设它们受支持 目标服务器)——在上面的例子中,我们将下载所有文件 以“.TXT”结尾。

  • pServerHostKey:用于满足构建的安全机制 进入 WinSCP 进程。默认情况下,WinSCP 会提示用户 连接到 SFTP 时验证主机密钥并将其添加到本地缓存 服务器第一次。因为这将自动完成, 非交互式过程,获得该提示将导致错误 我们的脚本。为了防止这种情况,脚本被构建为提供服务器 主机密钥以避免错误,并且还有额外的好处 确保我们实际连接到正确的 SFTP 服务器。这 WinSCP 文档站点上的简短文章描述了如何 检索目标服务器的服务器主机密钥。

  • pServerUserPassword:这被标记为敏感以屏蔽 密码。作为脚本逻辑的一部分,此密码将是 在发送到服务器之前解密。

在控制流中创建一个新的脚本任务,并将上面显示的所有 7 个参数添加到 ReadOnlyVariables 列表中。

enter image description here

使用 Main() 函数(在新脚本任务中自动创建),创建 Process 对象并配置一些运行时选项,包括可执行文件的名称和下载目录。

public void Main()
        {
            // Create a new Process object to execute WinSCP
            Process winscp = new Process();
            // Set the executable path and download directory
            winscp.StartInfo.FileName = Dts.Variables["$Package::pWinSCPLocation"].Value.ToString();
            winscp.StartInfo.WorkingDirectory = Dts.Variables["$Package::pDownloadDir"].Value.ToString();
            
            // Set static execution options (these should not need to change)
            winscp.StartInfo.UseShellExecute = false;
            winscp.StartInfo.RedirectStandardInput = true;
            winscp.StartInfo.RedirectStandardOutput = true;
            winscp.StartInfo.CreateNoWindow = true;
            // Set session options
            string sessionOptionString = "option batch abort" + System.Environment.NewLine + "option confirm off";

下一步是创建将建立连接并下载文件的输入字符串。在此代码段的底部,有 3 个变量将捕获输出消息、错误消息和返回值,所有这些都将用于记录运行时信息。

// Build the connect string (<user>:<password>@<hostname>)
            string connectString = @"open " + Dts.Variables["$Package::pServerUserName"].Value.ToString()
                                            + ":"
                                            + Dts.Variables["$Package::pServerUserPassword"].GetSensitiveValue().ToString()
                                            + "@"
                                            + Dts.Variables["$Package::pServerName"].Value.ToString();
            // Supplying the host key adds an extra level of security,and avoids getting the prompt to trust the server.
            string hostKeyString = Dts.Variables["$Package::pServerHostKey"].Value.ToString();
            // If hostkey was specified,include it
            if (hostKeyString != null && hostKeyString.Length > 0)
                connectString += " -hostkey=\"" + hostKeyString + "\"";
            // Build the get command string
            string getString = "get " + Dts.Variables["$Package::pFilename"].Value.ToString();
            // Create output variables to capture execution info
            string outStr = "",errStr = "";
            int returnVal = 1;

配置所有选项后,是时候调用 WinSCP.com。下面的 try/catch 块将尝试连接并从服务器下载指定的文件。

// This try/catch block will capture catastrophic failures (such as specifying the wrong path to winscp).
        try
        {
            winscp.Start();
            winscp.StandardInput.WriteLine(sessionOptionString);
            winscp.StandardInput.WriteLine(connectString);
            winscp.StandardInput.WriteLine(getString);
            winscp.StandardInput.Close();
            winscp.WaitForExit();
    // Set the outStr to the output value,obfuscating the password
            outStr = winscp.StandardOutput.ReadToEnd().Replace(":" + Dts.Variables["$Package::pServerUserPassword"].GetSensitiveValue().ToString() + "@",":*******@");
            returnVal = winscp.ExitCode;
        }
        catch (Exception ex)
        {
            errStr = "An error occurred when attempting to execute winscp.com: " + ex.Message.Replace("'","\"").Replace("--"," - ");
        }

该包已准备好执行。假设一切都配置正确,在系统上运行包应该正好下载两个文本文件(记住,我们使用通配符“*.txt”来获取所有文本文件)。