2013-09-27 100 views
8
$ftpServer = "ftp.example.com" 
$username ="validUser" 
$password ="myPassword" 
$localToFTPPath = "C:\ToFTP" 
$localFromFTPPath = "C:\FromFTP" 
$remotePickupDir = "/Inbox" 
$remoteDropDir = "/Outbox" 
$SSLMode = [AlexPilotti.FTPS.Client.ESSLSupportMode]::ClearText 
$ftp = new-object "AlexPilotti.FTPS.Client.FTPSClient" 
$cred = New-Object System.Net.NetworkCredential($username,$password) 
$ftp.Connect($ftpServer,$cred,$SSLMode) #Connect 
$ftp.SetCurrentDirectory($remotePickupDir) 
$ftp.GetFiles($localFromFTPPath, $false) #Get Files 

这是我从FTP服务器导入文件的脚本。
但是我不确定什么是remotePickupDir,这个脚本是否正确?PowerShell连接到FTP服务器并获取文件

回答

3

远程拾取目录路径应该是你tryng访问FTP服务器上的准确路径.. 这里是从服务器.. 您可以添加或修改SSLMode下载文件的脚本..

#ftp server 
$ftp = "ftp://example.com/" 
$user = "XX" 
$pass = "XXX" 
$SetType = "bin" 
$remotePickupDir = Get-ChildItem 'c:\test' -recurse 
$webclient = New-Object System.Net.WebClient 

$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) 
foreach($item in $remotePickupDir){ 
    $uri = New-Object System.Uri($ftp+$item.Name) 
    #$webclient.UploadFile($uri,$item.FullName) 
    $webclient.DownloadFile($uri,$item.FullName) 
} 
+10

如果$ remotepickupdir = GET-childitem C:\测试-recurse,PowerShell的将得到所有的项目在这条道路时,它会设置变量。所以它不能检索远程项目,因为此时还没有登录。你的代码看起来不对。 – BSAFH

+0

这不应被标记为接受。这并不回答这个问题! –

1

remotePickupDir将是您想要在ftp服务器上访问的文件夹。至于“这个脚本是否正确”,那么它工作吗?如果它有效,那么它是正确的。如果它不起作用,那么告诉我们你收到了什么错误信息或意外的行为,我们会更好地帮助你。

3

以下是将所有文件(通配符或文件扩展名)从FTP站点下载到本地目录的完整工作代码。设置变量值。

#FTP Server Information - SET VARIABLES 
    $ftp = "ftp://XXX.com/" 
    $user = 'UserName' 
    $pass = 'Password' 
    $folder = 'FTP_Folder' 
    $target = "C:\Folder\Folder1\" 

    #SET CREDENTIALS 
    $credentials = new-object System.Net.NetworkCredential($user, $pass) 

    function Get-FtpDir ($url,$credentials) { 
     $request = [Net.WebRequest]::Create($url) 
     $request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory 
     if ($credentials) { $request.Credentials = $credentials } 
     $response = $request.GetResponse() 
     $reader = New-Object IO.StreamReader $response.GetResponseStream() 
     while(-not $reader.EndOfStream) { 
      $reader.ReadLine() 
     } 
     #$reader.ReadToEnd() 
     $reader.Close() 
     $response.Close() 
    } 

    #SET FOLDER PATH 
    $folderPath= $ftp + "/" + $folder + "/" 

    $files = Get-FTPDir -url $folderPath -credentials $credentials 

    $files 

    $webclient = New-Object System.Net.WebClient 
    $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass) 
    $counter = 0 
    foreach ($file in ($files | where {$_ -like "*.txt"})){ 
     $source=$folderPath + $file 
     $destination = $target + $file 
     $webclient.DownloadFile($source, $target+$file) 

     #PRINT FILE NAME AND COUNTER 
     $counter++ 
     $counter 
     $source 
    } 
-1

对于通过powerShell从FTP检索文件/文件夹我写了一些功能,你甚至可以从FTP获得隐藏的东西。

例用于获取未隐藏在特定文件夹中的所有文件:

Get-FtpChildItem -ftpFolderPath "ftp://myHost.com/root/leaf/" -userName "User" -password "pw" -hidden $false -File 

例为获得所有文件夹(也隐藏)在一个特定的文件夹:

Get-FtpChildItem -ftpFolderPath"ftp://myHost.com/root/leaf/" -userName "User" -password "pw" -Directory 

你可以复制来自以下模块的功能不需要和第三个库安装: https://github.com/AstralisSomnium/PowerShell-No-Library-Just-Functions/blob/master/FTPModule.ps1

15

用于que的AlexFTPS库stion似乎已经死了(自2011年以来没有更新)。


或者,您可以尝试在没有任何外部库的情况下实现此功能。但不幸的是,.NET Framework和PowerShell都没有明确支持下载目录中的所有文件(只允许递归下载文件)。

