Grandfather-Father-Son Backup

by FloydTheDuck at 2013-03-25 08:51:33

Hello,I’m very new to Powershell and the subtitle for this forum said n00b’s welcome - so here I am :slight_smile: (and I won’t apologize since rule number 3 says not to :wink: )

My past experience has always been finding scripts (VB or, at my new job, Powershell) online and then modifying them to meet my needs. However, my current task is to setup a weekly script to do a Grandfather-Father-Son backup and Google searches have turned me up with few results. Here’s the setup:

IFS/Oracle Database (on Windows 2k8) has a hot backup every morning at 0430 to a iSCSI SAN. This SAN is then replicated across a WAN. What we would like is to retain 3 quarters, 3 month end, and 3 weeks of these backups. So, in essence, at the end of January 2013, we would have:
(3 quarters) — March 31st 2012, June 30th 2012, Sept 30th 2012
(3 months) — Oct 31st 2012, Nov 30th 2012, Dec 2012
(3 weeks) — Jan 5, 12, and 19 of 2013 (the first 3 Saturdays, as the last will likely be close to the EOM)

I’ve seen a bit online about finding the last days in a month, with syntax such as:

$Dayname = "Friday"
$LastDayOfMonth = (Get-Date -Year (Get-Date).Year -Month (Get-Date).Month -Day 1).AddMonths(1).AddDays(-1)
If($LastDayOfMonth.DayOfWeek -eq $DayName)
{
$Answer = $LastDayOfMonth
} #End If
Else {
While($Answer -eq $Null)
{
$LastDayOfMonth = $LastDayOfMonth.AddDays(-1)
If($LastDayOfMonth.DayOfWeek -eq $DayName)
{
$Answer = $LastDayOfMonth
} #End If
}#End While
}#End Else


We will likely have a second SAN that this script will replicate to before going across the WAN. So, once this script is implemented, it will be something like:
Database->Hot backup SAN->GF-F-S backup to other local SAN->Mirror/replicated to SAN off-site

Any help with this is hugely appreciated. I know there are "a dozen ways to skin a cat", I’m just looking to make an efficient script that won’t end up being buggy due to poor coding (if done by me). I didn’t provide all the details of server names/UNC paths, etc because I don’t expect anyone to do all the work, I just need help with the foundation/template and a kind explanation of how/why to use X command over Y command.

Thanks so much!
by DonJ at 2013-03-25 08:55:48
So… where are we starting? I’m not at all familiar with the tech you’re using, so are we just talking about a file copy based on date-based filenames or something?
by FloydTheDuck at 2013-03-25 10:37:38
[quote="DonJ"]So… where are we starting? I’m not at all familiar with the tech you’re using, so are we just talking about a file copy based on date-based filenames or something?[/quote]

Yes, sorry, I was afraid I may not have given enough info. This is fully Windows-based (as the SAN’s are iSCSI, so it’s just another drive letter as far as Windows is concerned).

The current hot-backup script just does a robocopy to mirror c:\orabatch to z:\Recovery\orabatch
I need to then do the GF-F-S backup mentioned above, retaining only the last 3 end-of-quarters, 3 end-of-months, and 3 end-of-weeks.

So I guess somehow the files need to be recognized by date (can Powershell see the file access times?) or maybe be moved to a folder for each month, so when it runs the weekly or monthly, it would be put in March… then next month would be in April, with Week1, week2, etc. tagged to the end.

I’m not sure the best way to go about this or the full capabilities of Powershell, so I’m not sure what can or cannot be done.
by DonJ at 2013-03-25 10:44:28
PowerShell can see LastWritten and stuff - run Dir | GM to see what it knows. So, then Get-Date is your key - run Get-Date | Gm and you’ll see its options for adding/subtracting time periods. That’ll let you construct a date in the past, and from there you can access pieces of the date to construct your filename. If you can show me an example filename, I can help you put something together.
by FloydTheDuck at 2013-03-25 11:00:31
[quote="DonJ"]… If you can show me an example filename, I can help you put something together.[/quote]

