rilpoint_mw113

Backup SP Farm

<-- Maintenance

Concept from Scripting Guy

<#
.SYNOPSIS
 Backs up a SharePoint farm on a scheduled basis.
 
.DESCRIPTION
 At its core, the BackupSharePoint script backs up a SharePoint farm. When run as 
 scheduled task, it generates a full farm backup once a week and differential 
 backups all other days. It also deletes the oldest backup directory, allowing for
 storage management.
 
.PARAMETER
 -drive <string[]>
     Indicates the drive letter of the server where the script is run. The script
     also assumes this drive also hosts the shared directory used to store backups.
 -backupDir <string[]>
     The shared UNC path for your backups to be stored in on the server
     Example: \\<YOUR SHAREPOINT SERVER>\<YOUR BACKUP FOLDER>\
 -fullBackupDay <string[]>
     The day that a full backup should be run on.
     Example: "Sunday"
 -configDBInstance <string[]>
     The SQL Server Database Server and Instance name hosting the SharePoint 
     configuration database. Example: "<YOUR SQL SERVER>\<YOUR INSTANCE>"
 -configDBName <string[]>
     The name of the farm's SharePoint configuration database. 
     Example: "<YOUR CONFIG DB>"
 -nbrDaysRetained <string[]>
     The number of days that backups should be retained. Example: 14
 -Computer <string{}>
     The name of the computer the script is being run on. If blank, the script
     will default to the local computer name environment variable
 
.EXAMPLE
-------------------------- EXAMPLE 1 -------------------------------------------
.\BackupSharePoint.ps1 -drive "C:" -backupDir "\\server\backups" 
    -fullBackupDay "Sunday" -configDBInstance sql\sql01 -configDBName ConfigDB 
    -nbrDaysRetained 14 
 
This command generates a backup of a SharePoint 2010 environment and is intended 
to be run as a Scheduled Task. It sets the backup to run as a Full Backup on Sunday,
and differential backups the rest of the week. A backup of the SharePoint 
Configuration database is also created daily. 
 
The command merges the SharePoint usage logs when a full backup is run. Backups 
more than 14 days old are deleted to conserve the amount of storage space used 
by backup files. Backups are stored in the \\server\backups shared directory, 
which should be on the C:\ drive of that target server.
 
-------------------------- EXAMPLE 2 -------------------------------------------
.\BackupSharePoint.ps1 -drive "E:" -backupDir "\\wss-server\backups" 
    -fullBackupDay "Saturday" -nbrDaysRetained 21 
 
This command generates a backup of a SharePoint 2007 environment and is intended 
to be run as a Scheduled Task. It sets the backup to run as a Full Backup on Saturday,
and differential backups the rest of the week. A backup of the SharePoint 
Configuration database is also created daily. 
 
Backups more than 21 days old are deleted to conserve the amount of storage space 
usedby backup files. Backups are stored in the \\server\backups shared directory, 
which should be on the E:\ drive of that target server.  
 
.NOTES
 This command is intended to be run as a Scheduled Task on a server in a 
 SharePoint farm. It can be run for the following SharePoint versions:
  - Windows SharePoint Services v3 (WSS)
  - Microsoft Office SharePoint Server 2007 (MOSS) - for all SKUs
  - Microsoft SharePoint Foundation 2010
  - Microsoft SharePoint Server 2010 - for all SKUs
 
 RECOMMENDED: configure the Scheduled Task to run with a service account rather
  than a named user. The farm's Database Access Account has the rights necessary
  in SharePoint and its databases to run backups with STSADM, but a separate account
  can be used if desired.
 
 REQUIRED: the account serving as the identity of the Scheduled Task must have the 
 following permissons on that server:
  - WSS or MOSS: 
      - DB_CREATOR and SECURITYADMIN roles in the SQL instance hosting 
        the farm's SharePoint databases
      - local administrator rights on the server
      - DB_OWNER rights on the farm's SharePoint databases
      - Read, Write, and Update rights in the shared directory where backups 
        are created
  - SharePoint Foundation 2010 or SharePoint Server 2010
      - It must be granted the SHAREPOINT_SHELL_ACCESS role via the 
        Add-SPShellAdmin CMDLET
      - Full Control of the shared directory where backups are created
      - The account that runs the SharePoint 2010 Timer Job (SPTimerV4.exe) service,
        and the SQL Server instance's SQL Service account must have Full Control
        of the shared backup storage directory
 
 WARNING: this script does not back up the configuration of the IIS web sites 
 running on this server, or its file system in general. You should protect these
 resources as well, in order to ensure the best possible restore scenario for your
 environment. These are targeted for a subsequent release of the tool.
 
