81 votes

Télécharger des fichiers avec FTP en utilisant PowerShell

Je veux utiliser PowerShell pour transférer des fichiers avec FTP vers un serveur FTP anonyme. Je n'utiliserais pas de paquetage supplémentaire. Comment faire ?

Il ne doit y avoir aucun risque que le script se bloque ou se plante.

0 votes

Le planificateur de tâches JAMS offre cmdlets qui facilitent les transferts de fichiers sécurisés. Les cmdlets permettent d'automatiser simplement les transferts et de se connecter en utilisant divers protocoles. (FTP, SFTP, etc...)

89voto

Goyuix Points 9634

Je ne suis pas sûr que vous pouvez 100% bullet proof le script de ne pas suspendre ou planter, comme il ya des choses en dehors de votre contrôle (que faire si le serveur perd de l'énergie à mi-charge ?) - mais cela devrait fournir une base solide pour vous faire démarrer :

# create the FtpWebRequest and configure it
$ftp = [System.Net.FtpWebRequest]::Create("ftp://localhost/me.png")
$ftp = [System.Net.FtpWebRequest]$ftp
$ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$ftp.Credentials = new-object System.Net.NetworkCredential("anonymous","anonymous@localhost")
$ftp.UseBinary = $true
$ftp.UsePassive = $true
# read in the file to upload as a byte array
$content = [System.IO.File]::ReadAllBytes("C:\me.png")
$ftp.ContentLength = $content.Length
# get the request stream, and write the bytes into it
$rs = $ftp.GetRequestStream()
$rs.Write($content, 0, $content.Length)
# be sure to clean up after ourselves
$rs.Close()
$rs.Dispose()

1 votes

Comment repérer les erreurs ? Que se passe-t-il si je ne peux pas me connecter ? si je ne peux pas envoyer le fichier ? si la connexion est interrompue ? Je veux gérer les erreurs et en informer l'utilisateur.

18 votes

Ce sont toutes de très bonnes questions individuelles qui concernent les scripts PowerShell en général et qui peuvent être appliquées à bien d'autres scénarios que la simple gestion des transactions ftp. Mon conseil : Parcourez le tag PowerShell ici et lisez sur la gestion des erreurs. La plupart de ce qui pourrait mal tourner dans ce script lancera une exception, il suffit d'envelopper le script dans quelque chose qui le gérera.

3 votes

Ce n'est pas une bonne solution pour les gros fichiers zip. Lorsque j'essaie "$content = gc -en byte C:\mybigfile.zip "Le traitement du powershell a pris beaucoup de temps. La solution proposée par @CyrilGupta fonctionne mieux pour moi.

52voto

Cyril Gupta Points 7189

Il y a aussi d'autres moyens. J'ai utilisé le script suivant :

$File = "D:\Dev\somefilename.zip";
$ftp = "ftp://username:password@example.com/pub/incoming/somefilename.zip";

Write-Host -Object "ftp url: $ftp";

$webclient = New-Object -TypeName System.Net.WebClient;
$uri = New-Object -TypeName System.Uri -ArgumentList $ftp;

Write-Host -Object "Uploading $File...";

$webclient.UploadFile($uri, $File);

Et vous pouvez exécuter un script contre l'utilitaire de ligne de commande FTP de Windows en utilisant la commande suivante

ftp -s:script.txt 

(Voir cet article )

La question suivante sur SO répond également à cette question : Comment faire pour script uploader et télécharger par FTP ?

0 votes

Il ne semble pas y avoir de moyen de désactiver le mode PASSIF en utilisant la première option présentée ici.

2 votes

Si votre mot de passe contient des caractères qui ne sont pas autorisés dans une URL, alors la création de l'icône $uri lance une erreur. Je préfère définir les informations d'identification sur le client : $webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)

0 votes

Le problème de la passivité était en fait un avantage lorsqu'on utilisait le service FTP de box.com (qui ne supporte que le mode passif). En ce qui concerne les caractères non autorisés dans l'URL : ceci devrait être utile ... utilitaire intégré pour coder/décoder l'URL et donc, par exemple, dans Powershell ftps téléchargement vers box.com en utilisant le mode passif

32voto

Dexter Legaspi Points 404

