web-dev-qa-db-fra.com

Copier des dossiers sans fichiers, des fichiers sans dossiers ou tout ce qui utilise PowerShell

J'aimerais pouvoir écrire un script PowerShell prenant un dossier (ou un ensemble de dossiers) et les dupliquer dans lequel la structure de dossiers (sans les fichiers) pourrait être créée, où la structure de fichiers (sans les dossiers) pourrait être créé ou dans lequel les deux fichiers (tous ou tous les dossiers sélectionnés)ETpeuvent être créés.

    Example:

    C:\ProdData has 3 subfolders in it
    C:\ProdData\Fld1
    C:\ProdData\Fld2
    C:\ProdData\Fld3 - has 2 subfolders under it
    C:\ProdData\Fld3\MyFolder1
    C:\ProdData\Fld3\MyFolder2

Chaque dossier ci-dessus contient un nombre différent de fichiers de différentes tailles, d’extensions de fichiers différentes.

J'aimerais avoir un script PowerShell qui dupliquerait cette structure de dossiers ailleurs, me donnant le choix entre Structure des dossiers uniquement , Fichiers uniquement , ou Fichiers AND Folders à copier.

Dans ce qui précède, j'aimerais pouvoir copier C:\ProdData dans un autre dossier, en renommant essentiellement ProdData en TestData (c'est-à-dire C:\ProdData copié dans C:\TestData ), ou pour copier la structure de dossiers complète.

C:\ProdData dans un autre dossier qui est un sous-dossier de quelque chose d'autre:C:\TestArea\TestFolders\2012-04-01\TestData\ProdData\Fld1, etc ...

Et choisissez de manière sélective d'inclure des dossiers, des fichiers ou les deux.

La solution idéale serait (pour les dossiers uniquement) de prendre la structure de dossiers, de l’exporter/de la sauvegarder, de la lire et de créer la même structure ailleurs. Certaines solutions que j'ai trouvées indiquent qu'elles copient uniquement la structure de dossiers, mais si des données existent, elles sont également copiées et vous ne pouvez pas exclure l'une ou l'autre. J'ai une solution partielle à l'exigence de fichiers uniquement qui préserve le chemin, mais cela prendrait un fichier:

c:\ProdData\Fld1\MyFile.dat

et le copier dans:

c:\TestData\yyyyMMdd_hhmmss_ProdData_Fld1_MyFile.dat

Mais ce n'est pas quelque chose qui pourrait être facilement décodé et il serait impossible de réintégrer la structure source. J'apprécierais toute idée sur la manière de réaliser cela sans réinventer la roue.

18
steve_o

Pour tout copier dans un dossier hierarchie

Copy-Item $source $dest -Recurse -Force

Pour copier la hiérarchie, vous pouvez essayer:

$source = "C:\ProdData"
$dest = "C:\TestData"
Copy-Item $source $dest -Filter {PSIsContainer} -Recurse -Force

Pour aplatir une structure de fichier, vous pouvez essayer:

$source = "C:\ProdData"
$dest = "C:\TestData"
New-Item $dest -type directory
Get-ChildItem $source -Recurse | `
    Where-Object { $_.PSIsContainer -eq $False } | `
    ForEach-Object {Copy-Item -Path $_.Fullname -Destination $dest -Force} 

Bonne chance!

19
Reinout

Voici quelques idées pour gérer chaque situation que vous décrivez.

Structure des dossiers uniquement

Cela copiera la source dans une destination, en recourant aux sous-répertoires mais en excluant tous les fichiers.

robocopy $source $dest /e /xf *.*

Fichiers uniquement (Structure aplatie)

Il y a plusieurs façons de gérer cela, mais je ne connais pas de manière particulièrement bonne ou élégante. Voici une approche peu commode mais efficace: pour chaque sous-répertoire, il exécute une copie non récursive dans un dossier de destination racine. Des critiques ou des alternatives plus agréables seraient les bienvenues.

Get-ChildItem $source -Recurse |
  Where-Object { $_.PSIsContainer -eq $true } |
  Foreach-Object { robocopy $_.FullName $dest }

Tout

Ce scénario est le plus simple du groupe.

robocopy $source $dest /e

Vous pouvez tester vous-même les commutateurs (en faisant référence à robocopy /? en cours de route) pour affiner le processus. Le scénario le plus délicat à mon avis est celui qui aplatit la structure des répertoires. Vous aurez des décisions à prendre, comme comment vous voulez gérer le même nom de fichier apparaissant dans plusieurs répertoires.

Pour accepter les options de la ligne de commande, je vous suggère de créer des jeux de paramètres Powershell pour vos trois situations. Un certain nombre de blogs autour du concept traitent du concept, mais vous pouvez également consulter TechNet ou exécuter help about_Functions_Advanced_Parameters dans Powershell.

30
ajk

Ce qui suit ne copie que la structure de dossiers de ProdData à TestData sans aucun fichier.

$from = "C:\ProdData"
$to = "C:\TestData"

Get-ChildItem -Path $from -Recurse | 
?{ $_.PSIsContainer } | 
Copy-Item -Destination {Join-Path $to $_.Parent.FullName.Substring($from.length)} -Force 

1
Fred B

Je propose ma solution:

$source = "C:\temp\"
$dest = "C:\TestData\"

#create destination directory if dont exist
New-Item -ItemType Directory $dest -Force


#To copy everything in a folder hierarchie
Get-ChildItem $source -Recurse | Copy-Item -Destination {$_.FullName.Replace($source, $dest)}  -Force

#To copy only directory hierarchie:
Get-ChildItem $source -Recurse -directory | Copy-Item -Destination {$_.FullName.Replace($source, $dest)}  -Force

#To copy only file (remove doublon be carefull):
Get-ChildItem $source -Recurse -file | Copy-Item -Destination $dest -Force
0
Esperento57