.LINKS
 - Windows SharePoint Services v3 Backup and Recovery at TechNet: 
      http://technet.microsoft.com/en-us/library/cc287741%28office.12%29.aspx
 - Microsoft Office SharePoint Server 2007 Backup and Recovery at TechNet:
      http://technet.microsoft.com/en-us/library/cc263053%28office.12%29.aspx
 - SharePoint Foundation 2010 Backup and Recovery at TechNet: 
      http://technet.microsoft.com/en-us/library/cc287896.aspx
 - SharePoint Server 2010 Backup and Recovery at TechNet:
      http://technet.microsoft.com/en-us/library/ee662536.aspx
 - STSADM.exe reference at TechNet: 
      http://technet.microsoft.com/en-us/library/cc288981%28office.12%29.aspx
 - SharePoint 2010 CMDLETs:
    - Add-SPShellAdmin
    - Backup-SPFarm
    - Merge-SPLogFile
    - Backup-SPConfigurationDatabase
#>
 
#requires -version 2
 
# Declare the script's input parameters
param([string]$drive = $(Throw "the drive parameter is required."), `
      [string]$backupDir = $(Throw "the backupDir parameter is required."), `
     [string]$fullBackupDay = $(Throw "the fullBackupDay parameter is required."), `
      #[string]$logStorage, `
      [string]$configDBInstance, `
      [string]$configDBName, `
  [string]$nbrDaysRetained = $(Throw "the nbrDaysRetained parameter's required."), `
      #[string]$sharePointVersion = $(throw "the SP Version parameter is required."), `
      [string]$computer)
# END Parameters
 
# This function determines the amount of free space on the computer's target drive
function Get-FreeDiskSpace($drive,$computer)
{
 $driveInfo = Get-WmiObject -class win32_LogicalDisk -computername $computer `
                            -filter "Name = '$drive'" 
 $space = ($driveInfo.FreeSpace/1MB)
 return $space
}
 
# This function determines the amt of storage currently used by the backup directory
function Get-BackupStorageUsed($backupDir)
{
 $backupStorage = (Get-ChildItem $backupDir -recurse | Measure-Object `
                      -property length -sum)
 $backupstorage = ($backupStorage.sum / 1MB)
 return $backupstorage
} # End Get-BackupStorageUsed
 
# This function determines the directory of the most recently created backup
function Get-NewestBackup($backupDir)
{
 $newestFolder = (Get-ChildItem -path $backupDir | Sort -property LastWriteTime `
                  | Select-Object -last 1 -property FullName | format-table `
                  -hidetableheaders | out-string| foreach { $_.trim() } )
 return $newestFolder
} # End Get-NewestBackup
 
