Backup for Lync Server 2013

March 31, 2013

Often I get asked what should someone backup for Lync Server 2013 and thankfully the list of items hasn’t changed that much from Lync Server 2010 to Lync Server 2013.  Back in June of 2012 I wrote an article on how to backup and recovery Lync Server 2010 and I highlighted a few major items:

  • CMS Database
  • LIS Database
  • Response Groups
  • User Data

Things haven’t changed that much and with the exception of maybe adding your CDR/Archiving and Persistent Chat data to this list but otherwise it is still a very complete list.  With Lync Server 2013 we get a significantly better pool pairing process that does much of this replication of data from point A to point B but as any network administrator is aware, you should ALWAYS have a backup plan that involves several different ways to recover data.

So below is a script I have created for my Lync 2013 Deployments.  I know there are a ton of different scripts out on the web for backup of Lync but I typically have two issues.  First, I’m not a PowerShell expert and many times when I look at the scripts I can’t seem to figure out what is going on.  Second, backing up data is only one step of the puzzle, the second item is to get that data somewhere else.  So I always make sure my scripts have a robocopy process to get information from one side to the other and with multiple versions of it.

This script has been tested with both Standard and Enterprise Edition pools and on Windows Server 2012.

# Export Script for Backup
# Created By Richard Brynteson
# Avtex 2013

# Import Lync Module
Import-Module “C:Program FilesCommon FilesMicrosoft Lync Server 2013ModulesLyncLync.psd1”

###Variables To Set
$folderPath = “D:BackupFromMSP”
$lengthOfBackup = “-10”
$drFolderPath = “\drserver.domain.comFromMSP$
$poolFQDN = “”

#Production – Delete Older Than x Days
get-childitem $folderPath -recurse | where {$_.lastwritetime -lt (get-date).adddays($lengthOfBackup) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force }

#Production – Delete Empty Folders
$a = Get-ChildItem $folderPath -recurse | Where-Object {$_.PSIsContainer -eq $True}
$a | Where-Object {$_.GetFiles().Count -eq 0} | Remove-Item

#Production – Get Date and Create Folder
$currDate = get-date -uformat “%a-%m-%d-%Y-%H-%M”
New-Item $folderPath$currDate -Type Directory

#Delete Older Than x Days – DR Side
get-childitem $drFolderPath -recurse | where {$_.lastwritetime -lt (get-date).adddays($lengthOfBackup) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force }

#Delete Empty Folders – DR Side
$a = Get-ChildItem $drFolderPath -recurse | Where-Object {$_.PSIsContainer -eq $True}
$a | Where-Object {$_.GetFiles().Count -eq 0} | Remove-Item

#Message Out
Write-Host -ForegroundColor Green “Backup to server in progress”

#Export CMS/XDS and LIS
Export-CsConfiguration -FileName $folderPath$
Export-CsLisConfiguration -FileName $folderPath$

#Export Voice Information
Get-CsDialPlan | Export-Clixml -path $folderPath$currDateDialPlan.xml
Get-CsVoicePolicy | Export-Clixml -path $folderPath$currDateVoicePolicy.xml
Get-CsVoiceRoute | Export-Clixml -path $folderPath$currDateVoiceRoute.xml
Get-CsPstnUsage | Export-Clixml -path $folderPath$currDatePSTNUsage.xml
Get-CsVoiceConfiguration | Export-Clixml -path $folderPath$currDateVoiceConfiguration.xml
Get-CsTrunkConfiguration | Export-Clixml -path $folderPath$currDateTrunkConfiguration.xml

#Export RGS Config
Export-CsRgsConfiguration -Source “service:ApplicationServer:$poolFQDN” -FileName $folderPath$

#Export User Information
Export-CsUserData -PoolFqdn $poolFQDN -FileName $folderPath$

Write-Host -ForegroundColor Green “XDS, LIS, User and RGS backup to server is completed.  Files are located at $folderPath$currDate”
Write-Host -ForegroundColor Green “Please make sure to export Voice Configuration”  

#Copy Files to DR Server
robocopy $folderPath $drFolderPath /COPY:DATSO /S

How to Use The Script

I have made it as simple as I can to use and reuse.  First off, save the above to a file names LyncBackupScript.ps1 and save it to D:backup.  In terms of variables, I have four of them.  The first one is the location of where the backup files are actually going to be stored.  So let’s say this script is at D:Backup then I’m going to store my files in D:BackupFromMSP.  Within that folder, the script is going to create a folder for each day.  The length of backup is how many files are we going to keep on the server.  The number must be a negative number, like -10 days.  DR folder path works like above.  The Pool is the name of the pool you want to backup.

You will want to schedule this script as a scheduled task.  So your scheduled task would be something like:

powershell.exe -FileName d:backuplyncbackupscript.ps1

So go to Administrative Tools | Scheduled Tasks.  Create a new task (Lync Backup for Example).  The path to the executable is above and set it to be scheduled on a daily basis.  After you have walked through the wizard and picked a particular day, make sure to edit the backup script.  You will want to change the setting to allow the script to run anytime.  When you do that, you will need to make whatever user is going to run the script with Logon as Batch permissions.  You can do this through the Local Security Policy.  Lastly, in terms of permissions, you will need to be a member of the RTCUniversalServerAdmins group to execute this.

I’ll add some pretty screen shots to this over the coming days but it’s late.  Next to add is a little simple error handling and a HTML E-Mail Report on failures/success.  But that is a project for another night/time.

UPDATE – I have updated the script with the provided info on how to backup voice configuration items.



Written by Richard Richard is an Office Apps & Services MVP (Teams / Skype) who lives in Minneapolis, MN. Microsoft Certified Solutions Master (MCSM) and MCSM Instructor - when those were a thing long ago. When not writing code, breaking teams - debate coach and avid golfer.
Follow on Twitter

Built using Gatsby and Material-UI

Copyright © TheArgyleMVP 2022.