Moving files/folders based on creation date and keeping folder structure - powershell

Windows 7 Pro environment.
I'm looking to create a batch or PowerShell script to move folders based on creation or last modified date.
The source folder is "D:\Video". The destination is "F:\DVRBackups\".
The requirement is that the folder structure be maintained, and that only folders older than a certain creation date are moved, whilst the others are left untouched.
The folder structure for the source folder looks like this:
D:\Video\Cam01\XXXX
D:\Video\Cam02\XXXX
D:\Video\Cam03\XXXX
..etc..
(XXX = hundreds of folders within the Cam01/02/03 folders spanning months)
The number of camera folders changes based on the computer DVR box i'm working on. Some locations have 5 cameras, some have as many as 35 (i.e., Cam01, Cam02, .., Cam35).
Folders from within the Cam01/02/03 folders need to be moved over to F:\DVRBackups, whilst maintaining the original folder structure.
i.e.
D:\Video\Cam01\0318 --> F:\DVRBackups\Video\Cam01\0318
D:\Video\Cam01\0319 --> F:\DVRBackups\Video\Cam01\0319
D:\Video\Cam02\0501 --> F:\DVRBackups\Video\Cam02\0501
..etc..
Can someone assist?

If it's just the folders within each CamXX folder that you need to check the Last modified time and them move. You can use the following in PowerShell.
$source = "D:\Video\"
$destination = "F:\DVRBackups\"
$date = Get-Date "25/03/2015 12:00"
dir $source | %{ dir $_.FullName | ?{ $_.LastWriteTime -gt $date } | Copy-Item -Destination $destination -Recurse -Force }
If you want to test what folders will be moved before hand use this command first.
dir $destination | %{ dir $_.FullName | ?{ $_.LastWriteTime -gt $date } | select LastWriteTime, FullName }
This will provide a list of the all folders that will have all there content moved.

Related

Excluding Parent Directory if Any File is New

My company has individual folders on a share for each project they are working on, and if no files inside one of those folders or its subfolders has been touched in the last six months, I want to move them to an archive location. If any one file within the folder or any of its subfolders have been modified in the last six months, I want to skip the entire parent directory. I'm most of the way there now, but my current iteration only skips the individual files, and I'm not sure how to specify skipping the entire parent. Here is my current script:
$Date = (Get-Date).AddMonths(-6)
$Source = 'C:\Scripts\Source'
$Dest = 'C:\Scripts\Test Target'
Get-ChildItem $Source -File -Recurse | Where {$_.LastWriteTime -lt $Date} | ForEach {
$actualSource = Split-Path $_.FullName
$actualDest = Split-Path $_.FullName.Replace($source,$dest)
robocopy $actualSource $actualDest $_.Name /SEC
}
When using my test directories, I have a folder C:\Scripts\Source\Drivers. The script copies that Drivers folder like I want it to, but if I put a newer file anywhere within that Drivers folder, I want the entire folder to be skipped. Currently, the folder and anything older than six months within the folder are still being copied, and it is just skipping the individual files which are newer.
Please let me know if any more information is needed.
Simply pull back your copy and recurse statement one level up. First you want to iterate through all the parent folders. Then for each parent folder, recurse and check to see if there is any modified files, if there is, then copy the folder:
$Date = (Get-Date).AddMonths(-6)
$Source = 'C:\Scripts\Source'
$Dest = 'C:\Scripts\Test Target'
$ParentFolders = Get-ChildItem $Source -Directory
Foreach($Folder in $ParentFolders){
$NewFiles = Get-ChildItem $Folder -File -Recurse | Where {$_.LastWriteTime -lt $Date}
if($NewFiles.Count -eq 0)
{
#Archive
robocopy $Folder $Dest /SEC
}
}

Copy file from directories with today's date to another location

