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 = “pool.domain.com”
###Done
#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$currDateXdsConfig.zip
Export-CsLisConfiguration -FileName $folderPath$currDateLisConfig.zip
#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$currDateRgsConfig.zip
#Export User Information
Export-CsUserData -PoolFqdn $poolFQDN -FileName $folderPath$currDateUserData.zip
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.
Is this script compatible with Lync Server 2010?
Thanks
If you click on the Lync at the start of this article it goes back to a similar script I wrote for Lync Server 2010. This one has some specific Lync 2013 commands that didn’t exist before.
Nice!
Thanks very much for the script! Your article for Lync 2010 has a step to backup all the databases with an osql command. Is that no longer needed in 2013?
Found a way to include voice from a comment on this blog post: http://blogs.technet.com/b/uc_mess/archive/2011/03/17/lync_2d00_server_2d00_2010_2d00_backup_2d00_instructions.aspx#3437357
I added the code listed below:
#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
Thank you for this!
Mike
Does this also include the persistent group chat database information? I’m not seeing anything directly referencing those databases.
No, Persistent Chat is not included in pool pairing. You should do a stretched PChat pool to accomplish a similar process.
I receive the following error message. please help.
Import-Module : A positional parameter cannot be found that accepts argument ‘E:BackupFromMSP
= -10″’.
At E:BACKUPLyncbackupscript.ps1:6 char:1
+ Import-Module “C:Program FilesCommon FilesMicrosoft Lync Server 2013Modules …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Import-Module], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.ImportModuleCo
mmand
When trying to execute this on Windows 2012R2 through Task Scheduler, I kept getting errors that the path of C:WindowsSytem32Microsoft Lync Server 2013$currDateFilename.xml was not found.
I changed the variable name from folderPath to BackupPath and the script then completed successfully.
I’ve run this on Windows 2008R2 as written without issue.