How to use PowerShell copy-item and keep structure
I have a directory structure that looks like this:
C:\folderA\folderB\folderC\client1\f1\files
C:\folderA\folderB\folderC\client1\f2\files
C:\folderA\folderB\folderC\client2\f1\files
C:\folderA\folderB\folderC\client2\f2\files
C:\folderA\folderB\folderC\client3\f1\files
C:\folderA\folderB\folderC\client4\f2\files
I want to copy the content of the f1
folders in C:\tmp\ to get this
C:\tmp\client1\f1\files
C:\tmp\client2\f1\files
C:\tmp\client3\f1\files
I tried this:
Copy-Item -recur -path: "*/f1/" -destination: C:\tmp\
But it copies the contents without copying the structure correctly.
Solution 1:
In PowerShell version 3.0 and newer this is simply done this way:
Get-ChildItem -Path $sourceDir | Copy-Item -Destination $targetDir -Recurse -Container
Reference: Get-ChildItem
Solution 2:
PowerShell:
$sourceDir = 'c:\folderA\folderB\folderC\client1\f1'
$targetDir = ' c:\tmp\'
Get-ChildItem $sourceDir -filter "*" -recurse | `
foreach{
$targetFile = $targetDir + $_.FullName.SubString($sourceDir.Length);
New-Item -ItemType File -Path $targetFile -Force;
Copy-Item $_.FullName -destination $targetFile
}
Note:
- The -filter "*" does not do anything. It is just here to illustrate if you want to copy some specific files. E.g. all *.config files.
- Still have to call a New-Item with
-Force
to actually create the folder structure.
Solution 3:
I have been digging around and found a lot of solutions to this issue, all being some alteration, not just a straight copy-item command. Granted, some of these questions predate PowerShell 3.0 so the answers are not wrong, but using PowerShell 3.0 I was finally able to accomplish this using the -Container
switch for Copy-Item:
Copy-Item $from $to -Recurse -Container
This was the test I ran, no errors and the destination folder represented the same folder structure:
New-Item -ItemType dir -Name test_copy
New-Item -ItemType dir -Name test_copy\folder1
New-Item -ItemType file -Name test_copy\folder1\test.txt
# NOTE: with no \ at the end of the destination, the file
# is created in the root of the destination, and
# it does not create the folder1 container
#Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2 -Recurse -Container
# If the destination does not exist, this created the
# matching folder structure and file with no errors
Copy-Item D:\tmp\test_copy\* D:\tmp\test_copy2\ -Recurse -Container