Comment télécharger des fichiers via FTP avec PowerShell
Le protocole de transfert de fichiers (FTP) est un service commun utilisé pour transférer des fichiers entre les clients et les serveurs. Il est souvent utile d’automatiser ces transferts de fichiers, et les scripts PowerShell peuvent être utiles pour accélérer ce processus.
Sommaire
Comment utiliser FTP dans PowerShell
Il existe plusieurs façons d’effectuer des transferts FTP dans PowerShell.
Le plus simple est d’utiliser WebClient.UploadFile
. PowerShell est un langage de script orienté objet, et vous avez un accès complet à .NET
bibliothèques standard avec New-Object
. Avec cela, vous pouvez créer un nouveau WebClient
définissez ses informations d’identification et chargez un fichier.
$client = New-Object System.Net.WebClient $client.Credentials = New-Object System.Net.NetworkCredential("username", "password") $client.UploadFile("ftp://example.com/path/archive.zip", "C:archive.zip")
Cela fonctionnera bien, mais ne pourra pas gérer les requêtes cryptées TLS/SSL, ni effectuer de transferts FTP « actifs ». Utilisant FtpWebRequest
couvert ci-dessous, résoudra ce problème.
Cependant, il n’est pas recommandé de stocker votre nom d’utilisateur et votre mot de passe dans un script, surtout si ce script est validé dans un référentiel Git partagé. Vous pouvez à la place définir des variables d’environnement comme FtpUsername
et y accéder dans le script.
function uploadToFTPServer($remote, $local) { $client = New-Object System.Net.WebClient $client.Credentials = New-Object System.Net.NetworkCredential($Env:FtpUsername, $Env:FtpPassword) $client.UploadFile($remote, $local) } uploadToFTPServer "ftp://example.com/path/archive.zip", "C:archive.zip"
En faire une fonction vous permettra également d’effectuer facilement plusieurs transferts en appelant la fonction avec différents paramètres.
Transferts FTP avancés avec PowerShell
Si vous avez besoin de plus de contrôle, vous devez utiliser FtpWebRequest
. Cela prendra en charge les transferts TLS et vous permettra également de désactiver le mode passif. La façon la plus simple de l’utiliser est d’ouvrir un flux de fichiers et de le copier dans le flux FTP.
function uploadToFTPServer($remote, $local) { $request = [System.Net.FtpWebRequest]::Create($remote) $request.Credentials = New-Object System.Net.NetworkCredential($Env:FtpUsername, $Env:FtpPassword) $request.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile $request.UsePassive = $true $fileStream = [System.IO.File]::OpenRead($local) $ftpStream = $request.GetRequestStream() $fileStream.CopyTo($ftpStream) $ftpStream.Dispose() $fileStream.Dispose() } uploadToFTPServer "ftp://example.com/archive.zip" "C:archive.zip"
Puisqu’il utilise des flux de fichiers et ne lit pas tous les octets, cela a l’avantage de mieux fonctionner avec d’énormes transferts de fichiers.
Envoi de transferts SFTP avec Posh-SSH
SFTP est un protocole FTP alternatif qui fonctionne sur SSH. C’est un peu plus compliqué à utiliser que le FTP classique, car vous ne pouvez pas simplement envoyer un nom d’utilisateur et un mot de passe, et il n’est pas pris en charge par PowerShell natif.
Vous devrez installer le Posh-SSH
package pour communiquer via SFTP :
Install-Module -Name Posh-SSH
Ensuite, vous pourrez démarrer une nouvelle session, en utilisant un nouvel objet d’identification. Cela fonctionne de la même manière que les transferts de requête Web, sauf que vous devrez également fermer la session à la fin.
Import-Module Posh-SSH $Password = ConvertTo-SecureString $Env:FtpPassword -AsPlainText -Force $Credential = New-Object System.Management.Automation.PSCredential ($Env:FtpUsername, $Password) $FilePath = "C:archive.zip" $SftpPath="/folder" $ThisSession = New-SFTPSession -ComputerName '1.2.3.4' -Credential $Credential Set-SFTPFile -SessionId ($ThisSession).SessionId -LocalFile $FilePath -RemotePath $SftpPath Get-SFTPSession | % { Remove-SFTPSession -SessionId ($_.SessionId) }
Envoi de fichiers volumineux avec une barre de progression dans PowerShell
Utilisation du flux de fichiers CopyTo
est simple, mais pour les longs transferts, vous souhaiterez peut-être une sorte de suivi de la progression. C’est un peu compliqué à ajouter, puisque vous devrez copier les flux vous-même, mais fonctionne bien avec le script suivant :
$request = [Net.WebRequest]::Create("ftp://example.com/path/archive.zip") $request.Credentials = New-Object System.Net.NetworkCredential($Env:FtpUsername, $Env:FtpPassword) $request.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile $fileStream = [System.IO.File]::OpenRead("C:archive.zip") $ftpStream = $request.GetRequestStream() $buffer = New-Object Byte[] 10240 while (($read = $fileStream.Read($buffer, 0, $buffer.Length)) -gt 0) { $ftpStream.Write($buffer, 0, $read) $pct = ($fileStream.Position / $fileStream.Length) Write-Progress ` -Activity "Uploading" -Status ("{0:P0} complete:" -f $pct) ` -PercentComplete ($pct * 100) } $ftpStream.Dispose() $fileStream.Dispose()