Monday, June 15, 2015

Schedule Full and Incremental Content Backups using PowerShell Extensions

Standard
During my studies in University, and working for a smaller company in the past where I was involved in the hardware side of the IT world,  I discovered the power of command-line scripts when automating daily tasks such as server backups.

Looking back at late 2006, when Microsoft first introduced PowerShell,  they gave us a more advanced command-line interface where we could do some really fancy stuff. There was a new syntax we had to learn, but with enough time, it was as familiar as the good old MS-DOS prompt.



Enter Sitecore PowerShell Extensions

Having been in the Sitecore world for quite some time, I was excited to find Sitecore PowerShell Extensions on the marketplace.

As Alistair Deneys put it at the 2012 Symposium:
"There is nothing you can not do with PowerShell Console, because you're inside the Sitecore application. You can call the Sitecore API"

I have been using the module religiously for the past year, and am truly impressed by the work of the contributors.

If you know a little PowerShell, and haven't tried it before, I suggest you download and give it a bash.

This post assumes that you have the module installed. As I am running XP 8.0 Update 2, I installed version 3.0 in my instance.

The Use Case

As I mentioned in an earlier post, one of the projects that I am working on involves building out a couple new sites that have an E-Commerce back end that supports thousands of products that we are integrating into Sitecore via Commerce Connect.

One of the features that the client requested was the ability to perform batch product updates using Microsoft Excel. We ended up building an admin app where they could export and import CSV files and manipulate the content within Sitecore, using the data within these files. Our tree structure looks like this:

You may already be thinking that this sounds like trouble, and trust me, we had the same thoughts.

Wouldn't it be nice if we could have an automated daily backup strategy that would enable us to revert to a backup set relatively quickly in case something went wrong? Just like a server backup script?

PowerShell Backup Scripts

After doing some research and testing, I formulated the following scripts that create either a full or incremental package of all the items in the Master database that are located at this path in the content tree: "/sitecore/content/Data/Product-Repository/Products". You can modify this path to suite your needs.

Full Backup Script

 $packageBackupName = "Client Products Full Package Backup";  
 $sourceItems = Get-ChildItem -Path "master:\sitecore\content\Data\Product-Repository\Products"  
 $package = new-package $packageBackupName;  
 $package.Sources.Clear();  
 Write-Log "$packageBackupName started";  
 $Author = [Sitecore.Context]::User.Profile.FullName;  
 $Publisher = [Sitecore.SecurityModel.License.License]::Licensee  
 $DayOfWeek = [datetime]::Now.DayofWeek  
 $package.Metadata.Author = $Author;  
 $package.Metadata.Publisher = $Publisher;  
 $package.Metadata.Version = "";  
 $package.Metadata.Readme = "";  
 $packageSource = $sourceItems | New-ItemSource -Name "Content Source" -InstallMode Overwrite -MergeMode Merge  
 $package.Sources.Add($packageSource);  
 Export-Package -Project $package -Path "$packageBackupName-$DayOfWeek" -Zip  
 Write-Log "$packageBackupName completed"  

Incremental Backup Script

Note: This script will generate a package of items located under the target path that have been added or changed within the last 2 days. You can modify this day value by changing the "$changedDays" variable below.

 $packageBackupName = "Client Products Incremental Package Backup";  
 $changedDays = 2;  
 $sourceItems = Get-ChildItem -Recurse -Path "master:\sitecore\content\Data\Product-Repository\Products" | Where-Object  { $_."__Updated" -gt (Get-Date).AddDays(-$changedDays) -or $_."__Created" -gt (Get-Date).AddDays(-$changedDays)}  
 $package = new-package $packageBackupName;  
 $package.Sources.Clear();  
 Write-Log "$packageBackupName started";  
 $Author = [Sitecore.Context]::User.Profile.FullName;  
 $Publisher = [Sitecore.SecurityModel.License.License]::Licensee  
 $DayOfWeek = [datetime]::Now.DayofWeek  
 $package.Metadata.Author = $Author;  
 $package.Metadata.Publisher = $Publisher;  
 $package.Metadata.Version = "";  
 $package.Metadata.Readme = "";  
 $packageSource = $sourceItems | New-ItemSource -Name "Content Source" -InstallMode Overwrite -MergeMode Merge  
 $package.Sources.Add($packageSource);  
 Export-Package -Project $package -Path "$packageBackupName-$DayOfWeek" -Zip  
 Write-Log "$packageBackupName completed"  

Running Scripts and Package Default Location



Setting up Scheduled Tasks

You can certainly run these scripts on demand to create packages, but the real magic would be to let these scripts run on a schedule so that once they are set up, they would take care of themselves.

This can be achieved within a few simple steps:

1. Navigate to /sitecore/system/Modules/PowerShell/Script Library/Task Management/Tasks and create a new Powershell Script Library item, that will contain your 2 scripts. I called mine "Content Backups".

2. Within this new script library item, create 2 new PowerShell Script items, and paste in each respective PowerShell script. I called my items "Full Product Backup" and "Incremental Product Backup".



3. Navigate to "/sitecore/system/Tasks/Schedules" and create a Schedule Item to invoke the scripts housed in the Items above. To learn more about Sitecore Scheduled Tasks, please see John West‘s post discussing them).

  3.1 Set the command to "Commands/PowerShellScriptCommands"
  3.2 Set items to the location of your PowerShell Script Item for each script that you created in step
2.
  3.3 Set the schedule item to your preferred value.




I set my Full Backup to ||1|13.00:00 so that it will run once on Sunday and the interval will be 13 hours, so it will only be executed once within the day.

I set my Incremental Backup to ||126|13.00:00 so that it will run Monday - Saturday, once during the day (same as above).

Reviewing and Testing your Scheduled Tasks

Checking that you set up everything correctly and testing it out is easy. Simply open up the Task Manager within the PowerShell Toolbox:



Once launched, you can review the scheduled tasks that you set up. To test either of them, click on the item and then click the "Execute Now" button.





2 comments:

  1. Wonderful use case for creating packages and running scheduled tasks in SPE. Keep it up! Also check out our book http://sitecorepowershell.gitbooks.io/sitecore-powershell-extensions/

    ReplyDelete
    Replies
    1. I appreciate you taking the time to check out my post Michael. I will make sure I check out your book. Like I mentioned in the post, I love what you guys have done with SPE! Cheers!

      Delete