我正在开发一个PowerShell脚本,它将从FTP站点提取文件。文件每小时上传到FTP站点,所以我需要下载最新的文件。我目前的代码下载了今天的所有文件而不是一个文件。如何使其仅下载最新文件?
以下是我目前使用的代码
$ftpPath = 'ftp://***.***.*.*'
$ftpUser = '******'
$ftpPass = '******'
$localPath = 'C:\Temp'
$Date = get-date -Format "ddMMyyyy"
$Files = 'File1', 'File2'
function Get-FtpDir ($url, $credentials)
{
$request = [Net.FtpWebRequest]::Create($url)
if ($credentials) { $request.Credentials = $credentials }
$request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory
(New-Object IO.StreamReader $request.GetResponse().GetResponseStream()) -split "`r`n"
}
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($ftpUser,$ftpPass)
$webclient.BaseAddress = $ftpPath
Foreach ( $item in $Files )
{
Get-FTPDir $ftpPath $webclient.Credentials |
? { $_ -Like $item+$Date+'*' } |
% {
$webClient.DownloadFile($_, (Join-Path $localPath $_))
}
}
答案 0 :(得分:8)
FtpWebRequest
并不容易。对于您的任务,您需要知道文件时间戳。
遗憾的是,由于FtpWebRequest
/ .NET Framework / PowerShell提供的功能不支持FTP MLSD
命令,因此没有真正可靠有效的方法来检索时间戳。 MLSD
命令以标准化的机器可读格式提供远程目录的列表。命令和格式由RFC 3659标准化。
.NET框架支持的替代方案:
ListDirectoryDetails
方法(FTP LIST
命令)检索目录中所有文件的详细信息,然后处理FTP服务器特定格式的详细信息(* nix格式类似于{{1} } * nix命令是最常见的,缺点是格式可能会随着时间而改变,对于较新的文件" 5月8日17:48"格式用于旧文件" 2009年10月18日&# 34;使用格式)ls
方法(FTP GetDateTimestamp
命令)单独检索每个文件的时间戳。优点是响应由RFC 3659标准化为MDTM
。缺点是你必须为每个文件发送一个单独的请求,这可能是非常低效的。一些参考文献:
或者,使用支持YYYYMMDDHHMMSS[.sss]
命令的第三方FTP库,和/或支持解析专有列表格式。
例如WinSCP .NET assembly支持两者。
示例代码:
MLSD
有关完整代码,请参阅Downloading the most recent file (PowerShell)。
(我是WinSCP的作者)
答案 1 :(得分:0)
我尝试了这个,但出现错误:
Error: Exception calling "ListDirectory" with "1" argument(s): "Error listing directory '/path/'.
Could not retrieve directory listing
Can't open data connection for transfer of "/path/"
我在Internet上阅读了很多有关此问题的内容,但是找不到一个看起来很简单的解决方案,而且我不是网络设置向导。所以我选择了另一种方法。在本例中,我要为其自动下载文件的文件名具有指定的日期:backup_2018_08_03_020003_1048387.bak
因此,我们可以在命令行ftp会话中使用mget *2018_08_03*
来获取文件。
我们的备份过程每天早上01:00 AM运行,因此我们每天都有一个可以提取的备份。
当然,有一个脚本可以根据备份文件的时间戳来获取最新的备份文件,这是更好,更好的选择,以防万一最新备份或备份文件命名格式出了问题。该脚本只是为了内部开发目的而获取备份的脚本,因此,如果损坏,则没什么大不了的。稍后,我将进行调查,并检查是否可以提供更清洁的解决方案。
我制作了一个批处理脚本,该脚本只使用普通的ftp命令提示符脚本来要求提供今天的备份文件。
正确设置今天的日期格式很重要。它必须正确匹配文件名中日期的格式。
如果要使用脚本,则应使用自己的信息替换变量。您还应该对运行它的目录具有写访问权。
这是我制作的脚本:
@Echo Off
Set _FTPServerName=xxx.xxx.xx.xxx
Set _UserName=Username
Set _Password=Password
Set _LocalFolder=C:\Temp
Set _RemoteFolder="/path/"
Set _Filename=*%date:~-4,4%_%date:~-7,2%_%date:~-10,2%*
Set _ScriptFile=ftptempscript
:: Create script
>"%_ScriptFile%" Echo open %_FTPServerName%
>>"%_ScriptFile%" Echo %_UserName%
>>"%_ScriptFile%" Echo %_Password%
>>"%_ScriptFile%" Echo lcd %_LocalFolder%
>>"%_ScriptFile%" Echo cd %_RemoteFolder%
>>"%_ScriptFile%" Echo binary
>>"%_ScriptFile%" Echo mget -i %_Filename%
>>"%_ScriptFile%" Echo quit
:: Run script
ftp -s:"%_ScriptFile%"
del "%_ScriptFile%"