function Get-SPVersion
{  
 # Load the Microsoft.SharePoint assembly to access the SPFarm class
 [void][System.reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") 
 
 # Obtain the local SharePoint Farm object
 $spFarm = [Microsoft.SharePoint.Administration.SPFarm]::Local
 
 # Get the farm's build version
 $spVersion = $spFarm.BuildVersion.ToString()  
 
 # Set the value to check the farm's version against for SharePoint 2010
 $checkSPVersion2010 = "14.0"
 
 # Compare local farm's version to see if it is greater than the static 2010 value
 if ($spVersion -gt $checkSPVersion2010)
 {
  return "2010"
 }
 else
 {
  return "2007"
 }
 
} # END Get-SPVersion
 
function Get-LogLocation
{
 # Get the local SP Diagnotic Service object
 $spDiagService = [Microsoft.SharePoint.Administration.spdiagnosticsservice]::Local
 
 # Get the Diagnostic Service's LogLocation member
 $logLocation = $spDiagService.loglocation
 
 # Return the LogLocation    
 return $logLocation
} #End Get-LogLocation
 
# Using a function to allow for the use of the same backup process, 
# regardless of Backup Method
function Backup-Farm ($backupMethod, $backupDir, $errorFlag, $entryType)
{
  # Execute the requested backup based on SharePoint version provided as input
  if ($sharePointVersion -eq 2007)
  {
   # Generate the path for STSADM
   $stsadm = join-path -path $spRoot -childpath "\BIN\stsadm.exe"
 
   # Run a farm backup with the STSADM command line tool using the input parameters   
   & $stsadm -o "backup" -directory $backupDir `
                            -backupmethod $backupMethod -quiet
  }
  else # SharePoint 2010
  {
      # Run a farm backup with the SP2010 CMDLET using the parameters passed in
      Backup-SPFarm -directory $backupDir -backupmethod $backupMethod
  }
 
  # Get the most recently modified backup folder
  $newestFolder = Get-NewestBackup($backupDir)
 
  # Build the file path for the most recently created backup log file
  $newestLog = Join-Path -path $newestFolder -childpath "spbackup.log"
 
  # Getting the number of errors in the backups log file 
  #  (subtracting 1 for the reporting line at the end of the document)
  $errorLog = Get-Content $newestLog | Out-String 
  $errorCount = [regex]::matches($errorLog,"error").count - 1
 
  # If there is an error, report it
  if ($errorCount -gt 0)
  {
   # Create Error Message
   $eventMsg = $eventMsg + "At least one error was found while making a " `
       + $backupMethod + "backup, stored in the " + $newestFolder + "directory. " `
       + "Please review the spbackup.log file in that directory carefully to " `
       + "diagnose and resolve the issue before running another backup."
 
   # Report an error
   Record-Event -eventMsg $eventMsg -entryType "Error"
 
   # Set the Error flag to "On"
   $errorFlag = 1
  }
  else #Report the successful Farm backup
  {
    # Report the Farm's Backup
    $eventMsg = "A " + $backupMethod + " backup of the farm was successfully " `
                 + "backed up to " + $newestFolder + ". See " + $newestLog `
                 + "  for more information."
    Record-Event -eventMsg $eventMsg -entryType "Information"
  }
}
 
# This function standardizes the process to write entries to the event log 
# about the backups progress
function Record-Event ($eventMsg, $entryType )
{
   # Write the event to the servers Application log
   Write-EventLog -LogName Application -Source $spEventSourceType -EventID 1001 `
                  -Message $eventMsg -EntryType $entryType  
}
# end Record-Event
 
# This function check for the scripts Source type in the Event Log. 
#	if its not there, it will create it.
function Check-LogSource ($sourceType)
{
   if ([System.Diagnostics.EventLog]::SourceExists($sourceType) -eq $False) 
	{
		New-EventLog -Source $sourceType -LogName Application
	}  
}
# end Check-LogSource
 
## MAIN ##
# Preset the error reporting and configuration variables 
$errorFlag = 0
$errorCount = 0
$entryType = "Information"
 
# Check to see if an input was provided for the Computer Name
if ($computer -eq $null)
{
 $computer = $env:computername 
}
 
# Determine the version of SharePoint running on the server
$sharePointVersion = Get-SPVersion
 
# Define the path for the SharePoint 2007 root folder (AKA the "12 Hive")
$spRoot = "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12"
 
# Load the SharePoint 2010 PowerShell snapin if version is 2010 and its not loaded
if (((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) `
     -eq $null) -and ($sharePointVersion -eq 2010))
{
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}
 
# Create the Event Log Source type, based on the version of SharePoint used
$spEventSourceType = "SP" + $sharePointVersion + "Backup"
 
# See if the Event Log Source type already exists or not
Check-LogSource -sourceType $spEventSourceType
 
# Determine the amount of free space in MB on the drive targeted for backup storage
$space = Get-FreeDiskSpace -drive $env:systemdrive -computer $env:computername
 
# Determine the amount of storage in MB currently used on the drive 
# targeted for backup storage
$backupstorage = Get-BackupStorageUsed -backupDir $backupDir
 
# Back Up SharePoint
# ASSUMPTION: the first time this script is run will be the same day as the 
#             $fullBackupDay variable, to ensure that a full backup is made 
#             prior to any differentials (as required by SP)
 
