Forum Discussion
.ps1 script: how to loop in a range of dates
- Dec 12, 2022
Just tested this script, this works:
foreach ($folder in Get-ChildItem -Path c:\mypath -Directory | Sort-Object Name) { try { Test-Path "$($folder.fullname)\myfolder1" -ErrorAction Stop | Out-Null Copy-Item "$($folder.fullname)\myfolder1" -Recurse -Destination C:\destpath\myfolder1 -Force:$true -Confirm:$false -ErrorAction Stop Write-Host ("Processing {0}" -f $folder.fullname) -ForegroundColor Green } catch { Write-Warning ("Folder myfolder1 not found in {0} or not enough permissions" -f $folder.FullName) } }Source directory:
Destination directory:It will check permissions and copy if it has permissions and will overwrite if the file is already present, it will show a warning if the folder1 folder was not found in a directory.
You can test it for yourself with a test directory structure 🙂
but I guess that I have so many folders when recurse and I think it spends a lot to recurse on them.
Since I try this (and it is stuck after the first 3 warnings, but yet not printed the folders, the fourth warning):
$sourcepath = 'C:\MyPath'
$myfolder1 = 'a\b\c\myfolder1'
$destinationpath = 'C:\DestPath\myfolder1'
Write-Warning ($sourcepath)
Write-Warning ($myfolder1)
Write-Warning ($destinationpath)
$folders = Get-ChildItem -Path $sourcepath -Directory -Recurse
Write-Warning ($folders)
foreach ($folder in $folders | Sort-Object Name) {
Write-Warning ("$($folder.fullname)\$($myfolder1)" -f $folder.FullName)
try {
Test-Path "$($folder.fullname)\$($myfolder1)" -ErrorAction Stop | Out-Null
foreach ($file in Get-ChildItem -Path "$($folder.fullname)\$($myfolder1)" -Recurse -File) {
if (Test-Path -Path "$($destinationpath)\$($file.name)") {
$destinationfile = Get-ChildItem -Path "$($destinationpath)\$($file.Name)"
if ($file.LastWriteTime -gt $destinationfile.LastWriteTime) {
Copy-Item $file.FullName -Destination $destinationpath -Force:$true -Confirm:$false -ErrorAction Stop
Write-Host ("Processing {0} in {1} and overwriting old version" -f $file.name, $folder.fullname) -ForegroundColor Green
}
else {
Write-Host ("File {0} from {1} already present in {2}, no change needed" -f $file.Name, $folder.Name, $destinationpath) -ForegroundColor Green
}
}
else {
Copy-Item $file.FullName -Destination $destinationpath -ErrorAction Stop
Write-Host ("Copying new file {0} from {1} to {2}" -f $file.name, $folder.fullname, $destinationpath) -ForegroundColor Green
}
}
}
catch {
Write-Warning ("Folder $myfolder1 not found in {0} or not enough permissions" -f $folder.FullName)
}
}
marco69 Did another test, and changed the script a little bit again:
$sourcepath = 'C:\MyPath'
$destinationpath = 'C:\DestPath\myfolder1'
$myfolder1 = 'Test\Test2'
foreach ($folder in Get-ChildItem -Path $sourcepath -Directory) {
try {
if (Test-Path "$($folder.fullname)\$($myfolder1)" -ErrorAction Stop) {
foreach ($file in Get-ChildItem -Path "$($folder.fullname)\$($myfolder1)" -Recurse -File) {
if (Test-Path -Path "$($destinationpath)\$($file.name)") {
$destinationfile = Get-ChildItem -Path "$($destinationpath)\$($file.Name)"
if ($file.LastWriteTime -gt $destinationfile.LastWriteTime) {
Copy-Item $file.FullName -Destination $destinationpath -Force:$true -Confirm:$false -ErrorAction Stop
Write-Host ("Processing {0} from {1} and overwriting old version" -f $file.name, "$($folder.FullName)\$($myfolder1)") -ForegroundColor Green
}
else {
Write-Host ("File {0} from {1} already present in {2}, no change needed" -f $file.Name, "$($folder.FullName)\$($myfolder1)", $destinationpath) -ForegroundColor Green
}
}
else {
Copy-Item $file.FullName -Destination $destinationpath -ErrorAction Stop
Write-Host ("Copying new file {0} from {1} to {2}" -f $file.name, "$($folder.FullName)\$($myfolder1)", $destinationpath) -ForegroundColor Green
}
}
}
else {
Write-Warning ("Folder {0} was not found in {1}" -f $myfolder1, $folder.FullName)
}
}
catch {
Write-Warning ("Folder {0} not found in {1} or not enough permissions" -f $myfolder, $folder.FullName)
}
}
In my case, it looks for a subdirectory pattern specified in the $myfolder1 variable, 'Test\Test2'. It does that in the directory that is defined as $sourcepath. So, c:\mypath\20220421\Test\Test2 is processed with all files beneath that path including one in subdirectories below that. And c:\mypath\20220422\test\blabla is not.
- Dec 13, 2022Yes 🙂 Good to hear!
- marco69Dec 13, 2022Copper Contributorthank you so much my friend!
for your patience, kindness and a huge huge proficiency!!!
cheers! - marco69Dec 13, 2022Copper Contributor
HiHarm_Veenstra , we got it!!!
I took the very first version and a little bit arranged, this is the very final version, it work fine!!!
$sourcepath = 'C:\MyPath' $myfolder1 = 'a\b\c\myfolder1' $destinationpath = 'C:\DestPath\myfolder1' Write-Warning ($sourcepath) Write-Warning ($myfolder1) Write-Warning ($destinationpath) $folders = Get-ChildItem -Path $sourcepath -Directory foreach ($folder in $folders | Sort-Object Name) { if (Test-Path "$($folder.fullname)\$($myfolder1)") { Write-Warning ("Processing file: $($folder.fullname)\$($myfolder1)" -f $folder.FullName) Write-Warning ("To be copied to: $($destinationpath)\$($myfolder1)" -f $folder.FullName) robocopy2.exe "$($folder.fullname)\$($myfolder1)" "$($destinationpath)\$($myfolder1)" /S /XO /LOG+:"$($destinationpath)\robocopy.log" /R:1 /W:1 } else { Write-Warning ("Folder {0} not found in {1} or not enough permissions" -f $myfolder1, $folder.FullName) } } - Dec 13, 2022😄 Let me know, give me some likes on my comments and mark it as a solution if it's solved will be enough 😛
- marco69Dec 13, 2022Copper ContributorEXCELLENT!!!!
in the afternoon I wll try soon
thank you again!!!
let you know
you have a wagon of beers (or whatever you want) for you approaching!!!! - Dec 13, 2022
marco69 ok 🙂 A light version using Robocopy mirrors the directories if the $myfolder1 pattern is found, copies changes files and removes files from the destination path if it's also deleted in the source path. Logfile is in c:\destpath\robocopy.log
$sourcepath = 'C:\MyPath' $destinationpath = 'C:\DestPath' $myfolder1 = 'Test\Test2' foreach ($folder in Get-ChildItem -Path $sourcepath -Directory) { if (Test-Path "$($folder.fullname)\$($myfolder1)") { robocopy.exe "$($folder.fullname)\$($myfolder1)" "$($destinationpath)\$($folder.name)\$($myfolder1)" /mir /log+:"$($destinationpath)\robocopy.log" /X /TEE /FP /R:1 /W:1 } else { Write-Warning ("Folder {0} not found in {1} or not enough permissions" -f $myfolder1, $folder.FullName) } }It shows the status on the screen, you can change/check the robocopy parameters if needed (Check them using robocopy /? in a command-prompt or on the website.
- marco69Dec 13, 2022Copper Contributor
excuse me Harm, you are right
do you think it's possible to keep the source tree?
the very first version kept the tree (the only change to do there is to take the newest files and new ones) - Dec 13, 2022
It does copy everything in the root of the destpath without creating directories.. "into one folder destination." That's what you asked 😛
- marco69Dec 13, 2022Copper Contributoryes, just tried and it seems working, but this last version doesn't create the tree, it copies everything into the destpath...
I'm still waiting for the fourth log 🙂
I really think it's creating the folders list, if so it should work
I let it running and let you know