Copier des fichiers efficacement avec PowerShell Copy-Item : Un guide complet

Copie de fichiers. Ce n’est pas sexy mais il faut le faire. Dans l’interface graphique, nous copions et collons avec le presse-papiers, mais en PowerShell, nous avons une cmdlet appelée Copy-Item.

Les commandes de copie de fichiers existent depuis toujours dans tous les langages de shell. Dans l’univers PowerShell, la méthode la plus populaire pour copier un fichier ou un dossier dans votre script PowerShell de A à B est d’utiliser la cmdlet PowerShell Copy-Item. Cette cmdlet nous permet de copier un fichier et un dossier tout en nous donnant la possibilité de parcourir les fichiers d’un dossier, d’utiliser des caractères génériques pour sélectionner les fichiers que nous devons copier et même d’utiliser PowerShell Remoting pour une copie de fichier !

Cette cmdlet fait partie des cmdlets fournisseurs PowerShell. C’est une cmdlet générique reconnue par son nom de type Item. La plupart de ces cmdlets fournisseurs peuvent être utilisées avec différents fournisseurs, mais au cours de mes presque 10 ans d’utilisation de PowerShell, je n’ai vu Copy-Item utilisée qu’avec le fournisseur du système de fichiers.

En utilisant cette cmdlet, PowerShell permet à un développeur de copier des fichiers et des dossiers de différentes manières.

Utilisation de base

Dans sa forme la plus basique, la cmdlet Copy-Item copie un seul fichier de A à B en utilisant le paramètre Path comme chemin source du fichier et le paramètre Destination comme chemin du dossier de destination.

PS> Test-Path -Path C:\PointB\1.txt
False
PS> Copy-Item -Path C:\PointA\1.txt -Destination C:\PointB\
PS> Test-Path -Path C:\PointB\1.txt
True 

Cette cmdlet peut également copier des dossiers vides. Je vais lister les éléments dans le dossier C:\EmptyFolder puis les copier.

PS> Get-ChildItem -Path C:\EmptyFolder\
PS> Test-Path -Path C:\PointB\EmptyFolder -PathType Container
False
PS> Copy-Item -Path C:\EmptyFolder\ -Destination C:\PointB\
PS> Test-Path -Path C:\PointB\EmptyFolder -PathType Container
True 

Il se peut qu’il y ait un fichier en lecture seule dans le dossier. Par défaut, Copy-Item ne l’écrasera pas. Pour forcer l’écrasement, ajoutez simplement le paramètre Force.

Être sélectif avec Copy-Item

En plus de copier un seul fichier ou dossier, nous pouvons également copier l’intégralité du contenu d’un dossier. Le paramètre Path de Copy-Item accepte des caractères génériques tels que l’astérisque pour correspondre à un ou plusieurs caractères ou le point d’interrogation pour correspondre à un seul caractère.

PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> @(Get-ChildItem -Path C:\PointA).Count
10000
PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> Copy-Item -Path C:\PointA\* -Destination C:\PointB\
PS> @(Get-ChildItem -Path C:\PointB).Count
10000
PS> @(Get-ChildItem -Path C:\PointB).Count
0
PS> Copy-Item -Path 'C:\PointA\26?0.txt' -Destination C:\PointB\
PS> Get-ChildItem -Path C:\PointB\

Directory: C:\PointB
Mode                LastWriteTime         Length Name
-a----        8/11/2017   8:59 AM              5 2600.txt
-a----        8/11/2017   8:59 AM              5 2610.txt
-a----        8/11/2017   8:59 AM              5 2620.txt
-a----        8/11/2017   8:59 AM              5 2630.txt
-a----        8/11/2017   8:59 AM              5 2640.txt
-a----        8/11/2017   8:59 AM              5 2650.txt
-a----        8/11/2017   8:59 AM              5 2660.txt
-a----        8/11/2017   8:59 AM              5 2670.txt
-a----        8/11/2017   8:59 AM              5 2680.txt
-a----        8/11/2017   8:59 AM              5 2690.txt

Fusionner plusieurs dossiers ensemble

Une autre fonctionnalité intéressante de Copy-Item est sa capacité à copier plusieurs dossiers simultanément. En passant plusieurs chemins au paramètre Path, Copy-Item examinera chacun d’entre eux, copiera soit le dossier, soit le(s) fichier(s) en fonction du chemin et les « fusionnera » tous dans la destination unique.

