PowerShell Script to Manipulate SQL Server Backup Files
Scenario
I use Ola Hallengren’s famous backup solution to back up my SQL Server databases. The destination for full backups is a directory on local disk; let’s say D:\SQLBackup\
If you are familiar with Ola’s backup scripts, you know the full path for backup file looks something like:
D:\SQLBackup\InstanceName\DatabaseName\FULL\InstanceName_DatabaseName_FULL_yyyymmdd_hhmiss.bak
Where InstanceName is a placeholder for the name of the SQL server instance, similarly, DatabaseName is for the Database Name.
Problem
Depending upon my retention period settings, I may have multiple copies of full backup files under the said directory. The directory structure is complicated too (backup file for each database is under two parent folders). I want to copy the latest backup file (only) for each database to a UNC share and rename the backup file scrubbing everything but the database name.
Let’s say the UNC path is \\RemoteServer\UNCBackup. The end result would have the latest full backup file for all the databases copied over to \\RemoteServer\UNCBackup with files containing their respective database names only.
Solution
I wrote a PowerShell script to achieve the solution. This script can be run from a PowerShell console or PowerShell ISE. The more convenient way would be to use PS subsystems and schedule a SQL Server agent job to run this PowerShell script. As always, please run this on a test system first and use at your own risk. You may want to tweak the script depending upon your requirement.
<#################################################################################
Script Name: CopyLatestBackupandRename.ps1
Author : Prashant Kumar
Date : March 29th, 2015
Description: The script is useful for those using Ola Hallengren’s backup solution.
This script takes SQL Server full backup parent folder as an input,
a remote UNC path as another input and copies the latest backup file
for each database, renames the backup file to the remote UNC path.
This Sample Code is provided for the purpose of illustration only and is not
intended to be used in a production environment. THIS SAMPLE CODE AND ANY
RELATED INFORMATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
##################################################################################>
#Clear screen
cls
#Specify Parent folder where Full backup files are originally being taken
$SourcePath = ‘D:\SQLBackup\InstanceName’
#Specify UNC path ot network share where backup files has to be copied
$UNCpath = ‘\\RemoteServer\UNCBackup’
#Browse thru subfolders (identical to database names) inside $SourcePath
$SubDirs = dir $SourcePath -Recurse | Where-Object {$_.PSIsContainer} | ForEach-Object -Process {$_.FullName}
#Browse through each sub-drorectory inside parent folder
ForEach ($Dirs in $SubDirs)
{
#List recent file (only one) within sub-directories
$RecentFile = dir $Dirs | Where-Object {!$_.PSIsContainer} | Sort-Object {$_.LastWriteTime} -Descending | Select-Object -First 1
#Perform operation on each file (listed above) one-by-one
ForEach ($File in $RecentFile)
{
$FilePath = $File.DirectoryName
$FileName = $File.Name
$FileToCopy=$FilePath+‘\’+$FileName
$PathToCopy=($filepath -replace [regex]::Escape($SourcePath), $UNCpath)+‘\’
#Forecfully create the desired directory structure at destination if one doesn’t exist
New-Item -ItemType Dir -Path $PathToCopy -Force
#Copy the backup file
Copy-Item $FileToCopy $PathToCopy
#Trim the date time from the copied file name, store in a variable
$DestinationFile = $PathToCopy+$FileName
$RenamedFile = ($DestinationFile.substring(0,$DestinationFile.length–20))+‘.bak’
#Rename the copied file
Rename-Item $DestinationFile $RenamedFile
}
}
Share this
You May Also Like
These Related Stories
No Comments Yet
Let us know what you think