2012-01-05 165 views
3

我是PowerShell的新手,我试图转换一个批处理文件,该文件根据名称和扩展名从ftp站点上的目录下载多个文件。尽管我发现了几个下载文件的例子,但我努力找到一个能够显示如何下载多个文件的例子。在批处理中,我可以很简单地使用ftp.exe和带有通配符的mget命令?FTP使用PowerShell下载多个文件

有人可以请指出我在正确的方向。

在此先感谢。 约翰

回答

1

在批处理我可以很简单地使用Ftp.exe和MGET命令 使用通配符?

如果您愿意,您可以在Powershell中执行相同操作。

对于更多的Powershell方式,您可以使用FTPWebRequest。看到这里:http://msdn.microsoft.com/en-us/library/ms229711.aspx。您可以构建该示例以循环下载多个文件。

但底线是,您不必将批量转换为Powershell。如果你愿意,你可以,但是你有批量的东西,尤其是在调用外部程序的时候,应该也能工作。

+0

我同意你说的话,但在此caase使用Win32 FTP.exe并没有给我足够的灵活性;考虑到PowerShell并没有给我提供功能,这有点奇怪!?! – 2012-01-05 23:34:05

1

有多种方法可以实现这一点。一种是使用System.Net.FtpWebRequest如图所示: http://www.systemcentercentral.com/BlogDetails/tabid/143/IndexID/81125/Default.aspx

或者有/ n软件NetCmdlets你可以使用:

http://www.nsoftware.com/powershell/tutorials/FTP.aspx

+0

