Batch - Find and Move Folders Based on Folder Created Date - powershell

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 }

Related

Powershell script to delete all files older than one day, in directories with specific words in the name

I need a script to search through a root directory (such as C:\inetpup\wwwroot\Listings) and find all subdirectories that have the word "ImageCache" in the directory name (such as 114WestImageCache, 214OakImageCache, etc), and then delete all files inside those directories that are more than thirty days old. The closest I've gotten so far is:
dir C:\inetpup\wwwroot\Listings\ | where {$_.name -ne 'ImageCache'}| Remove-Item -Recurse -force
But that also deletes everything (regardless of date) except the one directory named only "ImageCache". I want to leave the directories alone that don't have "ImageCache" in their name, and only delete the files inside the ImageCache directories that are older than 30 days. Can anybody help me out?
The following script will do it for you.
Get-ChildItem -Path "C:\inetpub\wwwroot\Listings" -Recurse -Force | ? { $_.DirectoryName -like "*ImageCache*" -and $_.CreationTime -lt (Get-Date).AddDays(-1)} | % { $_.Delete() }
The ? clause checks the DirectoryName against anything containing the string you are looking for. This will hit files also in subdirectories of the ImageCache directory as well, hopefully what you like. It also checks against a CreationTime less than the current date minus one day - that is, older than a day. The % then deletes all matches - remove that if you want to test this first.

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

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.

delete if 30days old by folder name

I am trying to delete all folders that are passed 30 days old but I need to base it off of the folder name instead of the creation date. Files get generated and put into a folder with the month on it and inside of it the Month date and year. The Month format is like this MM yyyy and month date like MMddyyyy. I had a script working in powershell v2 that worked well but stopped working in powershell V3.
This was my V2 script
function Delete-Folder-30days
$today = get-date -displayhint date
$30days = (get-date).AddDays(-30)
$folders = (gci "\\$args\Apps\AndrewTest" | where-object {$_.PSIsContainer -eq $True})
foreach ($f in $folders) {
$folderdate = get-date -mont $f.Name.substring(0,2) -day $f.Name.substring(2,2) -year $f.Name.substring(4,2)
if ($folderdate)
{
Remove-Item "\\$args\Apps\AndrewTest\$f" -recurse
}
}
}
Delete-Folder-30days $Server
What could i be doing wrong here?
Thanks,
Andrew
Try using the [DateTime]::ParseExact() method, it's much simpler for your purposes:
function Delete-Folder-30days{
gci "\\$args\Apps\AndrewTest" -Directory | ?{[datetime]::ParseExact($_.Name,"MMddyyyy",$null) -lt (get-date).AddDays(-30)} | Remove-Item -Recurse
}
Delete-Folder-30days $Server
Edit: Sorry! Had the String and Format switched (should be like ("04122014","MMddyyyy",$null)) but I had the first two arguments reversed.
Edit2: You want it to include .zip files as well? There's a couple of things. If you want to include all files then it is really simple. Just remove the -Directory from the GCI command and it will look at all files and folders in the target directory. If you ONLY want folders and .ZIP files then it gets a little more complicated. Basically we will still remove the -Directory switch, but we'll have to add some filtering into the Where clause as such:
?{($_.PSIsContainer -and [datetime]::ParseExact($_.Name,"MMddyyyy",$null) -lt (get-date).AddDays(-30)) -or ($_.Extension -ieq ".zip" -and [datetime]::ParseExact($_.BaseName,"MMddyyyy",$null) -lt (get-date).AddDays(-30))}
So now instead of just checking the specially formatted date, you are asking Is this a folder, or does it have the .zip file extension? If at least one of those two is true, does it match the specially formatted date?

Powershell - Delete subfolder(s) in folder with specific name(s) older than 30 days

