Reputation: 1243
I would like to be able to write a PowerShell script that would take a folder (or set of folders) and to duplicate them in which the folder structure (without the files) could be created, where the file structure (without the folders) could be created, or in which both the files (all or selected ones) AND folders could be created.
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
Each folder above has a various number of files of various sizes in it, of various file extensions.
I would like to have a PowerShell script that would duplicate that folder structure elsewhere, giving me a choice of Folder Structure Only, Files Only, or Files AND Folders to be copied.
In the above, I'd like to be able to copy C:\ProdData to another folder, essentially renaming ProdData to TestData (that is, C:\ProdData copied to C:\TestData), or to copy the entire folder structure.
C:\ProdData
into another folder that is a subfolder of something else: C:\TestArea\TestFolders\2012-04-01\TestData\ProdData\Fld1
, etc...
And selectively choose to include folders, files or both.
The ideal solution would be to (for folders only) take the folder structure, export/save it, read it in, and create that same structure elsewhere. Some solutions I've found said they copied the folder structure only, but if data exists, that gets copied also and you can't exclude one or the other. I have a partial solution to the files-only requirement that semi-preserves the path, but it would take a file:
c:\ProdData\Fld1\MyFile.dat
and copy it to:
c:\TestData\yyyyMMdd_hhmmss_ProdData_Fld1_MyFile.dat
But that's not something that could easily be decoded and would be impossible to re-integrate the source structure. I'd appreciate any thoughts about how to accomplish this without re-inventing the wheel.
Upvotes: 31
Views: 64283
Reputation: 17472
I propose my 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
Upvotes: 7
Reputation: 193
The following copies just the folder structure form ProdData to TestData without any files
$from = "C:\ProdData"
$to = "C:\TestData"
Get-ChildItem -Path $from -Recurse |
?{ $_.PSIsContainer } |
Copy-Item -Destination {Join-Path $to $_.Parent.FullName.Substring($from.length)} -Force
Upvotes: 1
Reputation: 485
To copy everything in a folder hierarchie
Copy-Item $source $dest -Recurse -Force
To copy the hierarchie you can try:
$source = "C:\ProdData"
$dest = "C:\TestData"
Copy-Item $source $dest -Filter {PSIsContainer} -Recurse -Force
To flatten a file structure you can try:
$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}
Good luck!
Upvotes: 37
Reputation: 4603
Here are some ideas for handling each situation you describe.
Folder Structure Only
This will copy the source to a destination, recursing subdirectories but excluding all files.
robocopy $source $dest /e /xf *.*
Files Only (Flatten Structure)
There are a few ways to handle this, but I don't know of an especially good or elegant way. Here's an awkward but effective approach - for each subdirectory, it runs a non-recursive copy to a root destination folder. Criticism or nicer alternatives would be most welcome.
Get-ChildItem $source -Recurse |
Where-Object { $_.PSIsContainer -eq $true } |
Foreach-Object { robocopy $_.FullName $dest }
Everything
This scenario is the most straightforward of the bunch.
robocopy $source $dest /e
You can experiment with the switches yourself (referencing robocopy /?
along the way) to fine tune the process. The trickiest scenario in my opinion is the one that flattens the directory structure. You'll have some decisions to make, like how you want to handle the same file name appearing in multiple directories.
As for how to accept options from the command line, I'd suggest putting together Powershell parameter sets for your three situations. There are a number of blog posts around that discuss the concept, but you can also see TechNet or run help about_Functions_Advanced_Parameters
inside Powershell.
Upvotes: 35