$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
C'est le script que j'ai obtenu pour importer des fichiers à partir d'un serveur FTP.
Cependant, je ne sais pas quelle est la remotePickupDir
et ce script est-il correct?
Le chemin du répertoire de sélection à distance doit être le chemin exact sur le serveur FTP auquel vous souhaitez accéder ... Voici le script pour télécharger des fichiers du serveur ... vous pouvez ajouter ou modifier des informations avec 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)
}
La bibliothèque AlexFTPS utilisée dans la question semble être morte (n'a pas été mise à jour depuis 2011).
Alternativement, vous pouvez essayer d'implémenter cela sans aucune bibliothèque externe. Mais malheureusement, ni le .NET Framework ni PowerShell ne prennent en charge explicitement le téléchargement de tous les fichiers d’un répertoire (laissez uniquement les téléchargements de fichiers récursifs).
Vous devez implémenter cela vous-même:
Une partie délicate consiste à identifier les fichiers de sous-répertoires. Il n’ya aucun moyen de le faire de manière portable avec le framework .NET (FtpWebRequest
ou WebClient
). Malheureusement, le framework .NET ne prend pas en charge la commande MLSD
, qui est le seul moyen portable d’extraire une liste de répertoires avec des attributs de fichier dans le protocole FTP. Voir aussi Vérification si l'objet sur le serveur FTP est un fichier ou un répertoire .
Vos options sont:
ListDirectory
(commande NLST
FTP) et téléchargez simplement tous les "noms" sous forme de fichiers.LIST
command = ListDirectoryDetails
) et essayez d'analyser une liste spécifique au serveur. De nombreux serveurs FTP utilisent une liste de style * nix, dans laquelle vous identifiez un répertoire par la variable d
tout au début de l'entrée. Mais de nombreux serveurs utilisent un format différent. L'exemple suivant utilise cette approche (en supposant le format * 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()
}
}
}
Utilisez la fonction comme:
$credentials = New-Object System.Net.NetworkCredential("user", "mypassword")
$url = "ftp://ftp.example.com/directory/to/download/"
DownloadFtpDirectory $url $credentials "C:\target\directory"
Le code est traduit de mon exemple C # dans C # Téléchargez tous les fichiers et sous-répertoires via FTP .
Si vous souhaitez éviter les problèmes d’analyse des formats de liste de répertoires spécifiques au serveur, utilisez une bibliothèque tierce qui prend en charge la commande MLSD
et/ou en analysant divers formats de liste LIST
. Et idéalement avec un support pour télécharger tous les fichiers depuis un répertoire ou même des téléchargements récursifs.
Par exemple, avec WinSCP .NET Assembly vous pouvez télécharger le répertoire complet en un seul appel à 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()
}
En interne, WinSCP utilise la commande MLSD
, si elle est prise en charge par le serveur. Sinon, il utilise la commande LIST
et prend en charge des dizaines de formats de liste différents.
La méthode Session.GetFiles
est récursive par défaut.
(Je suis l'auteur de WinSCP)
Voici le code de travail complet pour télécharger tous les fichiers (avec caractère générique ou extension de fichier) du site FTP vers le répertoire local. Définissez les valeurs des variables.
#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
}
La remotePickupDir
serait le dossier que vous voulez aller sur le serveur ftp. En ce qui concerne "ce script est-il correct", eh bien, ça marche? Si cela fonctionne, alors c'est correct. Si cela ne fonctionne pas, dites-nous quel message d'erreur ou quel comportement inattendu vous avez et nous pourrons mieux vous aider.