This is a script I wrote to handle all of the extra, post-backup tasks that need to happen after the site database gets backed up.  It backs up your SSRS databases and keys, the afterbackup.bat file, your Client folder on the site server, the SCCMContentLib folder on the site server, logs everything and emails you the results.  You can either have it check for a successful site database backup ahead of time in case it failed.

#Requires -Version 3 
    This script checks a ConfigMgr site backup to ensure success and performs various post-backup functions that  
    back up other critical data that the built-in ConfigMgr site backup task does not. 
    This script checks any previous backup attempt ran within the last hour of this script running for a 
    a successful run if backup check is selected.  It assumes you also have SSRS installed on the site DB server  
    and backs up both SSRS databases, exports out the SSRS encryption keys, backs up the export file and the  
    entire ReportingServices folder on the server.  Once SSRS has been backed up, it then also copies the entire  
    SCCMContentLib folder, client install folder and the afterbackup.bat file to the destination backup folder path.   
    Once complete, it then attaches the log file it creates as part of the process and emails it out to the defined recipient. 
    The script intends on creating 7 days worth of backups in a central location labeled Monday through Friday 
    and places a copy of all backed up components in each day's folder. 
    Created on:     6/13/2014 
    Created by:     Adam Bertram 
    Filename:    Start-PostConfigMgrBackupSteps.ps1 
    Requirements:    ConfigMgr, Reporting Point installed on the site DB server 
    Todos:        Use the Sync framework to only copy deltas ( 
            Backup custom updates added via SCUP 
            Verify copies were actually successful 
            Retrieve more params automatically 
    This example uses all default parameters for the script which will be the most likely way it is executed. 
    The ConfigMgr site code that the site server is a part of 
.PARAMETER SiteDbServer 
    The Configmgr site server that has the Reporting Services Point and the Site database server role installed. 
.PARAMETER DestDbBackupFolderPath 
    The UNC root folder path where the days' backup folders will be copied to 
.PARAMETER SrcReportingServicesFolderPath 
    The UNC folder path where you have installed reporting services to on the server. 
.PARAMETER ReportingServicesDbBackupSqlFilePath 
    The UNC file path to the SQL file that is dynamically created (if not exists) that the script passes to the  
    sqlcmd utility to kick off a backup of the SSRS databases.  This does not have to exist.  It is recommended 
    to allow the script to create this. 
.PARAMETER ReportingServicesEncKeyPassword 
    The password that's set on the exported SSRS keys 
.PARAMETER SrcContentLibraryFolderPath 
    The folder path to ConfigMgr's content library on the site server.  This folder is called SCCMContentLib. The 
    default path probably does not need to be changed. 
.PARAMETER SrcClientInstallerFolderPath 
    The folder path where the ConfigMgr client install is located on the site server.  This is backed up if you 
    have any hotfixes being installed with your clients and may be located in here. 
.PARAMETER SrcAfterBackupFilePath 
    The file path where the afterbackup.bat file is located.  You should not have to change this from the default. 
.PARAMETER LogFilesFolderPath 
    The folder path where the script will create a log file for each day it runs. 
.PARAMETER CheckBackup 
    Use this switch to first check to ensure a recent backup was successful.  This parameter is recommended 
    when running inside the afterbackup.bat file. 
param ( 
    [string]$SiteCode = 'YOURSITEHERE', 
    [ValidateScript({Test-Connection $_ -Quiet -Count 1})] 
    [string]$SiteDbServer = 'YOURSITESERVERHERE', 
    [ValidateScript({ Test-Path $_ -PathType 'Container' })] 
    [string]$DestDbBackupFolderPath = '\\YOUR\DESTINATION\BACKUP\FOLDER\PATH', 
    [ValidateScript({ Test-Path $_ -PathType 'Container' })] 
    [string]$SrcReportingServicesFolderPath = "\\$SiteDbServer\f$\Sql2012Instance\MSRS11.MSSQLSERVER\Reporting Services", 
    [string]$ReportingServicesDbBackupSqlFilePath = "\\$SiteDbServer\c$\ReportingServicesDbBackup.sql", 
    [string]$ReportingServicesEncKeyPassword = 'my_password', 
    [ValidateScript({ Test-Path $_ -PathType 'Container' })] 
    [string]$SrcContentLibraryFolderPath = "\\$SiteDbServer\f$\SCCMContentLib", 
    [ValidateScript({ Test-Path $_ -PathType 'Container' })] 
    [string]$SrcClientInstallerFolderPath = "\\$SiteDbServer\c$\Program Files\Microsoft Configuration Manager\Client", 
    [ValidateScript({ Test-Path $_ -PathType 'Leaf' })] 
    [string]$SrcAfterBackupFilePath = "\\$SiteDbServer\c$\Program Files\Microsoft Configuration Manager\inboxes\\afterbackup.bat", 
    [string]$LogFilesFolderPath = "$DestDbBackupFolderPath\Logs", 
begin { 
    Set-StrictMode -Version Latest 
    try { 
        ## This function builds a SQL file called $ReportingServicesDbBackupSqlFile that backs up both 
        ## reporting services databases to a subfolder called ReportsBackup under today's 
        ## destination backup folder 
        function New-ReportingServicesBackupSqlFile($TodayDbDestFolderPath) { 
            Add-Content -Value "declare @path1 varchar(100); 
            declare @path2 varchar(100); 
            SET @path1 = '$TodayDbDestFolderPath\ReportsBackup\ReportServer.bak'; 
            SET @path2 = '$TodayDbDestFolderPath\ReportsBackup\ReportServerTempDB.bak'; 
            USE ReportServer; 
            DBCC SHRINKFILE(ReportServer_log); 
            USE ReportServerTempDb; 
            DBCC SHRINKFILE(ReportServerTempDB_log);" -Path $ReportingServicesDbBackupSqlFilePath 
        function Convert-ToLocalFilePath($UncFilePath) { 
            $Split = $UncFilePath.Split('\') 
            $FileDrive = $Split[3].TrimEnd('$') 
            $Filename = $Split[-1] 
            $FolderPath = $Split[4..($Split.Length - 2)] 
            if ($Split.count -eq 5) { 
            } else { 
        Function Get-LocalTime($UTCTime) { 
            $strCurrentTimeZone = (Get-WmiObject win32_timezone).StandardName 
            $TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTimeZone) 
            $LocalTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($UTCTime$TZ) 
        if (!(Test-Path $LogFilesFolderPath)) { 
            New-Item -Path $LogFilesFolderPath -Type Directory | Out-Null 
        $script:MyDate = Get-Date -Format 'MM-dd-yyyy' 
        $script:LogFilePath = "$LogFilesFolderPath\$MyDate.log" 
        ## Simple logging function to create a log file in $LogFilesFolderPath named today's 
        ## date then write a timestamp and the message on each line and outputs the log file 
        ## path it wrote to 
        function Write-Log($Message) { 
            $MyDateTime = Get-Date -Format 'MM-dd-yyyy H:mm:ss' 
            Add-Content -Path $script:LogFilePath -Value "$MyDateTime - $Message" 
        $DefaultBackupFolderPath = "$DestDbBackupFolderPath\$SiteCode" + 'Backup' 
        if (!(Test-Path $DefaultBackupFolderPath)) { 
            throw "Default backup folder path $DefaultBackupFolderPath does not exist" 
        if ($CheckBackup.IsPresent) { 
            ## Ensure the backup was successful before doing post-backup tasks 
            ## $DefaultBackupFolderPath is the path where the builtin Site Backup SQL maintenance task places the 
            ## backup. Ensure it has today's write time before going further because if not then the backup 
            ## didn't run successfully 
            $BackupFolderLastWriteDate = (Get-ItemProperty $DefaultBackupFolderPath).Lastwritetime.Date 
            $SuccessMessageId = 5035 
            $OneHourAgo = (Get-Date).AddHours(-1) 
            Write-Log "One hour ago detected as $OneHourAgo" 
            $WmiParams = @{ 
                'ComputerName' = $SiteDbServer; 
                'Namespace' = "root\sms\site_$SiteCode"; 
                'Class' = 'SMS_StatusMessage'; 
                'Filter' = "Component = 'SMS_SITE_BACKUP' AND MessageId = '$SuccessMessageId'" 
            $LastSuccessfulBackup = (Get-WmiObject @WmiParams | sort time -Descending | select -first 1 @{ n = 'DateTime'; e = { $_.ConvertToDateTime($_.Time) } }).DateTime 
            $LastSuccessfulBackup = Get-LocalTime $LastSuccessfulBackup 
            Write-Log "Last successful backup detected on $LastSuccessfulBackup" 
            $IsBackupSuccessful = $LastSuccessfulBackup -gt $OneHourAgo 
            if (($BackupFolderLastWriteDate -ne (get-date).date) -or !$IsBackupSuccessful) { 
                throw 'The backup was not successful. Post-backup procedures not necessary' 
        $CommonCopyFolderParams = @{ 
            'Recurse' = $true; 
            'Force' = $true; 
    } catch { 
        Write-Log "ERROR: $($_.Exception.Message)" 
        exit (10) 
process { 
    try { 
        ## If today's folder exists in the root of the backup folder path 
        ## remove it else create a new one 
        $Today = (Get-Date).DayOfWeek 
        $TodayDbDestFolderPath = "$DestDbBackupFolderPath\$Today" 
        if ((Test-Path $TodayDbDestFolderPath -PathType 'Container')) { 
            Remove-Item $TodayDbDestFolderPath -Force -Recurse 
            Write-Log "Removed $TodayDbDestFolderPath..." 
        ## Rename the default backup folder to today's day of the week 
        Rename-Item $DefaultBackupFolderPath $Today 
        ## Create the folder to put the reporting services database backups in 
        New-Item -Path "$TodayDbDestFolderPath\ReportsBackup" -ItemType Directory | Out-Null 
        ## if the SQL file that gets invoked to backup the SSRS databases isn't in the root of 
        ## C on the site server, build it.  The root of C isn't necessary.  It just needs to be 
        ## somewhere on the local server 
        if (Test-Path $ReportingServicesDbBackupSqlFilePath) { 
            Remove-Item $ReportingServicesDbBackupSqlFilePath -Force 
        New-ReportingServicesBackupSqlFile $TodayDbDestFolderPath 
        Write-Log "Created new SQL file in $TodayDbDestFolderPath..." 
        ## Convert the UNC path specified for the SQL file into a local path to feed to 
        ## sqlcmd on the site server which backs up the SSRS databases.  Confirm success 
        ## afterwards. 
        Write-Log "Backing up SSRS Databases..." 
        $LocalPath = Convert-ToLocalFilePath $ReportingServicesDbBackupSqlFilePath 
        $result = Invoke-Command -ComputerName $SiteDbServer -ScriptBlock { sqlcmd -$using:LocalPath } 
        if ($result[-1] -match 'DBCC execution completed') { 
            Write-Log 'Successfully backed up SSRS databases' 
        } else { 
            Write-Log 'WARNING: Failed to backup SSRS databases' 
        ## Export the SSRS Encryption keys to a local file via remoting on the site server and 
        ## copy that file to the backup location 
        Write-Log "Exporting SSRS encryption keys..." 
        $ExportFilePath = "\\$SiteDbServer\c$\rsdbkey.snk" 
        $LocalPath = Convert-ToLocalFilePath $ExportFilePath 
        $result = Invoke-Command -ComputerName $SiteDbServer -ScriptBlock { echo y | rskeymgmt --$using:LocalPath -$using:ReportingServicesEncKeyPassword } 
        if ($result[-1] -ne 'The command completed successfully') { 
            Write-Log 'WARNING: SSRS keys were not exported!' 
        } else { 
            Copy-Item $ExportFilePath $TodayDbDestFolderPath -Force 
            Write-Log 'Successfully exported and backed up encryption keys.' 
        ## Backup the Reporting Services SSRS folder 
        Write-Log "Backing up $SrcReportingServicesFolderPath..." 
        Copy-Item @CommonCopyFolderParams -Path $SrcReportingServicesFolderPath -Destination "$TodayDbDestFolderPath\ReportsBackup" 
        Write-Log "Successfully backed up the $SrcReportingServicesFolderPath folder.." 
        ## Backup the SCCMContentLib folder 
        Write-Log "Backing up $SrcContentLibraryFolderPath..." 
        Copy-Item @CommonCopyFolderParams -Path $SrcContentLibraryFolderPath -Destination $TodayDbDestFolderPath 
        Write-Log "Successfully backed up the $SrcContentLibraryFolderPath folder.." 
        ## Backup the client install folder from the site server to the backup folder 
        Write-Log "Backing up $SrcClientInstallerFolderPath..." 
        Copy-Item @CommonCopyFolderParams -Path $SrcClientInstallerFolderPath -Destination $TodayDbDestFolderPath 
        Write-Log "Successfully backed up the $SrcClientInstallerFolderPath folder.." 
        ##TODO: Backup any SCUP updates 
        ## On the computer that runs Updates Publisher, browse the Updates Publisher 2011 database file (Scupdb.sdf) 
        ## in %USERPROFILE%\AppData\Local\Microsoft\System Center Updates Publisher 2011\5.00.1727.0000\. There is 
        ## a different database file for each user that runs Updates Publisher 2011. Copy the database file to your 
        ## backup destination. For example, if your backup destination is E:\ConfigMgr_Backup, you could copy the 
        ## Updates Publisher 2011 database file to E:\ConfigMgr_Backup\SCUP2011. 
        ## Backup the afterbackup.bat file that kicks off this script 
        Write-Log "Backing up $SrcAfterBackupFilePath.." 
        Copy-Item @CommonCopyFolderParams -Path $SrcAfterBackupFilePath -Destination $TodayDbDestFolderPath 
        Write-Log "Successfully backed up the $SrcAfterBackupFilePath file..." 
    } catch { 
        Write-Log "ERROR: $($_.Exception.Message)" 
end { 
    Write-Log 'Emailing results of backup...' 
    ## Email me the results of the backup and post-backup tasks 
    $Params = @{ 
        'From' =  'ConfigMgr Backup <>'; 
        'To' = 'Adam Bertram <>'; 
        'Subject' = 'ConfigMgr Backup'; 
        'Attachment' =  $script:LogFilePath; 
        'SmtpServer' = 'SOMESERVER' 
    Send-MailMessage @Params -Body 'ConfigMgr Backup Email'