AD Manager Plus generates reports hourly to a time stamped file path and I would like to copy these files to another location - overwriting the existing file. I will then schedule the script to run hourly after the files have been generated. Unfortunately the location the reports are extracted to cannot be modified and it creates date & time stamped folders.
Example:
C:\ADManager Plus\audit-data\reports\16042019\DailyTrue-Up01-55-07\Real Last Logon.xls
C:\ADManager Plus\audit-data\reports\ddmmyyyy\DailyTrue-Uphh-mm-ss\Real Last Logon.xls
I thought the easiest approach would be to:
Get the last modified folder in the Reports Folder - eg Apr162019
Get the last modified folder in the Apr162019 Folder - eg DailyTrue-Up01-55-07
Filter for the Real Last Logon.xls spreadsheet in folder DailyTrue-Up01-55-07
$Path = "C:\ADManager Plus\audit-data\reports"
$DestinationPath = "\\domain\networkshare\Reports\"
Get-ChildItem -Path $Path -Directory | ForEach-Object {
Get-ChildItem -Path "$Path\$_" -File -Filter "Real Last Logon.xlsx" |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1 |
Copy-Item -Force -Destination (New-Item -Force -Type Directory -Path (Join-Path $DestinationPath ($_.FullName.Replace("$Path\", ''))))
}
The code we have seems to copy all folders to the location and can't look in multiple directories.
I got a feeling we are approaching this wrong, Can anyone suggest the best way to achieve this? There are few posts online that explain how to retrieve files from time stamped folders.

Batch - Find and Move Folders Based on Folder Created Date

I'm trying to create a batch (or PowerShell) script that does the following:
Gets the current date (i.e. 06/21/2018)
Looks at all sub-folders in a specific folder (not recursively, just the immediate sub-folders) and finds all folders with a created date in the previous year, up to the current date in the previous year (i.e. 01/01/2017 - 06/21/2017).
Moves all of those folders to a '2017 Jobs' folder.
So I've been searching around for an answer to this question but everything seems to be focused around file dates, not folder dates, so here we are. I know how to use Robocopy to move the folders once found, but all of it's switches are based around moving files older than X date, not folders. Any ideas on how I can achieve a folder-based created date looping lookup?
Without building the entire script for you, here are your pieces:
$date = Get-Date
$dateAYearAgo = $date.AddYears(-1)
$items = Get-ChildItem "C:\base\folder" | Where-Object {$_.CreationTime -gt $start -and $_.CreationTime -lt $end}
$items | Move-Item "C:\base\folder\2017 Jobs"
As for filtering out just folders, you can see if the version of powershell you are on allows Get-ChildItem C:\ -Directory to pull only directories, or you can use Get-ChildItem C:\ | Where-Object { $_.PSIsContainer }

Move a files that have the same name but different extension. Powershell

I am a junior tech and have been tasked to write a short powershell script. The problem is that I have started to learn the PS 5 hours ago - once my boss told that I'm assigned to this task. I'm a bit worried it won't be completed for tomorrow so hope you guys can help me a bit. The task is:
I need to move the files to different folders depending on certain conditions, let me start from the he folder structure:
c:\LostFiles: This folder includes a long list of .mov, .jpg and .png files
c:\Media: This folder includes many subfolders withe media files and projects.
The job is to move files from c:\LostFiles to appropiate folders in c:\Media folder tree if
The name of the file from c:\LostFiles corresponds to a file name in one of the subfolders of the C:\media We must ignore the extension, for example:
C:\LostFiles has these files which we need to move (if possible) : imageFlower.png, videoMarch.mov, danceRock.bmp
C:\Media\Flowers\ has already this files: imageFlower.bmp, imageFlower.mov
imageFlower.png should be moved to this folder (C:\media\Flowers) because there is or there are files with exactly the same base name (extension must be ignored)
Only the files that have corresponding files (the same name) should be moved.
So far I have written this piece of code (I know it is not much but will be updating this code as I am working on it now (2145 GMT time). I know I missing some loops, hey yeah, I am missing a lot!
#This gets all the files from the folder
$orphans = gci -path C:\lostfiles\ -File | Select Basename
#This gets the list of files from all the folders
$Files = gci C:\media\ -Recurse -File | select Fullname
#So we can all the files and we check them 1 by 1
$orphans | ForEach-Object {
#variable that stores the name of the current file
$file = ($_.BaseName)
#path to copy the file, and then search for files with the same name but only take into the accont the base name
$path = $Files | where-object{$_ -eq $file}
#move the current file to the destination
move-item -path $_.fullname -destination $path -whatif
}
You could build a hashtable from the media files, then iterate through the lost files, looking to see if the lost file's name was in the hash. Something like:
# Create a hashtable with key = file basename and value = containing directory
$mediaFiles = #{}
Get-ChildItem -Recurse .\Media | ?{!$_.PsIsContainer} | Select-Object BaseName, DirectoryName |
ForEach-Object { $mediaFiles[$_.BaseName] = $_.DirectoryName }
# Look through lost files and if the lost file exists in the hash, then move it
Get-ChildItem -Recurse .\LostFiles | ?{!$_.PsIsContainer} |
ForEach-Object { if ($mediaFiles.ContainsKey($_.BaseName)) { Move-Item -whatif $_.FullName $mediaFiles[$_.BaseName] } }

Powershell Copy files and folders

I have a PS script which Zips up the previous months logs and names the zip file FILENAME-YYYY-MM.zip
This works
What I now want to do is copy these zip files off to a network share but keeping some of the folder structure. I currently a folder structure similar to the following;
C:\Folder1\
C:\Folder1\Folder2\
C:\Folder1\Folder3\
C:\Folder1\Folder4\Folder5\
There are .zip files in every folder below c:\Folder1
What I want is for the script to copy files from c:\folder1 to \\networkshare but keeping the folder structure, so I should have 3 folders and another subfolder in folder4.
Currently I can only get it to copy the whole structure so I get c:\folder1\... in my \\networkshare
I keep running into issues such as the new folder structure doesn't exist, I can't use the -recurse switch within the Get-ChildItem command etc...
The script I have so far is;
#This returns the date and formats it for you set value after AddMonths to set archive date -1 = last month
$LastWriteMonth = (Get-Date).AddMonths(-3).ToString('MM')
#Set destination for Zip Files
$DestinationLoc = "\\networkshare\LogArchive\$env:computername"
#Source files
$SourceFiles = Get-ChildItem C:\Sourcefiles\*.zip -Recurse | where-object {$_.lastwritetime.month -le $LastWriteMonth}
Copy-Item $SourceFiles -Destination $DestinationLoc\ZipFiles\
Remove-Item $SourceFiles
Sometimes, you just can't (easily) use a "pure PowerShell" solution. This is one of those times, and that's OK.
Robocopy will mirror directory structures, including any empty directories, and select your files (likely faster than a filter with get-childitem will). You can copy anything older than 90 days (about 3 months) like this:
robocopy C:\SourceFiles "\\networkshare\LogArchive\$($env:computername)\ZipFiles" /E /IS /MINAGE:90 *.zip
You can specify an actual date with /MINAGE too, if you have to be that precise.
How about Copy-Item "C:\SourceFiles\" -dest $DestinationLoc\ZipFiles -container -recurse? I have tested this and have found that it copies the folder structure intact. If you only need *.zip files, you first get them, then for each you call Resolve-Path with -Relative flag set and then add the resultant path into Destination parameter.
$oldloc=get-location
Set-Location "C:\SourceFiles\" # required for relative
$SourceFiles = Get-ChildItem C:\Sourcefiles\*.zip -Recurse | where-object {$_.lastwritetime.month -le $LastWriteMonth}
$SourceFiles | % {
$p=Resolve-Path $_.fullname -relative
copy-item $_ -destination "$DestinationLoc\ZipFiles\$p"
}
set-location $oldloc # return back