PS> Copy-Item -Path C:\PointB\*,C:\PointC\*,C:\PointD\* -Destination C:\PointE
PS> Get-ChildItem -Path C:\PointE

Directory: C:\PointE
Mode                LastWriteTime         Length Name
-a----       11/11/2017  12:15 PM              2 PointBFile.txt
-a----       11/11/2017  12:15 PM              2 PointCFile.txt
-a----       11/11/2017  12:16 PM              4 PointDFile.txt

Copier des fichiers de manière récursive

Il est peu probable que vous ayez la chance d’avoir tous les fichiers dans un seul dossier sans sous-dossiers à l’intérieur. Nous rencontrons généralement des situations où nous avons beaucoup de sous-dossiers dans le dossier parent qui contiennent également des fichiers que nous aimerions copier. En utilisant le paramètre Recurse sur Copy-Item, il examinera volontiers chaque sous-dossier et copiera tous les fichiers et dossiers de manière récursive.

Remarquez ici que je transmets les fichiers et dossiers de Get-ChildItem directement à Copy-Item. Copy-Item prend en charge le pipeline !

PS> (Get-ChildItem -Path C:\PointB\ -Recurse).Count
5
PS> Get-ChildItem -Path C:\PointB\ | Copy-Item -Destination C:\PointC -Recurse
PS> (Get-ChildItem -Path C:\PointC\ -Recurse).Count
5

Avantages de l’utilisation du paramètre PassThru

De nombreux cmdlets de PowerShell ont un paramètre PassThru. Les cmdlets qui ne renvoient généralement rien peuvent renvoyer les objets qu’ils manipulent en utilisant le paramètre PassThru. Ce cmdlet ne fait pas exception. Lorsque j’ai commencé à écrire des scripts, je n’utilisais jamais ce paramètre car je ne pensais pas en avoir besoin.

Par exemple, si je voulais copier un fichier vers un emplacement distant et y faire référence plus tard dans mon script, je ferais quelque chose comme ceci :

$remoteFilePath = '\WEBSRV1\c$\File.txt'
Copy-Item -Path C:\File.txt -Destination $remoteFilePath
Write-Host "I've just copied the file to $remoteFilePath"

Cette méthode fonctionne, mais elle peut être améliorée. Au lieu de définir une variable pour le chemin distant, pourquoi ne pas simplement capturer l’objet renvoyé par la cmdlet Copy-Item en utilisant le paramètre PassThru ? Les objets renvoyés auront toujours le chemin d’accès du fichier de destination.

$copiedFile = Copy-Item -Path C:\File.txt -Destination '\WEBSRV1\c$'

Copie de fichiers à l’aide d’une session d’accès distant PowerShell

Une fonctionnalité intéressante introduite avec PowerShell v5 est la capacité de cette cmdlet à ne pas utiliser le protocole SMB par défaut pour transférer un fichier, mais à utiliser plutôt WinRM et une session d’accès distant PowerShell. En utilisant le paramètre Session, Copy-Item utilise une session PowerShell existante et transfère les fichiers de cette manière. C’est un excellent moyen de contourner les pare-feu et, lorsque la communication de la session est chiffrée, cela ajoute également une couche de sécurité supplémentaire.

PS> $session = New-PSSession -ComputerName WEBSRV1
PS> Invoke-Command -Session $session -ScriptBlock { Test-Path -Path C:\File.txt }
False
PS> Copy-Item -Path C:\File.txt -ToSession $session -Destination 'C:\'
PS> Invoke-Command -Session $session -ScriptBlock { Test-Path -Path C:\File.txt }
True

Nous aurions pu copier le fichier File.txt via SMB et espérer que le partage administratif C$ soit disponible et utiliser le chemin de destination \\WEBSRV1\c$. Comme nous avons utilisé le paramètre ToSession à la place, le chemin de destination sera toujours le chemin local de l’ordinateur sur lequel s’exécute la session distante.

Résumé

Le cmdlet Copy-Item est l’un de ces cmdlets principaux de PowerShell que vous utiliserez encore et encore. En PowerShell, vous pouvez copier des fichiers et des dossiers de différentes manières grâce à sa simplicité et sa puissance, notamment grâce à sa capacité à utiliser des caractères génériques, à fusionner plusieurs dossiers de fichiers ensemble et à utiliser des sessions PowerShell à distance existantes!

Plus de lectures

Copy-item

Source:
https://adamtheautomator.com/copy-item/