# want to ensure that there is enough storage for the new backup
if ($space -gt ($backupStorage * 2)) 
{
 # Check Date to Run correct type of backup
 if ((Get-Date -format dddd) -eq $fullBackupDay)
 {
  # Call the Backup-Farm function with a backupmethod of "Full"
  Backup-Farm -backupMethod "Full" -backupDir $backupDir -errorFlag $errorFlag `
              -entryType $entryType
 
  # Merge diagnostic logs - SharePoint 2010 only
  # NOTE: Doing this for all diagnostic logs simultaneously can be time consuming,
  #    test 1st & determine if you should target specific logs in your backup script
  if ($sharePointVersion -eq 2010)
  {
   # Get the Farm's ULS log storage location
   $logStorage = Get-LogLocation
 
   # Run the CMDLET to merge the log files
   Merge-SPLogFile -path $logStorage -overwrite
  }
 }
 else # Do a Differential Backup of the Farm
 {
  # Call the Backup-Farm function with a backupmethod of "Differential"
  Backup-Farm  -backupMethod "Differential" -backupDir $backupDir -errorFlag `
               $errorFlag -entryType $entryType
 }
 
 # Call the Backup-SPConfigurationDatabase CMDLET to backup the Farm's 
 # Configuration database 
 # Ensure that the error flag has not be tripped and that it is a 2010 backup
 if (($errorFlag -ne 1) -and ($sharePointVersion -eq 2010) )
 {
  # NOTE: the account set as the identity for the Scheduled Task must be assigned 
  # the db_backupoperator role in SQL Server, otherwise credentials must be 
  # passed in this call
  Backup-SPConfigurationDatabase -directory $backupDir -databaseserver `
                          $configDBInstance -databasename $configDBName
 
  # Check for errors in the Configuration Database backups log file
  # Get the most recently modified backup folder (reset the variable since the 
  #       Config Backup has now been run)
  $newestFolder = (Get-ChildItem -path $backupDir | Sort -property LastWriteTime `
                  | Select-Object -last 1 -property FullName | format-table `
                  -hidetableheaders | out-string| foreach { $_.trim() } )
  #$newestLog = $newestFolder + "\spbackup.log"
  $newestLog = Join-Path -path $newestFolder -childpath "spbackup.log"
 
  # Getting the number of errors in the log file 
  # (subtracting 1 for the reporting line at the end of the document)
  $errorLog = Get-Content $newestLog | Out-String 
  $errorCount = [regex]::matches($errorLog,"error").count - 1
 
  # If there is an error, report it
  if ($errorCount -gt 0)
  {
   # Create Error Message
   $eventMsg = $eventMsg + "At least one error was found while making a " `
       + "Configuration Database backup, stored in the " + $newestFolder `
       + "directory. Please review the spbackup.log file in that directory " `
       + "carefully to diagnose & resolve the issue before running another backup."
 
   # Report an error
   Record-Event -eventMsg $eventMsg -entryType "Error"
 
   # Set the Error flag to "On"
   $errorFlag = 1
  }
  else #Report the successful Config DB backup
  {
    # Report the Deletion Event
    $eventMsg = "The Configuration Database was successfully backed up to " `
              + $newestFolder + ". See " + $newestLog + " for more information."
    Record-Event -eventMsg $eventMsg -entryType "Information"
  }
 }
 
 # Do final error check prior to deleting log files in backup directory
 # older than the retention period threshold
 if ($errorFlag -ne 1) # Ensure that the error flag has not be tripped
 {
  # Remove backup folders older than the retention period to reduce storage
  # Since multiple backup folders are created when a farm backup and a config db
  # backup is created for SP 2010, this should select all folders older than the
  # retention date, rather than just the oldest folder in the backup directory
   # Iterate through each folder in backup directory other than retention threshold
   foreach ($i in (Get-ChildItem $backupDir | where-Object{($_.PSIsContainer)} `
                | Where-Object {($_.LastWriteTime -lt `
                ($(Get-Date).AddDays(-($nbrDaysRetained))))} `
                | Sort-Object{($_.CreationDate + $_.CreationTime)}))
    {
      # Delete the target folder and everything contained within it
      Remove-Item -path $i.FullName -recurse
 
      # Report the Deletion Event
      $eventMsg = "Folder " + $targetFolder + " was deleted to conserve storage " `
             + "usage since it was more than " + $nbrDaysRetained + " days old."
      Record-Event -eventMsg $eventMsg -entryType "Information"
    }
 }
}
else
{
 # Set the error flag to 1
 $errorFlag = 1
 # Set the error message to report that there is not enough space to run the backup
 $eventMsg = "There does not appear to be sufficient disk space available on the " `
           + $drive + " of " + $computer + "to hold a new backup. Please resolve " `
           + "this issue before creating a new backup"
 
 # Report an error
 Record-Event -eventMsg $eventMsg -entryType "Error"
}
Skin by RIL Partner