You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用WinSCP .NET组件从FTP所有目录下载1天内文件至本地单目录

问题分析与解决方案

核心问题定位

原代码的几个致命错误导致无法传输文件:

  • 错误读取本地目录的文件,完全搞反了操作对象(应该读取远程FTP服务器的文件)
  • foreach循环里误用集合$files而非单个文件对象$file
  • Session.GetFiles的参数逻辑不符合WinSCP API要求
  • 错误处理代码的语法位置不正确

修正后的完整代码

# 加载WinSCP .NET组件
Add-Type -Path "WinSCPnet.dll"

# 配置会话参数
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol              = [WinSCP.Protocol]::ftp
    HostName              = "ftp site"
    UserName              = "UserName"
    Password              = "Password"
    # FTP协议不需要SSH密钥,注释掉冗余配置
    # SshHostKeyFingerprint = "stuff"
}

$sessionOptions.AddRawSettings("FSProtocol", "2")

$session = New-Object WinSCP.Session
$session.SessionLogPath = $log
try {
    # 连接FTP服务器
    $session.Open($sessionOptions)

    # 配置传输选项
    $transferOptions = New-Object WinSCP.TransferOptions -Property @{
        TransferMode = [WinSCP.TransferMode]::Ascii
        # 禁用自动创建目录,确保所有文件都下载到本地单个目录
        CreateDirectories = $False
    }

    $localTargetDir = "LocalFilePath\"
    $cutoffTime = (Get-Date).AddDays(-1)

    # 递归遍历远程所有文件,筛选1天内更新的文件
    $remoteFiles = $session.EnumerateRemoteFiles("/", "*", [WinSCP.EnumerationOptions]::AllDirectories) | 
        Where-Object { $_.LastWriteTime -gt $cutoffTime }

    # 逐个传输符合条件的文件
    foreach ($file in $remoteFiles) {
        # 提取远程文件名,直接保存到本地目标目录(不保留远程目录结构)
        $localSavePath = Join-Path $localTargetDir (Split-Path $file.FullName -Leaf)
        $transferResult = $session.GetFiles($file.FullName, $localSavePath, $False, $transferOptions)
        # 检查传输是否出错
        $transferResult.Check()
    }
}
catch {
    Write-Host "错误: $($_.Exception.Message)"
    exit 1
}
finally {
    # 释放会话资源
    $session.Dispose()
}
exit 0

关键修正点说明

  • 正确获取远程文件:用$session.EnumerateRemoteFiles替代本地的Get-ChildItem,递归遍历远程所有目录的文件
  • 时间筛选逻辑:通过Where-Object过滤出最后修改时间在1天内的文件
  • 单个目录保存:
    • 设置CreateDirectories = $False,避免自动创建远程目录结构
    • 用Split-Path提取纯文件名,结合本地目标路径,确保所有文件都存到同一个目录下
  • 循环逻辑修复:foreach循环中使用单个文件对象$file,正确调用GetFiles方法
  • 语法修正:把catch块移到try块之后,符合PowerShell语法规范
  • 冗余配置清理:移除FTP不需要的SSH密钥配置

额外提示

  • 可以提前检查本地目标目录是否存在,不存在则自动创建:
    if (-not (Test-Path $localTargetDir)) {
        New-Item -ItemType Directory -Path $localTargetDir | Out-Null
    }
    
  • 如果传输二进制文件(如图片、压缩包),把TransferMode改为[WinSCP.TransferMode]::Binary
  • 查看SessionLogPath指定的日志文件,可以排查传输过程中的细节问题

内容的提问来源于stack exchange,提问作者JM1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:20:23