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)

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: http://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}