Reputation: 117
During repetitive logs collection on my internal system, found strange behavior of recursive Copy-Item call
Say, i have C:\Source with some files and subfolders with files. I want to copy this recursively to C:\Target. For first time all source will be copied recursively to C:\Target
The problem happens when i try to copy "C:\Source" to "C:\Target" for second time. In this case will "C:\Source" will be copied to "C:\Target\Source"
For example:
cls
if(Test-Path "C:\Target")
{
Remove-Item "C:\Target"
}
Copy-Item "C:\Source" "C:\Target" -Force -Recurse | Out-Null
DIR "C:\Target"
Write-Host "OK"
Write-Host " "
Write-Host " "
Copy-Item "C:\Source" "C:\Target" -Force -Recurse | Out-Null
DIR "C:\Target"
Write-Host "Not OK"
Script output:
Directory: C:\Target
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 4/11/2016 3:45 PM SampleSourceFolderLevel1
-a--- 4/11/2016 3:35 PM 0 SampleFileLevel0.txt
OK
d---- 4/11/2016 3:45 PM SampleSourceFolderLevel1
d---- 4/11/2016 3:45 PM Source
-a--- 4/11/2016 3:35 PM 0 SampleFileLevel0.txt
Not OK
Any idea how can i make Copy-Item to work like
ROBOCOPY $sourceLog $targetLog /E | Out-Null
??
Thanks in advance
Upvotes: 4
Views: 2020
Reputation: 8047
Copy-Item
has inconsistent behaviour based on the fact if the destination exist or not.
If you want to have a consistent copy experience, use this pattern:
$copyFrom = 'C:\Foo\Bar\TargetDirectoryToCopy'
$destinationPath = 'D:\Bar\Foo\'
$newItemParams = @{
Path = $destinationPath
ItemType = 'Directory'
Force = $True
}
$copyParams = @{
Path = $copyFrom
Destination = $destinationPath
Recurse = $True
Confirm = $false
Force = $True
}
New-Item @newItemParams
Copy-Item @copyParams
The directory D:\Bar\Foo\
will have TargetDirectoryToCopy
directory nested inside.
So if there is a file C:\Foo\Bar\TargetDirectoryToCopy\FooBar.txt
, its copy will be created as D:\Bar\Foo\TargetDirectoryToCopy\FooBar.txt
along with any another file in C:\Foo\Bar\TargetDirectoryToCopy
Upvotes: 0
Reputation: 58931
Seems like you want to copy the content of c:\Source
. You just need to add \*
:
Copy-Item -Path "C:\Source\*" -Destination "C:\Target" -Force -Recurse | Out-Null
It works for the first run because you delete the target folder and the cmdlet now copies the folder C:\Source
to C:\Target
. If C:\Target
exists, the cmdlet will copy the source into the Target folder.
Upvotes: 4