设计范围:使用 PowerShell 和 WinSCP .NET 程序集通过文件时间戳识别要下载的文件,自动完成夜间下载。所连接的 FTP 服务器是 IIS,因此其当前配置不支持所有命令(如 MLSD),而且我认为它们不会在收到请求时做出更改。
问题:包含 1 位或 2 位数字月份的文件返回的字符串长度不同,我不确定如何解决这个问题。我的代码现在可以使用,但 10 月份将停止使用。
例如,三月显示 3/dd/yyyy 而不是 03/dd/yyyy
其他注意事项:起初我尝试使用 WinSCP.com 编写脚本,但找不到正确指定日期的方法。
例如,您可以指定*.zip>=1D
或*.zip<=1D
,但*.zip=1D
或*.zip==1D
目前不受最新版本的 WinSCP 支持。
代码:
$yesterday = [DateTime]::Today.AddDays(-1).ToString("M/dd/yyyy")
# OR I have to use ToString("MM/dd/yyyy") for months 10-12,
# but I need both formats to work.
#delete the temporary file
del .\FTPfiles.txt
# Load WinSCP .NET assembly
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Ftp
HostName = "server.com"
UserName = "joe"
Password = "smith"
}
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
$directory = $session.ListDirectory("/Folder")
foreach ($fileInfo in $directory.Files)
{
Write-Output ("{1} {0}" -f
$fileInfo.Name, $fileInfo.LastWriteTime) >> FTPfiles.txt
}
$fileList = get-content .\FTPfiles.txt | findstr $yesterday
$stripped = $fileList -creplace '^.*Z12', 'Z12'
# Download files
$remotePath = "/Folder/"
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
$lines = $stripped
foreach ($line in $lines)
{
Write-Host ("Downloading {0} ..." -f $line)
$session.GetFiles($remotePath+$line, "C:\Downloads\").Check()
}
}
catch [Exception]
{
Write-Host ("Error: {0}" -f $_.Exception.Message)
exit 1
}
finally
{
# Disconnect, clean up
$session.Dispose()
}
将$fileInfo in $directory.Files
上次写入时间和文件名写入FTPfiles.txt
FTP 服务器上指定文件夹中的所有文件。然后读取此文本文件,并进一步缩减为仅写入时间为昨天的文件,目前该方法仅适用于一年中的 9 个月,因为日期格式使用 1 位数字表示月份,而不是 2 位数字。
接下来,读取该文件并删除文件名前的日期,以便使用文件名进行循环下载。转换如下所示:
FROM:
3/14/2017 2:04:00 AM Z1234_20170314050001_1.zip
3/14/2017 3:04:00 AM Z1234_20170315060002_1.zip
3/14/2017 4:04:00 AM Z1234_20170316070001_1.zip
3/14/2017 5:04:00 AM Z1234_20170317080001_1.zip
TO:
Z1234_20170314050001_1.zip
Z1234_20170315060002_1.zip
Z1234_20170316070001_1.zip
Z1234_20170317080001_1.zip
然后脚本使用这些文件名从前一天下载所需的文件。
答案1
尝试此功能并在参数中传递指定的日期范围StartDate
并EndDate
Function Download-Files
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)][Object]$Session,
[Parameter(Mandatory=$true)][String]$RemotePath,
[Parameter(Mandatory=$true)][String]$LocalPath,
[Parameter(Mandatory=$false)][String]$StartDate,
[Parameter(Mandatory=$false)][String]$EndDate
)
If (-Not (Test-Path -Path $LocalPath -PathType Container)) {
New-Item -Path $LocalPath -ItemType Directory
}
Get-WinSCPChildItem -WinSCPSession $Session -Path $RemotePath | ForEach-Object {
If (-not($_.IsThisDirectory) -and -not($_.IsParentDirectory) -and $_.IsDirectory) {
Download-Files -Session $Session -RemotePath "$RemotePath\$($_.Name)\" -LocalPath "$LocalPath\$($_.Name)\" -StartDate $StartDate -EndDate $EndDate
}
If (-not($_.IsDirectory)) {
If ($_.LastWriteTime -ge $StartDate -and $_.LastWriteTime -le $EndDate) {
Receive-WinSCPItem -WinSCPSession $Session -Path "$RemotePath\$($_.Name)" -Destination $LocalPath
}
}
}
}
您可以从下载完整的代码示例如何使用 WinSCP 下载 PowerShell 中的最近文件
答案2
您可以使用today
和yesterday
关键字为了单个 WinSCP 文件掩码中的上限和下限时间约束:
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.FileMask = "*>=yesterday<today"
$session.GetFiles("/Folder/*", "C:\Downloads\", $False, $transferOptions).Check()
这需要 WinSCP 5.15 及更新版本。
在旧版本的 WinSCP 中,您可以在 PowerShell 代码中生成时间戳,例如:
*>=2017-03-15<2017-03-16
(午夜时间是隐含的,这也是为什么*=2017-03-15
不是你想要的;也是它没有被实现的原因,因为它没有任何用处)
在 PowerShell 中,你可以像这样实现它:
$yesterday = (Get-Date).AddDays(-1)
$yesterday_timestamp = $yesterday.ToString("yyyy-MM-dd")
$today = Get-Date
$today_timestamp = $today.ToString("yyyy-MM-dd")
$transferOptions = New-Object WinSCP.TransferOptions
$file_mask = "*>=$yesterday_timestamp<$today_timestamp"
$transferOptions.FileMask = $file_mask
$session.GetFiles("/Folder/*", "C:\Downloads\", $False, $transferOptions).Check()
看WinSCP 文章:有关在 PowerShell 中格式化时间戳。
虽然你也可以使用WinSCP%TIMESTAMP%
语法为了更简单的实现:
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.FileMask = "*>=%TIMESTAMP-1D#yyyy-mm-dd%<%TIMESTAMP#yyyy-mm-dd%"
$session.GetFiles("/Folder/*", "C:\Downloads\", $False, $transferOptions).Check()
请参阅 WinSCP 文章下载最新文件。