"Z:\IFS Recovery\oradata_hot\LIVE\BACKUPSET\2013_03_25\O1_MF_NNNDF_%TAG_8NZYCW28_.BKP"
by DonJ at 2013-03-25 11:18:54
Ok. So…


$olddate = (Get-Date).AddDays(-90)
$folder = "{0}{1}{2}" -f $olddate.year,$olddate.month,$olddate.day


Would give you that folder name for 90 days ago. I prefer AddDays() because it knows how to account for leap year and all that. You can build that into a path:

$path = "Z:\IFS Recovery\oradata_hot\LIVE\BACKUPSET$folder"

And then use Get-ChildItem to get a list of files in that folder, or even just pass that path to Robocopy or whatever.
by MasterOfTheHat at 2013-03-25 11:55:11
So, a couple of assumptions:
[list][]You don’t have any special backup types configured, (incremental, differential, etc), and each of the daily backups is therefore a full backup [/][]Your monthly and quarterly backups will just be one of those daily backups [/][]You aren’t trying to do the SAN-to-SAN replication via posh [/][/list]

If that’s the case, all you are really doing is file moving/copying and cleanup. Right?
by FloydTheDuck at 2013-03-25 12:34:36
[quote="MasterOfTheHat"]So, a couple of assumptions:
[list][]You don’t have any special backup types configured, (incremental, differential, etc), and each of the daily backups is therefore a full backup [/][]Your monthly and quarterly backups will just be one of those daily backups [/][]You aren’t trying to do the SAN-to-SAN replication via posh [/][/list]

If that’s the case, all you are really doing is file moving/copying and cleanup. Right?[/quote]

All of the above is correct.
by FloydTheDuck at 2013-04-01 10:02:15
I’m still a bit confused on the best way to design this.

I’m thinking:
1. Run the GFFS backup each Saturday
2. The script will backup to a weekly folder and will delete any backups older than 3 weeks
3. If it is the last Saturday of the month, it will set the destination to a folder such as \GFFS-Backup$month
4.Then, if a $month folder is older than 90 days and is not March, June, September, or December (end of quarter) then it will be deleted.

Will this design work? Or is it inefficient?
Also, DonJ mentioned something about a preference in syntax due to leap year, etc. Is there something wrong with the below (doing what I mentioned above)

#Will be used to backup every Saturday
$today = (Get-Date)
$folderbackup = "{0}{1}{2}" -f $today.year,$today.month,$today.day
$pathbackup = "C:\IFS Recovery\oradata_hot\LIVE\BACKUPSET$folderbackup"
#Run a backup script to $pathbackup
#Will be used to archive old folders
$olddate = (Get-Date).AddDays(-28)
#using Get-ChildItem properties, see if a folder is older than $olddate and delete if true
#
#If its the end of the month, backup to the GFFS monthly folder
$Dayname = "Saturday"
$LastDayOfMonth = (Get-Date -Year (Get-Date).Year -Month (Get-Date).Month -Day 1).AddMonths(1).AddDays(-1)
If($LastDayOfMonth.DayOfWeek -eq $DayName)
{
$Answer = $LastDayOfMonth
} #End If
Else {
While($Answer -eq $Null)
{
$LastDayOfMonth = $LastDayOfMonth.AddDays(-1)
If($LastDayOfMonth.DayOfWeek -eq $DayName)
{
$Answer = $LastDayOfMonth
} #End If
}#End While
}#End Else

#Get Today’s date and do some date formatting
$Date = ((get-date).ToShortDateString())
$LastSaturday = ($Answer.date)

#If Today’s date is the last Saturday of the month, put the backup in the GFFS backup folder
If ($Date -ge $LastSaturday){
#run a script here to move the backup to X:\GFFS-backup$month
} #End If