感谢您的快速响应。我看了你的第一个例子,但问题是它假设我知道我将要下载什么。至于/ n NetCmdlets,唉,我的公司不会支付他们:-( – 2012-01-05 05:25:25

+0

啊,所以使用通配符是唯一的选择!我会看看如果我有任何其他的参考。 – ravikanth 2012-01-05 09:10:17

0

奇怪的是有在cmdlet来处理FTP没有内置。我不确定为什么PowerShell团队做出了这个决定,但这意味着您必须依靠使用.NET代码,第三方脚本/模块/管理单元或Win32程序(如FTP.exe),因为其他人已经回答。

这里是下载使用.NET代码多个文件(二进制和文本)的例子:

$files = "Firefox Setup 9.0.exe", "Firefox Setup 9.0.exe.asc" 
$ftpFolder = 'ftp://ftp.mozilla.org/pub/firefox/releases/9.0/win32/en-US' 
$outputFolder = (Resolve-Path "~\My Documents").Path 

foreach ($file in $files) { 
    try { 
     $uri = $ftpFolder + '/' + $file 
     $request = [Net.WebRequest]::Create($uri) 
     $request.Method = [Net.WebRequestMethods+Ftp]::DownloadFile 
     $responseStream = $request.GetResponse().GetResponseStream() 

     $outFile = Join-Path $outputFolder -ChildPath $file 
     $fs = New-Object System.IO.FileStream $outFile, "Create" 

     [byte[]] $buffer = New-Object byte[] 4096 

     do { 
      $count = $responseStream.Read($buffer, 0, $buffer.Length) 
      $fs.Write($buffer, 0, $count) 
     } while ($count -gt 0) 

    } catch { 
     throw "Failed to download file '{0}/{1}'. The error was {2}." -f $ftpFolder, $file, $_ 
    } finally { 
     if ($fs) { $fs.Flush(); $fs.Close() } 
     if ($responseStream) { $responseStream.Close() } 
    } 
} 
+0

我认为这会工作,但我会需要在我下载之前创建$ files列表,因为文件名每天更改。在VBscript中,我会使用类似于 “mget”和“IDY03101。”&Year()和Month()&Day()&“* .axf“,它可以下载当天的所有文件 – 2012-01-05 23:16:41

+0

@JohnE你想使用'Get-Date' cmdlet来格式化文件名'$ file ='IDY03101。{0} .axf'-f(Get- Date -Format yyyyddmm)'。 – 2012-01-06 02:04:22

+0

感谢Andy,我想我现在唯一需要做的就是找到一个导出用于$ files的文件列表的好方法。@ravikanth示例是否是一个很好的方法来执行此操作? – 2012-01-06 04:20:25

0

@Jacob。您需要:: ListDirectory方法来创建一个列表。之后,您必须使用out-file命令将其输出到文本文件中。之后,您使用get-content命令导入列表。因此,使用文本文件,您可以使用foreach循环创建一个对象集合(不要忘记跳过带'-cne'条件的最后一行)。 您可以在此循环中使用您的循环参数包含您的download-ftp函数。 了解?不知道我的解释是否好。

所以这是一个例子,从我的剧本之一:

$files = Get-FtpList $ftpSource $ftpDirectory $ftpLogin $ftpPassword | Out-File -Encoding UTF8 -FilePath list.txt 

$list = Get-Content -Encoding UTF8 -Path list.txt 

foreach ($entry in $list -cne "") 
{ 
Get-FtpFile $ftpSource $ftpDirectory $entry $target $ftpLogin $ftpPassword 
Start-Sleep -Milliseconds 10 
} 

希望它现在为你工作。

PS:Get-FtpList和Get-FtpFile是自定义函数。

0

这就是我所做的。当我需要下载一个基于模式的文件时,我动态地创建了一个命令文件,然后让其他的使用ftp做 我使用了基本的powershell命令。我不需要下载任何附加组件 我首先检查是否存在必需的文件数量。如果他们这样做,我第二次使用Mget调用FTP。 我这运行从Windows 2008服务器连接到Windows XP的远程服务器

  function make_ftp_command_file($p_file_pattern,$mget_flag) 
       { 
       # This function dynamically prepares the FTP file 
       # The file needs to be prepared daily because the pattern changes daily 
       # Powershell default encoding is Unicode 
       # Unicode command files are not compatible with FTP so we need to make sure we create an ASCII File 

       write-output "USER" | out-file -filepath C:\fc.txt -encoding ASCII 
       write-output "ftpusername" | out-file -filepath C:\fc.txt -encoding ASCII -Append 
       write-output "password" | out-file -filepath C:\fc.txt -encoding ASCII -Append 
       write-output "ASCII" | out-file -filepath C:\fc.txt -encoding ASCII -Append 
       If($mget_flag -eq "Y") 
       { 
        write-output "prompt" | out-file -filepath C:\fc.txt -encoding ASCII -Append 
        write-output "mget $p_file_pattern" | out-file -filepath C:\fc.txt -encoding ASCII -Append 
       } 
       else 
       { 
        write-output "ls $p_file_pattern" | out-file -filepath C:\fc.txt -encoding ASCII -Append 
       }   

       write-output quit | out-file -filepath C:\fc.txt -encoding ASCII -Append 

      } 

      ########################### Init Section ############################### 
      $yesterday = (get-date).AddDays(-1) 
      $yesterday_fmt = date $yesterday -format "yyyyMMdd" 
      $file_pattern = "BRAE_GE_*" + $yesterday_fmt + "*.csv" 
      $file_log = $yesterday_fmt + ".log" 

      echo $file_pattern 
      echo $file_log 



      ############################## Main Section ############################ 
      # Change location to folder where the files need to be downloaded 
      cd c:\remotefiles 

      # Dynamically create the FTP Command to get a list of files from the Remote Servers 
      echo "Call function that creates a FTP Command " 
      make_ftp_command_file $file_pattern N 


      #echo "Connect to remote site via FTP" 
      # Connect to Remote Server and get file listing 
      ftp -n -v -s:C:\Clover\scripts\fc.txt 10.129.120.31 > C:\logs\$file_log 

      $matches=select-string -pattern "BRAE_GE_[A-Z][A-Z]*" C:\logs\$file_log 

      # Check if the required number of Files available for download 
      if ($matches.count -eq 36) 
      { 
       # Create the ftp command file 
        # this time the command file has an mget rather than an ls 
       make_ftp_command_file $file_pattern Y 
        # Change directory if not done so 
       cd c:\remotefiles 
        # Invoke Ftp with newly created command file 
       ftp -n -v -s:C:\Clover\scripts\fc.txt 10.129.120.31 > C:\logs\$file_log 
      } 
      else 
      { 
       echo "Full set of Files not available" 
      } 
0

这不是PowerShell中的特定。但我已经尝试了很多其他的解决方案,并且到目前为止

http://ncftp.com/客户端运行最好。它与ncftpls.exe列出远程文件和ncftpget.exe获取文件。在使用它们时Start-Process -Wait

0

的文件列表可以在一个变量来构造,并用常规的FTP命令中使用....

$FileList="file1_$cycledate.csv 
file2_$cycledate.csv 
file3_$cycledate.csv 
file4_$cycledate.csv" 

"open $FTPServer 
    user $FTPUser $FTPPassword 
ascii 
cd report 
" + 
($filelist.split(' ') | %{ "mget $_" }) | ftp -i -n