Now Lync 2013 public preview is out for some weeks, it is time to start sharing some of my experiences.
One of the most basic traps when using Lync is, from my experience, the absence of a good backup. Most commonly a SQL backup, VM snapshot or full disk backup are being made. but thats not enough! however, make sure you have those as well, just to be sure.
As none of the above backups are on the application level, it is hard – or even impossible – to restore from a tragical application error. And since we’re (going to) run beta software, you should be prepared for that. As the software seems stable enough, any small deviation from the tested scenario’s might end up in a failure. And when the system is non functional, you might also not be able to backup (user) data or move users to another pool without losing data!
When working with some user accounts, or lets say test accounts, you don’t want to lose that data. And even if you don’t care about this, you don’t want to be in the position that you need to re-build the complete environment (again).
You can prevent this all by one simple script: An application-level back-up. It’s not there by out of the box, but the powershell commands to get to such back-up are!
Before I put the script in this blogpost, I want to point out it’s actually an updated version of the script written by Traci Herr on MSDN. My thanks go out to the people who created this in the first place. I’ve updated it to work with Lync 2013, and let it make use of the newer powershell commands available. It’s not too fancy, but clean, plain and simple.
What will be backed up?
- CSConfig
- LISConfig
- RGSConfig
- UserConfig
- FileStore
- Certificates
- Voice Configuration
- SQL Databases
*note: The filestore section looks foor *all* file shares. When in co-existence with your Lync 2010 environment, it will also back-up this file share. In some ocasions I changed this section to only include the 2013 one.
As for now the “standard edition” most probably will be the most common version, I”ve built the script to work on one of those. But with a simple change in the section “variables” (change PoolName and SQLInstance variables) this can be undone. I deliberately didn’t include them as command-line options, as the script must be fairly easy and able to run unattended.
Last but not least, for the SQL backup I recommend a full SQL backup rather than using this script, but it might come in handy some time. however, this section might need some update to be more universal and complete.
That said, here is the script:
# Backup Script for Microsoft Lync 2013 # Put this into "c:\backup" folder cd c:\backup Import-Module 'C:\Program Files\Common Files\Microsoft Lync Server 2013\Modules\Lync\Lync.psd1' # Get FQDN $sysinfo = Get-WmiObject -Class Win32_ComputerSystem $fqdn = “{0}.{1}” -f $sysinfo.Name, $sysinfo.Domain # variables $PoolName = "$fqdn" $SQLInstance = "$fqdn\rtc" # Backup CSConfig New-Item c:\backup\CSconfig -type directory -force $CSconfigFile = "c:\backup\CSconfig\{0:yyyy.MM.dd-HH.mm}-CSconfig.zip" -f (Get-Date) export-csconfiguration -Filename $CSconfigFile -Force:$True # Backup LISConfig New-Item c:\backup\LISconfig -type directory -force $LISconfigFile = "c:\backup\LISconfig\{0:yyyy.MM.dd-HH.mm}-LISconfig.zip" -f (Get-Date) export-cslisconfiguration -Filename $LISconfigFile # Backup RGSConfig New-Item c:\backup\RGSconfig -type directory -force $RGSconfigFile = "c:\backup\RGSconfig\{0:yyyy.MM.dd-HH.mm}-RGSconfig.zip" -f (Get-Date) Export-CsRgsConfiguration -FileName $RGSconfigFile -source $PoolName # Backup UserConfig New-Item c:\backup\UserConfig -type directory -force $UserConfigFile = "c:\backup\UserConfig\{0:yyyy.MM.dd-HH.mm}-Userconfig.zip" -f (Get-Date) Export-CsUserData -PoolFqdn $PoolName -FileName $UserConfigFile # Backup FileStore New-Item c:\backup\FileStore -type directory -force Get-CSService -filestore | Select-Object UncPath,PoolFqdn | ForEach-Object {$Pool = "c:\backup\FileStore\"+$_.PoolFqdn; invoke-expression 'ROBOCOPY.EXE $_.UncPath $Pool *.* /E /B /PURGE /R:1 /W:2'} # Backup Certificates with Private Keys New-Item c:\backup\Cert -type directory -force dir cert:\localmachine\my | Where-Object { $_.hasPrivateKey } | Foreach-Object { [system.IO.file]::WriteAllBytes( "c:\backup\Cert\$($_.thumbprint).pfx", ($_.Export('PFX', 'secret')) ) } cd c:\backup # Backup Voice Configurations New-Item c:\backup\Voice -type directory -force $DialPlan = "c:\backup\Voice\{0:yyyy.MM.dd}-DialPlan.xml" -f (Get-Date) Get-CsDialPlan | Export-Clixml -path $DialPlan $VoicePolicy = "c:\backup\Voice\{0:yyyy.MM.dd}-VoicePolicy.xml" -f (Get-Date) Get-CsVoicePolicy | Export-Clixml -path $VoicePolicy $VoiceRoute = "c:\backup\Voice\{0:yyyy.MM.dd}-VoiceRoute.xml" -f (Get-Date) Get-CsVoiceRoute | Export-Clixml -path $VoiceRoute $PSTNUsage = "c:\backup\Voice\{0:yyyy.MM.dd}-PSTNUsage.xml" -f (Get-Date) Get-CsPstnUsage | Export-Clixml -path $PSTNUsage $VoiceConfiguration = "c:\backup\Voice\{0:yyyy.MM.dd}-VoiceConfiguration.xml" -f (Get-Date) Get-CsVoiceConfiguration | Export-Clixml -path $VoiceConfiguration $TrunkConfiguration = "c:\backup\Voice\{0:yyyy.MM.dd}-TrunkConfiguration.xml" -f (Get-Date) Get-CsTrunkConfiguration | Export-Clixml -path $TrunkConfiguration # Backup All SQL databases New-Item c:\backup\SQL -type directory -force osql -E -S $SQLInstance -i c:\backup\backup.sql
Save this in a *.ps1 file.
And:
DECLARE @name VARCHAR(50) -- database name DECLARE @path VARCHAR(256) -- path for backup files DECLARE @fileName VARCHAR(256) -- filename for backup DECLARE @fileDate VARCHAR(20) -- used for file name SET @path = 'C:\Backup\SQL' SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112) DECLARE db_cursor CURSOR FOR SELECT name FROM master.dbo.sysdatabases WHERE name NOT IN ('master','model','msdb','tempdb') OPEN db_cursor FETCH NEXT FROM db_cursor INTO @name WHILE @@FETCH_STATUS = 0 BEGIN SET @fileName = @path + @name + '_' + @fileDate + '.BAK' BACKUP DATABASE @name TO DISK = @fileName FETCH NEXT FROM db_cursor INTO @name END CLOSE db_cursor DEALLOCATE db_cursor
Save this as backup.sql.
Save both files to c:\backup on your Lync 2013 front-end server. Now you can run the PS1 powershell script manually (but elevated: “run as administrator”) to start the on-line backup process, or create a schedulded task to do so for you!
All output will be saved in c:\backup and will take approximately 50 MB, not counting the lync file share sizes. Zip it all and you have a complete application-level backup!
Make sure you run this periodically, and/or before making changes to the environment. you never now if, or when, something goes wrong. You are warned.