PowerShell : BITS, une méthode efficace pour télécharger et transférer des fichiers
Sommaire
I. Présentation
Dans ce tutoriel, nous allons voir comment télécharger des fichiers avec BITS via PowerShell, afin de profiter d'une méthode plus performante qu'avec le cmdlet Invoke-WebRequest.
Mais, au fait, c'est quoi BITS ? BITS pour Background Intelligent Transfer Service est un composant de Windows qui permet d'effectuer des transferts de données intelligents en arrière-plan. Il offre des possibilités intéressantes par rapport à une simple copie, notamment :
- La possibilité de mettre en pause et de reprendre un téléchargement (même en cas de coupure réseau) - Comme peut le permettre l'outil Robocopy
- La possibilité de gérer la priorité, c'est-à-dire la bande passante que nous allons allouer par rapport à l'activité réseau de la machine sur laquelle il s'exécute. Cet ajustement sera effectué avec le paramètre "-Priority" du commandlet "Start-BitsTransfer"
- Une véritable gestion des jobs, qui peuvent se dérouler en mode synchrone ou asynchrone
Ce n'est pas un nouveau composant intégré par Microsoft récemment puisqu'il existe depuis Windows XP, mais il a évolué au fil des versions de Windows (via bitsadmin.exe), le module PowerShell quant à lui est présent depuis PowerShell 2.0. Au-delà de PowerShell, BITS est utilisé notamment par WSUS et Windows Update.
Version originale de l'article : 6 février 2017
II. Les commandes du module BitsTransfer
Sur Windows, BITS dispose de son module PowerShell nommé "BitsTransfer". Il permet de gérer des jobs via la ligne de commande, ce qui est intéressant pour scripter, surtout pour transférer des gros fichiers où la probabilité qu'une coupure intervienne est plus forte.
Voici comment obtenir la liste de toutes les commandes de ce module :
Get-Command -Module BitsTransfer
Ensuite, la liste des commandes s'affiche dans la console :
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Add-BitsFile 2.0.0.0 BitsTransfer
Cmdlet Complete-BitsTransfer 2.0.0.0 BitsTransfer
Cmdlet Get-BitsTransfer 2.0.0.0 BitsTransfer
Cmdlet Remove-BitsTransfer 2.0.0.0 BitsTransfer
Cmdlet Resume-BitsTransfer 2.0.0.0 BitsTransfer
Cmdlet Set-BitsTransfer 2.0.0.0 BitsTransfer
Cmdlet Start-BitsTransfer 2.0.0.0 BitsTransfer
Cmdlet Suspend-BitsTransfer 2.0.0.0 BitsTransfer
Le module BitsTransfer n'a pas évolué depuis longtemps : la version 2.0 était déjà disponible en 2017, lorsque la première version de ce tutoriel a été écrite. Il intègre 8 commandlets qui vont permettre de créer des jobs avec BITS et de les gérer. Dans ce tutoriel, nous n'utiliserons pas tous les commandlets disponibles, mais nous aurons l'occasion d'en manipuler quelques-uns : Get-BitsTransfer, Complete-BitsTransfer, Start-BitsTransfer.
Note : Les commandlets "Suspend-BitsTransfer" et "Resume-BitsTransfer" permettent respectivement de suspendre un job BITS ou de reprendre un job BITS suspendu.
III. Télécharger un fichier avec BITS, via HTTP(S)
Passons maintenant à quelque chose de plus intéressant : le téléchargement d'un fichier par l'intermédiaire d'un job BITS. Pour commencer, nous allons utiliser le commandlet "Start-BitsTransfer" et deux paramètres pour définir la source et la destination. C'est un strict minimum pour utiliser ce commandlet qui offre bien d'autres possibilités.
A titre d'exemple, nous allons télécharger un fichier MSI depuis le GitHub de PowerShell et le le stocker dans "C:\temp\" en lui donnant comme nom son nom d'origine (qui sera écrit explicitement) voici la commande à exécuter :
Start-BitsTransfer -Source "https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/PowerShell-7.4.6-win-x64.msi" -Destination "C:\temp\PowerShell-7.4.6-win-x64.msi"
Une barre de progression s'affiche :
Lors d'un téléchargement, il y a différentes phases : Connecting, Transferring et Transferred (lorsque le téléchargement est terminé). Nous pouvons aussi rencontrer "TransientError" s'il y a un job en erreur. Par défaut, le mode de fonctionnement est synchrone, ce qui implique qu'avant de continuer, le script attendra la fin du téléchargement. Pour lancer plusieurs jobs en boucle à la volée, il faudra passer en mode asynchrone, c'est ce que nous allons voir maintenant.
IV. Téléchargement asynchrone avec BITS, via HTTPS
Le passage en mode asynchrone implique qu'il faut ajouter le paramètre "-Asynchronous" à la commande que l'on a exécuté précédemment, ce qui donnera :
Start-BitsTransfer -Source "https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/PowerShell-7.4.6-win-x64.msi" -Destination "C:\temp\PowerShell-7.4.6-win-x64.msi" -Asynchronous
Cette commande retourne :
JobId DisplayName TransferType JobState OwnerAccount
----- ----------- ------------ -------- ------------
8acce517-073c-4746-ab0f-abdd6c93afb3 BITS Transfer Download Connecting W11-01\Florian
Note : vous remarquerez dans la sortie de commande ci-dessus, la valeur "TransferType" à "Download". Ceci est logique, car BITS permet aussi de réaliser des jobs d'upload, pour cela il faudra utiliser le paramètre "TransferType" avec "Start-BitsTransfer".
Nous pouvons afficher l'évolution de notre job BITS en invoquant régulièrement cette commande :
Get-BitsTransfer
Lorsque nous sommes en mode asynchrone, il faut valider la fin du job BITS pour que le fichier soit sauvegardé sur votre machine à l'endroit indiqué dans le paramètre "-Destination". En attendant, le fichier téléchargé prend la forme d'un fichier temporaire (fichier .tmp). Pour valider tous les jobs, nous devons utiliser la commande suivante :
Get-BitsTransfer | Complete-BitsTransfer
Nous pourrions aussi préciser uniquement le job que nous venons de lancer, soit par son JobId ou son DisplayName, ce qui donnerait :
Get-BitsTransfer -JobId "8acce517-073c-4746-ab0f-abdd6c93afb3" | Complete-BitsTransfer
À partir de ce moment-là (sauf s'il y a eu une erreur), le fichier est enregistré sur votre machine !
V. Des paramètres supplémentaires pour les transferts BITS
Quand vous lancez le cmdlet "Start-BitsTransfer", vous pouvez aussi préciser d'autres paramètres. Voici quelques-uns des paramètres que vous pouvez utiliser :
- -Priority : déterminer la priorité, dans l'utilisation de la bande passante réseau, disponible sur la machine Windows (élévée, normal ou faible).
- -Credential et -Authentication : préciser des identifiants et une méthode d'authentification, pour s'authentifier sur le serveur source ou destination (selon s'il s'agit d'un upload ou d'un download).
- -DisplayName : ajouter un nom convivial à la tâche de transfert BITS, au lieu d'un simple "BITS Transfer", ce qui peut être utile pour préciser le nom du fichier.
- -TransferType : définir le type de transfert (par défaut : télécharger). Valeurs possibles : Download, Upload, Upload-Reply.
Passons maintenant au dernier exemple de ce tutoriel...
VI. Transférer un ensemble de fichiers avec BITS via SMB
Le téléchargement de fichiers avec BITS ne se limite pas aux fichiers hébergés sur le Web. Il peut tout à fait être utilisé pour télécharger plusieurs fichiers hébergés sur un serveur Web ou pour télécharger des fichiers hébergés sur un partage. D'ailleurs, je l'ai très souvent utilisé pour effectuer des transferts de fichiers entre deux machiens, via le protocole SMB (partages de fichiers).
De manière générale, la commande Start-BitsTransfer s'utilise de la même façon que la source soit un partage réseau ou une URL Web.. Par exemple, pour transférer tous les fichiers d'un dossier source vers une destination sur le réseau (chemin UNC), nous pouvons exécuter cette commande :
Start-BitsTransfer -Source "C:\TEMP\DATA\*.*" -Destination "\\srv-fichiers-01.it-connect.local\DATA\"
Dans la destination, les fichiers vont conserver leurs noms d'origine. Le problème, c'est que cela ne tient pas compte des sous-dossiers (et de leurs fichiers). Pour tenter d'avoir un meilleur résultat, nous pouvons coupler l'utilisation de Start-BitsTransfer à Get-ChildItem. Ainsi, BITS va bien envoyer tous les fichiers de la source vers la destination (copie réseau), mais sans reproduire l'arborescence de dossiers. Autrement dit, tous les fichiers seront copiés en vrac dans la destination.
Get-ChildItem "C:\TEMP\DATA\" -Recurse | Foreach { Start-BitsTransfer -Source $_.FullName -Destination "\\srv-fichiers-01.it-connect.local\DATA\" }
Pour aller plus loin, et reproduire l'arborescence complète, vous pouvez utiliser mon script PowerShell disponible sur GitHub.
Si vous mettez en source une arborescence avec un dossier racine, contenant des fichiers, puis des sous-dossiers avec d'autres fichiers, ces sous-dossiers peuvent contenir d'autres dossiers avec eux aussi des fichiers, etc... Tout sera recréé au sein de la destination avec la même arborescence et les mêmes noms de fichiers, en s'appuyant sur BITS. Un job BITS par sous-dossier sera généré.
Voici un exemple :
.\Start-BitsDownloadRecursive.ps1 -Source "C:\TEMP\DATA\" -Destination "\\srv-fichiers-01.it-connect.local\DATA\"
Vous pouvez tout à fait récupérer ce script pour l'améliorer.
VII. Conclusion
Lorsqu'il est question de télécharger, de charger ou de transférer des données avec PowerShell, BITS est clairement une solution à ne pas négliger. C'est relativement simple à utiliser, une fois que l'on a bien compris la mécanique des différents cmdlets. Grâce à ce tutoriel, vous disposer de quelques exemples qui vont vous permettre de prendre en main le transfert de fichiers BITS avec PowerShell !
Enfin, pour obtenir de l'aide sur les différents commandlets du module, consultez cette page :
Bonjour la commande « Get-Command -Module BitsTransfer » ne sert pas à importer le module mais juste à obtenir les commandes liées à celui-ci.
Hello TheMinester,
Effectivement, j’ai corrigé. Il s’agit d’une phrase que j’ai oublié de remplacer, lorsque j’ai mis à jour l’article (la version d’origine contenait la commande Import-Module).
bonjour est-ce que bits transfert service peux faire office de copie différentielle entre la source et la destination smb ?