stackoverflow,
I am trying to come up with a PoSh script to do a very specific task that has me beating my head against my desk here. I am pretty new to Powershell, and need some help here.
Here is what I am trying to accomplish:
I need to be able to search through a drive for a specific folder called "30 Day Toss" and delete any subfolder(s) inside of it that has a creationdate of over 30 days old.
Example:
P:\Project\2014\3D1004\Plan 1\30 Day Toss\Archive1
P:\Project\2014\3D1004\Plan 2\30 Day Toss\04-12-2014
The Archive1 folder above was created 10 days ago and doesn't need deleted.
The 04-12-2014 folder above was created over 30 days ago and needs deleted, along with all files/folders under it.
The Project, year, job number and plan number are all variable and change, so hard coding a search path isn't an option.
Any assistance would be greatly appricieated, thanks!
Ok, so assuming that your folder structure is always the same, and you always want the 6th level of folder or subfolders of that, this will work:
gci P:\ -directory -recurse | ?{$_.FullName -match ".:\\.+?\\.+?\\.+?\\.+?\\.+?\\" -and $_.CreationTime -lt (get-date).AddDays(-30)}|Remove-Item -recurse -whatif
That looks at the entire P: drive for folders, if the folder name is:
P:\<anything>\<anything>\<anything>\<anything>\<anything>\<anything>
It checks to see if it was created over 30 days ago, and if so it deletes it and all of it's contents. But it has to have that many levels for the script to look at it.
Edit: Ok, let's change it up a little. If the folder we're looking inside of is always called "30 Day Toss" we'll look for all folders with that name, and then pull a listing of things inside each of them. Easy enough! First, the code:
gci P:\ -Directory -Recurse | ?{$_.Name -ieq "30 Day Toss"} | %{GCI $_.FullName | ?{$_.CreationTime -lt (get-date).AddDays(-30)} | Remove-Item -Recurse -Force}
Then to break it down a little.
First we get a listing of all folders on the P: drive. Then we select only the ones named "30 day toss" (not case sensitive).
For each folder we find with that name we pull a directory listing for whatever is inside that folder, and then select only the things older than 30 days. For each of those things that are older than 30 days we delete them, and anything inside them.
$date = (get-date).AddDays(-30)
$folders = gci "p:\" -filter "30 Day Toss" -recurse
Foreach ($subfolder in $folders.FullName) { gci $subfolder | where {$_.psiscontainer} | where { $_.CreationTime -lt $date} | remove-item -force -recurse }

Find files only in subdirectories named OLD with a certain age using PowerShell

How can I get a nice list of files in a directory tree that contains multiple OLD Files?
I'd like to see only files from directories named OLD that have a certain age.
As I understand the question, Raoul Supercopter's solution doesn't quite answer it. Instead of finding all files from directories that are named "OLD" the solution above finds all files that contain "OLD" in their name.
Instead, I think you're asking for something that finds all files older than a certain date that are in directories named OLD.
So, to find the directories, we need something like the following:
dir -r | ? {$_.name -match "\bold\b" -and $_.PSIsContainer}
But you then need something that can recursively go through each directory and find the files (and, potentially, any directories named "OLD" that are contained in other directories named "OLD").
The easiest way to do this is to write a function and then call it recursively, but here's a way to do it on one line that takes a different tactic (note the line continuation character so this would fit:
dir -r | ? {!$_.PSIsContainer -and $_.LastWriteTime -lt (Get-Date 5/1/2006)} `
| ? {(% {$_.directoryname} | split-path -leaf) -eq "OLD"}
So, what's happening here?
The first section is just a basic recursive directory listing. The next section checks to be sure that you're looking at a file (!$_.PSIsContainer) and that it meets your age requirements. The parentheses around the Get-Date section let you get the results of running the command. Then we get the directory name of each file and use the split-path cmdlet to get just the name of the closest directory. If that is "OLD" then we have a file that matches your requirements.
Well, the first part is to list all the files, the second part filter your files, and finally format your output. You can use Format-List or table (but I don't have a PowerShell installation nearby to test it :])
$yourDate = Get-Date 5/1/2006
ls -recurse . | ? { $_.fullname -match "OLD" -and $_.lastwritetime -lt $yourDate } | % { $_.fullname }
Get-Date creates a Date-Time object when you give it a specific date as a parameter. Just use it and filter.