Je ne vais pas prétendre que c'est plus élégant que la solution la plus votée... mais c'est cool (enfin, au moins dans mon esprit LOL) à sa façon :

$server = "ftp.lolcats.com"
$filelist = "file1.txt file2.txt"   

"open $server
user $user $password
binary  
cd $dir     
" +
($filelist.split(' ') | %{ "put ""$_""`n" }) | ftp -i -in

Comme vous pouvez le voir, il utilise le minuscule client FTP intégré de Windows. C'est beaucoup plus court et plus simple, aussi. Oui, je l'ai vraiment utilisé et ça marche !

2 votes

Et si vous utilisez un autre type de FTP, il vous suffit de passer à un autre programme. Bien.

3 votes

C'est un peu délicat (si vous cassez l'utilisateur utilisateur passer en trois lignes ça ne marche pas, contrairement à l'utilisation d'un fichier script) et non documenté (qu'est-ce que le switch -in dans ftp), mais ça a marché !

0 votes

Excellente suggestion. Mes tests montrent que la commande FTP correcte est ftp.exe -i -n -d - ces interrupteurs sont tous documentés. Peut-être que la fonctionnalité a changé dans la version du système d'exploitation, mais je n'ai pas pu faire fonctionner la version affichée du tout. L'interrupteur critique ici est -n - désactiver l'autologon . Ou bien le USER n'est pas valide. Cette méthode d'entrée redirigée échoue si les lettres de créance sont sur des lignes séparées, c'est à dire [USERNAME][PASS] comme c'est le cas lors de l'exécution de commandes FTP. L'entrée ici doit ont USER [USERNAME] [PASS] sur une seule ligne après le OPEN [HOSTNAME] selon le commentaire précédent.

3voto

Edouard Kombo Points 31

Vous pouvez simplement gérer les téléchargements de fichiers par PowerShell, comme ceci. Le projet complet est disponible sur Github ici https://github.com/edouardkombo/PowerShellFtp

#Directory where to find pictures to upload
$Dir= 'c:\fff\medias\'

#Directory where to save uploaded pictures
$saveDir = 'c:\fff\save\'

#ftp server params
$ftp = 'ftp://10.0.1.11:21/'
$user = 'user'
$pass = 'pass'

#Connect to ftp webclient
$webclient = New-Object System.Net.WebClient 
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)  

#Initialize var for infinite loop
$i=0

#Infinite loop
while($i -eq 0){ 

    #Pause 1 seconde before continue
    Start-Sleep -sec 1

    #Search for pictures in directory
    foreach($item in (dir $Dir "*.jpg"))
    {
        #Set default network status to 1
        $onNetwork = "1"

        #Get picture creation dateTime...
        $pictureDateTime = (Get-ChildItem $item.fullName).CreationTime

        #Convert dateTime to timeStamp
        $pictureTimeStamp = (Get-Date $pictureDateTime).ToFileTime()

        #Get actual timeStamp
        $timeStamp = (Get-Date).ToFileTime() 

        #Get picture lifeTime
        $pictureLifeTime = $timeStamp - $pictureTimeStamp

        #We only treat pictures that are fully written on the disk
        #So, we put a 2 second delay to ensure even big pictures have been fully wirtten   in the disk
        if($pictureLifeTime -gt "2") {    

            #If upload fails, we set network status at 0
            try{

                $uri = New-Object System.Uri($ftp+$item.Name)

                $webclient.UploadFile($uri, $item.FullName)

            } catch [Exception] {

                $onNetwork = "0"
                write-host $_.Exception.Message;
            }

            #If upload succeeded, we do further actions
            if($onNetwork -eq "1"){
                "Copying $item..."
                Copy-Item -path $item.fullName -destination $saveDir$item 

                "Deleting $item..."
                Remove-Item $item.fullName
            }

        }  
    }
}

2voto

Mike Brady Points 58

La solution de Goyuix fonctionne très bien, mais tel que présenté, il me donne cette erreur : "La commande FTP demandée n'est pas prise en charge par le proxy HTTP".

En ajoutant cette ligne après $ftp.UsePassive = $true a réglé le problème pour moi :

$ftp.Proxy = $null;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X