使用PowerShell从FTP下载最新文件

Cor*_*068 5 ftp powershell 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 $_)) 
      }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ryl 8

这不容易FtpWebRequest.对于您的任务,您需要知道文件时间戳.

不幸的是,使用FtpWebRequest/.NET framework/PowerShell 提供的功能检索时间戳并没有真正可靠有效的方法,因为它们不支持FTP MLSD命令.该MLSD命令以标准化的机器可读格式提供远程目录的列表.RFC 3659标准化了命令和格式.

您可以使用的替代品,.NET框架支持:

  • ListDirectoryDetails方法(一个FTP LIST命令)来检索目录中所有文件的详细信息然后你处理FTP服务器特定格式的细节(*nix格式类似于ls*nix命令是最常见的,缺点是格式可能随时间而变化,对于较新的文件使用"May 8 17:48"格式,对于旧文件使用"Oct 18 2009"格式
  • GetDateTimestamp方法(FTP MDTM命令)单独检索每个文件的时间戳.优点是响应由RFC 3659标准化为YYYYMMDDHHMMSS[.sss].缺点是您必须为每个文件发送单独的请求,这可能是非常低效的.

一些参考:


或者,使用支持该MLSD命令的第三方FTP库,和/或支持解析专有列表格式.

例如,WinSCP .NET程序集支持两者.

示例代码:

# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "example.com"
    UserName = "user"
    Password = "mypassword"
}

$session = New-Object WinSCP.Session

# Connect
$session.Open($sessionOptions)

# Get list of files in the directory
$directoryInfo = $session.ListDirectory($remotePath)

# Select the most recent file
$latest =
    $directoryInfo.Files |
    Where-Object { -Not $_.IsDirectory } |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 1

# Any file at all?
if ($latest -eq $Null)
{
    Write-Host "No file found"
    exit 1
}

# Download the selected file
$sourcePath = [WinSCP.RemotePath]::EscapeFileMask($remotePath + $latest.Name)
$session.GetFiles($sourcePath, $localPath).Check()
Run Code Online (Sandbox Code Playgroud)

有关完整代码,请参阅下载最新文件(PowerShell).

(我是WinSCP的作者)

  • WinSCP是一个很棒的实用程序,非常可靠:) (2认同)

归档时间:

查看次数:

2556 次

最近记录:

7 年,2 月 前