使用PowerShell从FTP下载最新文件

时间:2016-11-28 13:39:21

标签: powershell ftp ftpwebrequest

我正在开发一个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 $_)) 
      }
}

2 个答案:

答案 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%"