Tuesday 5 April 2016

PowerShell SharePoint Backup and Restore made automatic

PowerShell SharePoint Backup and Restore

The Problem

I need an automatic method of backing up and restoring my SharePoint 2013 farm (on prem) to the same or a different farm (for creating a UAT/DEV environment refresh for instance ...)

The Approach

Use PowerShell to create a fast backup and create a fast restore.

The Result

First create a folder on one of the SharePoint servers (C:\SP_Backups in this example).

Next, the current logged in user needs to have securityadmin fixed server role on the SQL Server instance, db_owner fixed database role on all databases that are to be updated / accessed, be in the Administrators group on the server on which you are running the Windows PowerShell cmdlets ... in other words a member of the SPShellAdministrators so if this fails due to some kind of access or privvy errors - have the farm admin add the user running the script using:
Add-SPShellAdmin -UserName $domain\$user
When done the same Admin can remove the user using:
Remove-SPShellAdmin -UserName $domain\$user

Save the following to a ps1 file in the newly created folder above. Edit the path variables (highlighted below) and run it from an admin PS window (using .\<filename>.ps1)

# REQUIRES that the account running this has:
# - securityadmin fixed server role on the SQL Server instance
# - db_owner fixed database role on all databases that are to be updated.
# - Administrators group on the server on which you are running the Windows PowerShell cmdlets.
# can add by An administrator using the Add-SPShellAdmin cmdlet to grant permissions to use SharePoint 2013 cmdlets

# Add-SPShellAdmin -UserName $domain\$user
#
# load up the SharePoint snap-in if not loaded properly
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
# get some variables
$stamp = Get-Date -Format yyyy-MM-dd
# network share to copy completed backup to
$serverdir = "\\SERVER\Shared\baersland-farm-backup"
# local machine dir to create backup to
$dir = "\\SP13\SP_Backups\$stamp"
# create a new subfolder based on year-month-day
New-Item $dir -ItemType directory -Force

$ctdb = Get-SPContentDatabase
# create the restore powershell script in the newly created folder
Out-File -FilePath $dir\1-run_me_to_restore.ps1 -Force -InputObject "# Restore Script created:  $stamp"
Out-File -FilePath $dir\1-run_me_to_restore.ps1 -Append -InputObject "# Optional for moving to another farm -FarmCredentials domain\user -NewDatabaseServer newdbserver"
foreach ($_ in $ctdb) {
    $name = $_.Name
    $guid = $_.Id
    Write-Host "processing ... $name"
    Backup-SPFarm -Directory $dir -BackupMethod Full -Item $_.Name -Verbose
    Write-Host "backup of $name success!!"
    Out-File -FilePath $dir\1-run_me_to_restore.ps1 -Append -InputObject "Restore-SPFarm -Directory $dir -RestoreMethod Overwrite -Item $name -Verbose -Confirm $false"
}
# move from local to network share
Copy-Item -Path $dir -Destination $serverdir -Recurse -Force
Clear-Host
Write-Host "░░░░░░░░░░░░░░░░░░░░░█████████
░░███████░░░░░░░░░░███▒▒▒▒▒▒▒▒███
░░█▒▒▒▒▒█░░░░░░░███▒▒▒▒▒▒▒▒▒▒▒▒▒███
░░░█▒▒▒▒▒▒█░░░░██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░░░░█▒▒▒▒▒█░░░██▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒███
░░░░░█▒▒▒█░░░█▒▒▒▒▒▒████▒▒▒▒████▒▒▒▒▒▒██
░░░█████████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░░░█▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒▒▒▒▒▒██
░██▒▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒██▒▒▒▒▒▒▒▒▒▒██▒▒▒▒██
██▒▒▒███████████▒▒▒▒▒██▒▒▒▒▒▒▒▒██▒▒▒▒▒██
█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒████████▒▒▒▒▒▒▒██
██▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░█▒▒▒███████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░██▒▒▒▒▒▒▒▒▒▒████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█
░░████████████░░░█████████████████" -ForegroundColor Green

The lat bit is just a fun way of knowing when the script and backup have worked.

Restoring is simple. Open the date stamped folder and run the script this script created <path>/1-run_me_to_restore.ps1. If moving to another environment with different user credentials for the farm and a different database server ... recomended ... edit the file by removing the comment and adding values for the required info:
# Optional for moving to another farm -FarmCredentials domain\user -NewDatabaseServer newdbserver

Going Forward

Use parameters and can the script to be called as part of a toolset.
Set up a script to add this as a scheduled task on one of the servers.
Add error handling (try/catch with a nasty catch ascii image!)