如何设计SSIS包通过WinSCP实现SFTP内跨文件夹迁移文件
基于WinSCP实现SFTP文件移动的SSIS包设计方案
整体执行逻辑为:前置环境准备 → 配置SSIS全局变量 → 配置WinSCP连接参数 → 执行文件移动逻辑 → 异常/日志处理。
问题1:SSIS包中WinSCP的连接配置实现
- 前置环境准备:将WinSCP的核心执行文件
WinSCP.com、WinSCP.exe放到服务器无空格的固定路径下,例如C:\Tools\WinSCP\,避免路径识别错误。 - SSIS变量配置:在SSIS包的变量面板新增以下变量,敏感信息需开启敏感属性避免明文泄露:
SftpHost:字符串类型,存储SFTP服务器地址SftpPort:整型,默认值22,存储SFTP服务端口SftpUsername:字符串类型,存储SFTP登录账号SftpPassword:字符串类型,开启敏感属性,存储SFTP登录密码SourceSftpPath:字符串类型,存储SFTP源文件夹路径,例如/upload/to_process/TargetSftpPath:字符串类型,存储SFTP目标文件夹路径,例如/archive/processed/WinSCPExePath:字符串类型,存储WinSCP.com的本地完整路径
- 主机密钥预配置:先使用WinSCP GUI工具手动连接一次目标SFTP服务器,确认并保存主机密钥指纹,后续脚本配置该指纹可避免首次执行弹出确认框导致SSIS任务卡住。
问题2:批处理/自定义代码实现逻辑
提供两种可落地的实现方案,可根据场景复杂度选择:
方案1:批处理+执行进程任务(轻量场景首选)
无需编写代码,配置简单:
- 新建纯文本格式的WinSCP命令脚本
move_sftp_file.txt,内容模板如下:
# 连接SFTP服务器,生产环境请将-hostkey的值替换为实际保存的主机密钥指纹 open sftp://%SFTP_USER%:%SFTP_PWD%@%SFTP_HOST%:%SFTP_PORT% -hostkey="*" # 移动源路径下所有文件到目标路径 mv %SOURCE_PATH%* %TARGET_PATH% # 退出会话 exit
- 在SSIS包中新增「执行进程任务」,按如下配置:
- 可执行文件:选择变量
WinSCPExePath对应的路径 - 参数:填写
/script="C:\你的脚本存储路径\move_sftp_file.txt",也可通过SSIS表达式动态拼接参数,直接内联命令无需额外脚本文件:/command "open sftp://@[User::SftpUsername]:@[User::SftpPassword]@@[User::SftpHost]:@[User::SftpPort] -hostkey=""你的主机密钥指纹""" "mv @[User::SourceSftpPath]* @[User::TargetSftpPath]" "exit"
- 可执行文件:选择变量
方案2:C#脚本任务(复杂场景首选)
适合需要加自定义过滤、异常捕获、日志记录的场景:
- 在SSIS包中新增「脚本任务」,将上述所有自定义变量添加到任务的
ReadOnlyVariables列表中,引用WinSCPnet.dll程序集。 - 核心代码示例如下:
using WinSCP; using System; public void Main() { // 读取SSIS变量,敏感变量需用GetSensitiveValue方法读取 string host = Dts.Variables["User::SftpHost"].Value.ToString(); int port = (int)Dts.Variables["User::SftpPort"].Value; string username = Dts.Variables["User::SftpUsername"].Value.ToString(); string password = Dts.Variables["User::SftpPassword"].GetSensitiveValue().ToString(); string sourcePath = Dts.Variables["User::SourceSftpPath"].Value.ToString(); string targetPath = Dts.Variables["User::TargetSftpPath"].Value.ToString(); SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Sftp, HostName = host, PortNumber = port, UserName = username, Password = password, // 替换为实际的主机密钥指纹 SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" }; try { using (Session session = new Session()) { session.Open(sessionOptions); // 移动文件,可自定义匹配规则实现指定文件移动 session.MoveFile(sourcePath + "*", targetPath); } Dts.TaskResult = (int)ScriptResults.Success; } catch (Exception ex) { // 可自定义异常日志记录逻辑 Dts.Events.FireError(0, "SFTP移动文件失败", ex.Message, string.Empty, 0); Dts.TaskResult = (int)ScriptResults.Failure; } }
额外注意事项
- 运行SSIS包的服务账号需要拥有WinSCP路径的执行权限、脚本存储路径的读写权限。
- 如果需要过滤特定后缀的文件,修改
mv命令或MoveFile方法的匹配规则即可,例如sourcePath + "*.csv"仅移动csv文件。 - 建议在任务前后添加日志记录节点,记录执行时间、移动文件数量等信息,方便后续排查问题。
内容的提问来源于stack exchange,提问作者siddhesh
相关产品推荐
相关产品推荐

