Public/Backup-Files.ps1

function Backup-Files
{
    ##############################################################################
    #.SYNOPSIS
    # Backs up files (Used with Restore-Files).
    #
    #.DESCRIPTION
    # Use this function to maintain backups using Robocopy before starting the deployment.
    # Detailed information about the Robocopy exit codes is provided in the end of the operaton.
    # Default log file (BACKUP_DIR\_SitecoreDeploymentPS\BackupFilesLog.txt).
    # Ability to exclude folders and files from backup.
    # Creates backup subfolder each time when you call the funtion (subfolder name format: yyyy-MM-dd_HH-mm).
    # Used with Restore-Files.
    #
    #.PARAMETER SourceDir
    # Back up soucrce directory (absolute path).
    # Usually website root.
    #
    #.PARAMETER TargetDir
    # Back up target directory (absolute path).
    #
    #.PARAMETER ExcludedDirs
    # [OPTIONAL] Directories and files which won't be backed up (absolute paths).
    #
    #.PARAMETER LogFile
    # [OPTIONAL] Log file (absolute path).
    # [DEFAULT_VALUE] $TargetDir\yyyy-MM-dd_HH-mm\_SitecoreDeploymentPS\BackupFilesLog.txt
    #
    #.EXAMPLE
    # $sourceDir = "C:\inetpub\wwwroot\website"
    # $targetDir = "C:\backup"
    # $excludedDirs = @("$sourceDir\App_Data\MediaCache", "$sourceDir\_DEV", "$sourceDir\_CMP", "$sourceDir\upload", "$sourceDir\temp", "$sourceDir\sitecore", "$sourceDir\sitecore modules", "$sourceDir\sitecore_files")
    # $logFile = "C:\logs\BackupLog.txt"
    # Backup-Files -SourceDir $sourceDir
    # -TargetDir $targetDir
    # -ExcludedDirs $excludedDirs (optional, recommended)
    # -LogFile $logFile (optional)
    ##############################################################################

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)]
        [ValidateScript({
            if (Test-Path $_) { $true }
            else { Throw "The $_ path is not valid. Please, provide a valid value." }})]
        [string]$SourceDir,

        [Parameter(Mandatory=$true)]
        [ValidateScript({
            if (Test-Path $_) { $true }
            else { Throw "The $_ path is not valid. Please, provide a valid value." }})]
        [string]$TargetDir,
        
        [string[]]$ExcludedDirs,

        [string]$LogFile
    )

    Write-Host "Backup started."
    Write-Host "Backup source: $SourceDir"
    Write-Host "Backup target: $TargetDir"
   
    $uniqueDir = New-UniqueDir -Directory $TargetDir
    
    # Always create log directory.
    # Only backups which cotain log directory (created from Sitecore.Powershell) are considered valid for restore.
    $logDir = New-LogDir -Directory $uniqueDir

    if ([String]::IsNullOrWhiteSpace($LogFile))
    {
        $LogFile = "$logDir\BackupFilesLog.txt"
    }
    else
    {
        if(!(Test-Path $LogFile))
        {
            Remove-Dir -Directory $uniqueDir
            Throw "The '$LogFile' log path is not valid. Please, provide a valid value."
        }
    }

    if($ExcludedDirs.Count -gt 0)
    {
        $ExcludedDirsOption = ,"/XD" + $ExcludedDirs
    }

    Robocopy $SourceDir $uniqueDir /MIR $ExcludedDirsOption /LOG+:"$LogFile" /TEE

    if($ExcludedDirs.count -gt 0)
    {
        $excludedRelativeDirs = @()

        ForEach($dir in $ExcludedDirs)
        {
            $excludedRelativeDirs += $dir.Replace($SourceDir, "")
        }

        # Excluded directories file is used on restore.
        # Creates the file after Robocopy is finished, because otherwise the MIR option will delete it.
        New-ExcludedDirsFile -Directory $logDir -ExcludedDirs $excludedRelativeDirs
        
        # Creates empty directories for each excluded directory to be able to exclude them on restore and keep them untouched.
        New-EmptyDirs -Directory $uniqueDir -RelativeDirs $excludedRelativeDirs
    }

    $lastExitCode = $LASTEXITCODE
    Show-RobocopyResultMessage -RobocopyExitCode $lastExitCode
    Exit-Backup-Files -RobocopyExitCode $lastExitCode
}