你必须实现一个自己:

  • 列出远程目录
  • 反复调整项,下载文件(可选递归到子目录 - 再次列出这些,等)

棘手的部分是从子目录中识别文件。使用.NET框架(FtpWebRequestWebClient)无法以便携方式执行此操作。不幸的是,.NET框架不支持MLSD命令,该命令是用FTP协议检索具有文件属性的目录列表的唯一可移植方式。另请参阅Checking if object on FTP server is file or directory

的选项有:

  • 如果您知道该目录不包含任何子目录,使用ListDirectory方法(NLST FTP命令),只需下载所有的“名称”为文件。
  • 对确定文件失败并且目录成功的文件名执行操作(反之亦然)。即你可以尝试下载“名称”。
  • 你可能是幸运的,在特定情况下,可以通过文件名告诉从目录中的文件(即所有文件的扩展名,而子目录不)
  • 您使用长的目录列表(LIST命令= ListDirectoryDetails方法)并尝试解析服务器特定的列表。许多FTP服务器使用* nix风格的列表,其中您在条目的最开始处用d标识了一个目录。但是许多服务器使用不同的格式。下面的示例使用这种方法(假设* nix的格式)
function DownloadFtpDirectory($url, $credentials, $localPath) 
{ 
    $listRequest = [Net.WebRequest]::Create($url) 
    $listRequest.Method = [System.Net.WebRequestMethods+FTP]::ListDirectoryDetails 
    $listRequest.Credentials = $credentials 

    $lines = New-Object System.Collections.ArrayList 

    $listResponse = $listRequest.GetResponse() 
    $listStream = $listResponse.GetResponseStream() 
    $listReader = New-Object System.IO.StreamReader($listStream) 
    while (!$listReader.EndOfStream) 
    { 
     $line = $listReader.ReadLine() 
     $lines.Add($line) | Out-Null 
    } 
    $listReader.Dispose() 
    $listStream.Dispose() 
    $listResponse.Dispose() 

    foreach ($line in $lines) 
    { 
     $tokens = $line.Split(" ", 9, [StringSplitOptions]::RemoveEmptyEntries) 
     $name = $tokens[8] 
     $permissions = $tokens[0] 

     $localFilePath = Join-Path $localPath $name 
     $fileUrl = ($url + $name) 

     if ($permissions[0] -eq 'd') 
     { 
      if (!(Test-Path $localFilePath -PathType container)) 
      { 
       Write-Host "Creating directory $localFilePath" 
       New-Item $localFilePath -Type directory | Out-Null 
      } 

      DownloadFtpDirectory ($fileUrl + "/") $credentials $localFilePath 
     } 
     else 
     { 
      Write-Host "Downloading $fileUrl to $localFilePath" 

      $downloadRequest = [Net.WebRequest]::Create($fileUrl) 
      $downloadRequest.Method = [System.Net.WebRequestMethods+FTP]::DownloadFile 
      $downloadRequest.Credentials = $credentials 

      $downloadResponse = $downloadRequest.GetResponse() 
      $sourceStream = $downloadResponse.GetResponseStream() 
      $targetStream = [System.IO.File]::Create($localFilePath) 
      $buffer = New-Object byte[] 10240 
      while (($read = $sourceStream.Read($buffer, 0, $buffer.Length)) -gt 0) 
      { 
       $targetStream.Write($buffer, 0, $read); 
      } 
      $targetStream.Dispose() 
      $sourceStream.Dispose() 
      $downloadResponse.Dispose() 
     } 
    } 
} 

使用的功能等:

$credentials = New-Object System.Net.NetworkCredential("user", "mypassword") 
$url = "ftp://ftp.example.com/directory/to/download/" 
DownloadFtpDirectory $url $credentials "C:\target\directory" 

的代码是从我的C#示例中C# Download all files and subdirectories through FTP翻译。


如果你想避免与解析服务器特定的目录列表格式的烦恼,使用支持MLSD命令和/或解析各种LIST房源格式第三方库。理想情况下,支持从目录下载所有文件甚至递归下载。

例如与WinSCP .NET assembly你可以用一个调用Session.GetFiles下载整个目录:

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

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

$session = New-Object WinSCP.Session 

try 
{ 
    # Connect 
    $session.Open($sessionOptions) 

    # Download files 
    $session.GetFiles("/directory/to/download/*", "C:\target\directory\*").Check() 
} 
finally 
{ 
    # Disconnect, clean up 
    $session.Dispose() 
}  

内部,WinSCP赋予使用MLSD命令,如果服务器支持。如果不是,则使用LIST命令并支持数十种不同的列表格式。

默认情况下,Session.GetFiles method是递归的。

(我的WinSCP的作者)