Reputation: 1463
I have a script which moves files with a specific extension from a source directory to a destination directory.
My source directory looks like:
FILESFOLDER
File1.td
File2.td
SUBFOLDER
File3.td
File4.td
My script is short and looks like:
if(!(Test-Path $SourceDirPath) -or !(Test-Path $DestinationDirPath))
{
Write-Host "The source- or destination path is incorrect, please check "
break
}else
{
Write-Host "Success"
Copy-Item -path $SourceDirPath -Filter "*$extension" -Destination $DestinationDirPath -Recurse
}
I have to mention that the $SourceDirPath
comes from a config file and only works if I declare it as C:\FILESFOLDER\*
The script works but doesn't copy the files from the subfolder to destination. The destination only has File1 and File2.
What's wrong with my Copy-Item command?
Upvotes: 2
Views: 4430
Reputation: 443
So this will compare the directory source versus the destination and then copy over the content. Ignore my funky variables, I've amended them below on a edit
#Release folder
$Source = ""
#Local folder
$Destination = ""
#Find all the objects in the release
get-childitem $Source -Recurse | foreach {
$SrcFile = $_.FullName
$SrcHash = Get-FileHash -Path $SrcFile -Algorithm MD5 # Obtain hash
$DestFile = $_.Fullname -replace [RegEx]::escape($Source),$Destination #Escape the hash
Write-Host "comparing $SrcFile to $DestFile" -ForegroundColor Yellow
if (Test-Path $DestFile)
{
#Check the hash sum of the file copied
$DestHash = Get-FileHash -Path $DestFile -Algorithm MD5
#compare them up
if ($SrcHash.hash -ne $DestHash.hash) {
Write-Warning "$SrcFile and $DestFile Files don't match!"
Write-Warning "Copying $SrcFile to $DestFile "
Copy-Item $SrcFile -Destination $DestFile -Force
}
else {
Write-Host "$SrcFile and $DestFile Files Match" -ForegroundColor
Green
}
}
else {
Write-host "$SrcFile is missing! Copying in" -ForegroundColor Red
Copy-Item $SrcFile -Destination $DestFile -Force
}
}
Upvotes: 1
Reputation: 1726
Try this:
$source = "C:\Folder1"
$destination = "C:\Folder2"
$allfiles = Get-ChildItem -Path $source -Recurse -Filter "*$extension"
foreach ($file in $allfiles){
if (test-path ($file.FullName.replace($source,$destination))) {
Write-Output "Seccess"
Copy-Item -path $file.FullName -Destination ($file.FullName.replace($source,$destination))
}
else {
Write-Output "The source- or destination path is incorrect, please check "
break
}
}
Upvotes: 1
Reputation: 440317
The -Recurse
switch has no effect in your case, because it's only applied to the items matched by the combination of $SourceDirPath
, which uses a trailing \*
to match the items in the source directory, and -Filter
, which in your case are only the *.td
files located directly in your source directory.
Omitting the trailing \*
to target the directory itself (e.g., C:\FOLDER
rather than C:\FOLDER\*
), solves that problem in principle, but, due to an annoying quirk only works as intended if the destination directory does not exist yet.
If it does exist, the items are placed in a subdirectory of the destination directory, named for the source directory.
If there's nothing in the existing destination directory to preserve before copying (and no special attributes of directory itself need preserving, you can work around the problem by deleting the preexisting destination directory beforehand.
if(!(Test-Path $SourceDirPath) -or !(Test-Path $DestinationDirPath))
{
Write-Host "The source or destination path is incorrect, please check "
break
}
else
{
Write-Host "Success"
# Delete the preexisting destination directory,
# which is required for the Copy-Item command to work as intended.
# BE SURE THAT IT IS OK TO DO THIS.
Remove-Item $DestinationDirPath -Recurse
# Note: $SourceDirPath must NOT end in \*
Copy-Item -Recurse -LiteralPath $SourceDirPath -Filter "*$extension" -Destination $DestinationDirPath
}
If you do need to preserve existing $DestinationDirPath
content or attributes (ACLs, ...), more work is needed.
Upvotes: 4
Reputation: 59021
You should use the Get-ChildItem
cmdlet with the -recurse
parameter to retrieve all files based on your filter condition. Then you can pipe the result to the Copy-Item
cmdlet and only have to specify a destination.
Upvotes: 1