Reputation: 3162
I have a folder contains a lots of files created over the years. Lets call it folder A, in Folder A i have files created on 2012,2013,2014 and so on, files will continuously created in this folder. There is no structure under Folder A, just bunch of files.
Task1:
Now I have to make a copy of those files based on month and year, I have a folder B, in this Folder B, First I d like to have a level by year, then under each year, I will have folders by month, so all the files from Folder A will be copied into each location in folder B based on their date of Creation.
--B
---2013
--------Jan
--------Feb
--------Mar
---2014
--------Jan
--------Feb
--------Mar
.......
Task2:
This script will be scheduled 3 times per day, each time when it runs, it has to compare "last modify date" between source and destination, if "last modify date" on source is newer than destination, then copy the modified file to destination with "original name + modified date" as new file name. Skip if the files remain untouched.
Upvotes: 0
Views: 3143
Reputation: 2281
Ok, this has been reworked. It is the most efficient way I can think to do this with this technology.
$indexFilePath = "C:\Folder B\FileUpdateTracker.Json"
if ((Test-Path -Path $indexFilePath) -eq $false)
{
[psobject]@{
LastUpdate = [datetime]::MinValue.Date;
} | ConvertTo-Json | Out-File -FilePath $indexFilePath -NoClobber
}
$oldFileIndex = Get-Content -Path $indexFilePath | ConvertFrom-Json
$testFiles = @(Get-ChildItem -Path "C:\Folder A" | Where { $_.LastWriteTime.Date -ge $oldFileIndex.LastUpdate })
if ($testFiles.Count -eq 0)
{
return
}
$fileIndex = [psobject]@{
LastUpdate = (Get-Date).Date;
}
foreach ($file in $testFiles)
{
$year = $file.CreationTime.Year
$month = $file.CreationTime.ToString("MMM")
$archivePath = "C:\Folder B\$year\$month"
mkdir -Path $archivePath -ErrorAction SilentlyContinue
$copiedFileName = $null
if ((Test-Path "$archivePath\$($file.Name)") -and $file.LastWriteTime.Date -ge $oldFileIndex.LastUpdate)
{
$copiedFileName = "$archivePath\$($file.Name.Replace($file.Extension, "_$($file.LastWriteTime.ToString("MM-dd-yy_hh-mm"))$($file.Extension)"))"
}else{
$copiedFileName = "$archivePath\$($file.Name)"
}
Copy-Item -Path ($file.FullName) -Destination $copiedFileName
}
$fileIndex | ConvertTo-Json | Out-File -FilePath $indexFilePath -Force
Upvotes: 0
Reputation: 1244
Another way is to use BitsTransfer.
$dirA = "C:\Test\A"
$dirB = "C:\Test\B"
$params = Get-ChildItem $dirA -File | foreach {
$destFile = [IO.FileInfo]("{0}\{1:yyyy}\{1:MMM}\{2}_{3:yyyyMMddhhmmss}{4}" -f $dirB,$_.CreationTime,$_.BaseName,$_.LastWriteTime,$_.Extension)
if($destFile.Exists) { return }
$destFile.Directory.Create()
@{ Src = $_.FullName; Dest = $destFile.FullName }
}
if(!$params) { return }
Start-BitsTransfer -Source $params.Src -Destination $params.Dest -DisplayName "Backup"
Upvotes: 0
Reputation:
The most effecient method is IMO
## Q:\Test\2019\04\22\SO_55798207.ps1
$Source = "X:\FolderA"
$Target = "Y:\FolderB"
Push-Location $Source
Get-ChildItem $Source -File |
Select-Object *,@{n='YearMonth';e={$_.CreationTime.ToString('yyyy\\MMM')}} |
Group-Object YearMonth | ForEach-Object {
$NewFolder = Join-Path $Target $_.Name
If (!(Test-Path $NewFolder)){New-Item $NewFolder -ItemType Directory|Out-Null}
$_.Group | Copy-Item -Destination $NewFolder
}
Pop-Location
Upvotes: 1
Reputation: 396
This should fullfil your request:
$Files = Get-ChildItem -Path "C:\FolderA"
Foreach ($File in $Files) {
$File | Copy-Item -Destination "C:\FolderB\$( $File.LastWriteTime.Year )\$( $File.LastWriteTime.ToString("MMM") )"
}
Upvotes: 0