Backup SharePoint 2010 site collections with PowerShell, send alerts and much more

by

in ,

Last year I wrote a PowerShell chapter for SharePoint 2010 Unleashed. One of the scripts that is available in the book allows you to easily backup SharePoint 2010 site collections. The Backup-SPSite cmdlet is available in SharePoint 2010 OOTB, but we wanted to show our readers you can do more with PowerShell.

Therefore this script allows you to:

  • Backup a single site collection or multiple site collections.
  • You can limit the number of backup files to keep (e.g. last 5 backups).
  • Once backup is completed, the administrator will be sent and e-mail with the information about the backup status, site collection size and backup file size.

Backuping just Site Collections is not enough to restore your entire farm, check SharePoint 2010 backup. You can document your SharePoint farm settings with our tool Documentation Toolkit for SharePoint.

Here are the examples how you can call the backup script:

# Backup all site collections in your farm
Get-SPSite -Limit All | ForEach-Object {Backup-SPSiteCollections -SPSiteID $_.ID -BackupFolder "C:\Backups\" -SiteName $_.Url -BackupFilesLimit 5 -Email "your-email@contoso.com" -SmtpServer "smtp.contoso.com"}
#
#Backup a site collection whose URL equals http://intranet.contoso.com
Get-SPSite | Where {$_.Url -eq "http://intranet.contoso.com"} | ForEach-Object {Backup-SPSiteCollections -SPSiteID $_.ID -BackupFolder "C:\Backups\" -SiteName $_.Url -BackupFilesLimit 5 -Email "your-email@contoso.com" -SmtpServer "smtp.contoso.com"}
#
#Backup all site collections whose URL is not equal to http://no-backup.contoso.com, no emails will be sent
Get-SPSite | where {$_.Url -ne "http://no-backup.contoso.com"} | ForEach-Object {Backup-SPSiteCollections -SPSiteID $_.ID -BackupFolder "C:\Backups\" -SiteName $_.Url -BackupFilesLimit 5}

You can also schedule this script to be run via Scheduled Task. The user running the scheduled task must have proper privileges to perform backup operations.

  • Create an action for scheduled task to Start a program.
  • Type powershell to Program/Script textbox.
  • Paste the full path to your script to Arguments textbox (e.g. C:\Scripts\BackupScript.ps1)

Backup SharePoint via PowerShell scheduled via Scheduled Tasks

Here is the entire script:

#
# SharePoint 2010 Unleashed - PowerShell SharePoint backup script
# http://www.amazon.com/Microsoft-SharePoint-2010-Unleashed-Michael/dp/0672333252
# Copyright: Toni Frankola
# Version: 1.1.0, Jul 2011.
#
# Source: https://www.sharepointusecases.com/?p=1597
# Licensed under the MIT License:
# http://www.opensource.org/licenses/mit-license.php
#

cls
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
	Add-PSSnapin Microsoft.SharePoint.PowerShell;
}

Function Backup-SPSiteCollections ()
{
	param(
		[Parameter(
			Position=0,
			Mandatory=$true
		)]
		[Guid]$SPSiteID,
		[Parameter(
			Position=0,
			Mandatory=$true
		)]
		[string]$BackupFolder,
		[Parameter(
			Position=0,
			Mandatory=$true
		)]
		[string]$SiteName,
		[Parameter(
			Position=0,
			Mandatory=$true
		)]
		[int]$BackupFilesLimit,
		[Parameter(
			Position=0,
			Mandatory=$false
		)]
		[string]$Email = "",
		[Parameter(
			Position=0,
			Mandatory=$false
		)]
		[string]$SmtpServer = ""
	)

	$siteNameSlug = $SiteName -replace "https://", ""
	$siteNameSlug = $siteNameSlug -replace "http://", ""
	$siteNameSlug = $siteNameSlug -replace ":", "-"
	$siteNameSlug = $siteNameSlug -replace " ", "-"
	$siteNameSlug = $siteNameSlug -replace "/", "-"
	$siteNameSlug = $siteNameSlug -replace "\.", "-"

	# Test if backup folder exists
	if (Test-Path $BackupFolder)
	{
		# Retrive previous backup files , sorted by last write time (last modified)
    	$files = Get-Childitem $BackupFolder | where {$_.Name -like ("*" + $siteNameSlug + "*.dat")} | Sort $_.LastWriteTime
    	$filesCount = @($files).Count

		# If there are more files in directory than backupFilesLimit
    	if($filesCount -ge $BackupFilesLimit)
    	{
			# Delete all older files
        	for ( $i=0; $i -lt $filesCount-$BackupFilesLimit+1; $i++)
        	{
            	Remove-Item ($BackupFolder + $files[$i].Name)
        	}
    	}
	}
	# If backup folder does not exist it will be created
	else
	{
		New-Item $BackupFolder -type directory
	}

    $backupFileName = ("" + $siteNameSlug + "_" + (Get-Date -Format yyyy-MM-ddThh-mm-ss) + ".dat")
    $backupFilePath = $BackupFolder + $backupFileName
	$startTime = Get-Date
    Backup-SPSite -identity $_.ID -path ($backupFilePath) -force
    $endTime = Get-Date

	# Checking if Email and SmtpServer values have been defined
	if($Email -ne "" -and $SmtpServer -ne "")
	{
		$subject = "SharePoint Site Collection Backup Completed!"
		$body = "The following site collection was backuped: " + $SiteName + "`n"
		$body += "Site collection was backuped to: " + $backupFileName + "`n"
		$body += "Backup started on: " + $startTime + ", and ended on: " + $endTime + "`n`n"
		# Retrieving Site Collection size
		$SiteCollectionSize = Get-SPSite "http://intranet.contoso.com" | Select @{Label="Size"; Expression={$_.Usage.Storage/1MB}} | Select Size
		# Retrieving backup file size

		$backupFileSize = Get-ChildItem $backupFilePath
		$backupFileSize = [Math]::Round($backupFileSize.length/1MB, 2)

		$body += "Site collection size on SharePoint system is: " + [Math]::Round($SiteCollectionSize.Size, 2) + " MB`n"
		$body += "Backup file size: " + $backupFileSize + " MB"
		$smtp = new-object Net.Mail.SmtpClient($SmtpServer)
		# Sending email
		$smtp.Send($Email, $Email, $subject, $body)
	}
}

# Backup all site collections in your farm
Get-SPSite -Limit All | ForEach-Object {Backup-SPSiteCollections -SPSiteID $_.ID -BackupFolder "C:\Backups\" -SiteName $_.Url -BackupFilesLimit 5 -Email "your-email@contoso.com" -SmtpServer "smtp.contoso.com"}

#Backup a site collection whose URL equals http://intranet.contoso.com
Get-SPSite | Where {$_.Url -eq "http://intranet.contoso.com"} | ForEach-Object {Backup-SPSiteCollections -SPSiteID $_.ID -BackupFolder "C:\Backups\" -SiteName $_.Url -BackupFilesLimit 5 -Email "your-email@contoso.com" -SmtpServer "smtp.contoso.com"}

#Backup all site collections whose URL is not equal to http://no-backup.contoso.com, no emails will be sent
Get-SPSite | where {$_.Url -ne "http://no-backup.contoso.com"} | ForEach-Object {Backup-SPSiteCollections -SPSiteID $_.ID -BackupFolder "C:\Backups\" -SiteName $_.Url -BackupFilesLimit 5}

Comments

3 responses to “Backup SharePoint 2010 site collections with PowerShell, send alerts and much more”

  1. Thanks Toni for this awesome script. Would this back up a SharePoint workflow that I have in one of my lists in a site collection?

    I have some workflows that we customized in Designer.
    What do you think is the best way to back up workflows in SP2010?
    Thanks much again

  2. Toni Frankola Avatar
    Toni Frankola

    Yes, the script will backup everything in the content database including workflows.

  3. Thanks for the script! It helps a lot!
    We just tested the script and i think you may need to include “-descending” after “Sort $_.LastWriteTime”. By default, it keeps deleting the most recent backup file if i try to have more than one backup a day.

    Cheers!