编写PowerShell脚本:从SFTP服务器复制指定文件的最新版本
PowerShell SFTP 文件复制问题解决方案
问题分析
你当前的脚本存在两个核心问题:
- 第一个循环用无边界的
-match匹配文件名,会误匹配包含目标基础名的无关文件(比如File12.xxx会被当成File1的匹配项),且未筛选每个目标文件的最新版本,会复制所有匹配文件而非最新版。 - 第二个代码逻辑仅取整个SFTP目录的最新文件,完全忽略了目标文件名的限制,导致复制当日上传的随机文件。
同时还需要补充当月最后一个工作日触发的判断逻辑,以及确保单向复制不修改源文件(Get-SFTPItem本身只做复制,不会改动SFTP上的源文件,满足要求)。
完整解决方案代码
1. 当月最后一个工作日判断函数
function Get-LastWorkdayOfMonth { $today = Get-Date $lastDayOfMonth = [DateTime]::DaysInMonth($today.Year, $today.Month) $currentDate = Get-Date -Day $lastDayOfMonth # 倒推至最近的工作日(排除周六周日) while ($currentDate.DayOfWeek -in [DayOfWeek]::Saturday, [DayOfWeek]::Sunday) { $currentDate = $currentDate.AddDays(-1) } return $currentDate.Date } # 检查今日是否为当月最后一个工作日,不是则直接退出 $lastWorkday = Get-LastWorkdayOfMonth if ((Get-Date).Date -ne $lastWorkday) { Write-Output "今日非当月最后一个工作日,脚本终止。" exit }
2. SFTP目标文件筛选与复制逻辑
# 配置参数 $file1BaseName = "File1" $file2BaseName = "file2" $sftpSourcePath = "/path/to/dir/" $localDestination = "\\your-server\audit-share" $SessionID = "你的SFTP会话ID" # 需提前建立SFTP会话 # 获取SFTP目录下所有文件 $allSftpFiles = Get-SFTPChildItem -SessionId $SessionID -Path $sftpSourcePath # 筛选并获取File1的最新版本(按扩展名数字排序) $latestFile1 = $allSftpFiles | Where-Object { # 正则精确匹配:基础名.纯数字扩展名,避免部分匹配 $_.Name -match "^$([regex]::Escape($file1BaseName))\.\d+$" } | Sort-Object { # 提取扩展名的数字部分转为整数,确保数值排序(而非字符串排序) [int]$_.Name.Split('.')[-1] } -Descending | Select-Object -First 1 # 筛选并获取file2的最新版本 $latestFile2 = $allSftpFiles | Where-Object { $_.Name -match "^$([regex]::Escape($file2BaseName))\.\d+$" } | Sort-Object { [int]$_.Name.Split('.')[-1] } -Descending | Select-Object -First 1 # 执行复制操作 foreach ($target in @($latestFile1, $latestFile2)) { if ($target) { # Get-SFTPItem仅复制文件,不会修改SFTP源文件,满足单向复制要求 Get-SFTPItem -Path $target.FullName -Destination $localDestination -SessionId $SessionID Write-Output "已复制文件: $($target.Name) 到目标路径: $localDestination" } else { Write-Warning "未找到有效版本的 $($target.BaseName) 文件" } }
关键优化点
- 精确文件名匹配:用正则表达式的
^和$边界限制,确保只匹配基础名.数字格式的文件,避免误匹配。 - 正确的版本排序:将扩展名的数字部分转为整数后排序,避免字符串排序导致的逻辑错误(比如
100不会被排在9前面)。 - 触发条件控制:通过函数精准判断当月最后一个工作日,确保脚本仅在指定日期运行。
- 安全复制:
Get-SFTPItem本身是只读复制操作,不会修改SFTP服务器上的源文件,完全符合单向复制要求。
内容的提问来源于stack exchange,提问作者kevinm3
相关产品推荐
相关产品推荐

