2013-09-27 13 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 

Questo è lo script che ho ricevuto per importare i file da un server FTP.
Tuttavia, non sono sicuro di quale sia lo remotePickupDir ed è corretto questo script?PowerShell Connetti al server FTP e ottieni i file

risposta

3

Remote percorso della directory di prelievo dovrebbe essere il percorso esatto sul server FTP che si sta tryng accesso .. qui è lo script per scaricare file dal server .. è possibile aggiungere o modificare con 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

Se $ remotepickupdir = get-childitem c: \ test -recurse, PowerShell cercherà di ottenere tutti gli elementi in quel percorso quando si imposta la variabile. Quindi non può essere recuperato oggetti remoti perché a questo punto non c'è nemmeno stato un login. Il tuo codice sembra sbagliato. – BSAFH

+0

Questo non dovrebbe essere contrassegnato come accettato. Questo non risponde alla domanda! –

1

Il remotePickupDir sarebbe la cartella in cui si desidera accedere al server ftp. Per quanto riguarda "questo script è corretto", bene, funziona? Se funziona allora è corretto. Se non funziona, allora dicci quale messaggio di errore o comportamento imprevisto stai ottenendo e saremo in grado di aiutarti meglio.

3

Ecco il codice completo funzionante per scaricare tutti i file (con carattere jolly o estensione file) dal sito FTP alla directory locale. Imposta i valori delle variabili.

#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

Per il recupero di file/cartelle da FTP tramite PowerShell ho scritto alcune funzioni, è possibile ottenere anche nascosto roba da FTP.

Esempio per ottenere tutti i file che non sono nascosti in una cartella specifica:

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

Esempio per ottenere tutte le cartelle (anche nascosti) in una cartella specifica:

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

Si può solo copiare le funzioni dal seguente modulo senza necessità e installazione della 3a libreria: https://github.com/AstralisSomnium/PowerShell-No-Library-Just-Functions/blob/master/FTPModule.ps1

15

La libreria AlexFTPS utilizzata in que Stion sembra morto (non è stato aggiornato dal 2011).


In alternativa, è possibile provare a implementarlo senza alcuna libreria esterna. Ma sfortunatamente, né .NET Framework né PowerShell hanno alcun supporto esplicito per scaricare tutti i file in una directory (lasciare solo download di file ricorsivi).

è necessario implementare che da soli:

  • Lista directory remota
  • Iterate le voci, il download di file (e facoltativamente recursing in sottodirectory - messa in vendita di nuovo, ecc)

La parte difficile è identificare i file dalle sottodirectory. Non c'è modo di farlo in modo portatile con .NET framework (FtpWebRequest o WebClient). Il framework .NET purtroppo non supporta il comando MLSD, che è l'unico modo portatile per recuperare l'elenco di directory con attributi di file nel protocollo FTP. Vedi anche Checking if object on FTP server is file or directory.

Le opzioni disponibili sono:

  • Se si sa che la directory non contiene le sottodirectory, utilizzare il metodo ListDirectory (NLST comando FTP) e semplicemente scaricare tutti i "nomi" come file.
  • Esegue un'operazione su un nome file che ha esito negativo per il file e riesce per le directory (o viceversa). Cioè puoi provare a scaricare il "nome".
  • Si può essere fortunati e nel tuo caso specifico, si può dire di un file da una directory con un nome di file (ad esempio tutti i file hanno l'estensione, mentre sottodirectory NON)
  • si utilizza un lungo elenco di directory (LIST comando = ListDirectoryDetails metodo) e tenta di analizzare un elenco specifico del server. Molti server FTP utilizzano l'elenco * nix-style, in cui si identifica una directory tramite lo d all'inizio della voce. Ma molti server usano un formato diverso. L'esempio seguente utilizza questo approccio (supponendo che il formato * 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() 
     } 
    } 
} 

Utilizzare la funzione come:

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

Il codice viene tradotto da mia C# esempio nel C# Download all files and subdirectories through FTP.


Se si vuole evitare problemi con l'analisi dei formati di elenco di directory specifiche del server, utilizzare una libreria di terze parti che supporta il comando MLSD e/o l'analisi vari formati LIST quotazione. E idealmente con un supporto per il download di tutti i file da una directory o anche download ricorsivi.

Ad esempio, con WinSCP .NET assembly è possibile scaricare tutta la directory con una singola chiamata a 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() 
}  

Internamente, WinSCP usa il comando MLSD, se supportato dal server. In caso contrario, utilizza il comando LIST e supporta dozzine di formati di elenchi diversi.

Il Session.GetFiles method è ricorsivo per impostazione predefinita.

(Io sono l'autore di WinSCP)

Problemi correlati