Lync Backup Instructions

This script is to be run on a Lync Front End server that has the SQL client and tools installed

On your Lync Front End server, create a folder called “backup” on the root of C:\. Copy this into a Notepad file and name it “backup.ps1”. Copy the following three other files into the same backup folder.

***Change the SQLserver\InstanceName, LyncShare path/name as well as domain\administrator and password.***

This script backs up the CSConfig, LISConfig, Contact Lists and Conference Directories, all SQL databases and the certificates in the local Computer store

cd $env:UserProfile
Import-Module 'C:\Program Files\Common Files\Microsoft Lync Server 2010\Modules\Lync\Lync.psd1'
$filename = "c:\backup\{0:yyyy.MM.dd-HH.mm}-CSconfig.zip" -f (Get-Date)
$filename1 = "c:\backup\{0:yyyy.MM.dd-HH.mm}-LISconfig.zip" -f (Get-Date)
export-csconfiguration -Filename $filename -Force:$True
export-cslisconfiguration -Filename $filename1
c:\backup\dbimpexp.bat

osql -E -S sql2008\RTC -i c:\backup\backup.sql

Net Use b: \\sql2008\LyncShare
Xcopy B:\ c:\Backup\LyncShare /E /I /Y
Net Use B: /delete

Net Use S: \\sql2008\c$\Backup /User:Domain\Administrator p@ssw0rd1
Xcopy S:\ c:\Backup\SQLdbBackup /E /I /Y
Net Use S: /delete

dir cert:\localmachine\my |
Where-Object { $_.hasPrivateKey } |
Foreach-Object { [system.IO.file]::WriteAllBytes(
"c:\backup\$($_.thumbprint).pfx",
($_.Export('PFX', 'secret')) ) }

cd\

 

 

 

DBImpExp - Backup Contact Lists and Conference Directories  - Copy the following text and create a Batch file, name it “DBImpExp.bat” and place it in the “C:\Backup” folder

**Change the name of your SQLserver\Instance**

@ECHO OFF
REM For Standard Edition
"C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\dbimpexp.exe" /hrxmlfile:"c:\backup\DBImpExp.xml"
@ECHO OFF
REM For Enterprise Edition
REM "C:\Program Files\Common Files\Microsoft Lync Server 2010\Support\dbimpexp.exe" /hrxmlfile:"c:\<fullFilePath>.xml" /sqlserver:<sql server host name>

Backup All SQL databases

Copy this into a Notepad file and name it “backup.sql” . Save this file into the C:\Backup folder on your Lync server. Create a folder called "Backup" on your C: on your SQL server and save this file there as well

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\'

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

Backup Certificates with Private Keys - This is already built into the backup.ps1 script but it can be used by its self on other machines that are not FE servers to backup the certificates and private keys.

dir cert:\localmachine\my |

Where-Object { $_.hasPrivateKey } |

Foreach-Object { [system.IO.file]::WriteAllBytes(

"c:\backup\$($_.thumbprint).pfx",

($_.Export('PFX', 'secret')) ) }

Backup Voice Configurations (from Cscp)

 

Create a Scheduled Task in Windows

Create a new task for: powershell -command C:\Backup\backup.ps1

Now that you have all your backup files in one location, you can use Windows backup or any other backup software to backup your “c:\Backup” folder

 

 

Additionally you need to make sure that other components that Lync relies upon should be backed up:

· AD (both the RTC Service container and all users for policy and pool assignments)

· Load balancer configurations

· Firewall configurations

· DNS configurations

· DHCP configurations

· PSTN gateway configurations

The frequency of the backups should be determined by each individual company’s policies.

It is also important to make sure that you have a DR plan that includes both restoring data and plans for restoring services (user services, conferencing, etc.) during the outage.

 

 

Written By: Traci Herr, tracisy@microsoft.com, Microsoft Consulting Services, 3/8/11

Lync Backup Instructions.docx

Comments

  • Anonymous
    January 01, 2003
    Great article!  The process can also be simplified slightly by running dbimpexp from the powershell script rather than invoking a seperate .bat file: invoke-expression 'C:"Program Files""Common Files""Microsoft Lync Server 2010"Supportdbimpexp.exe /hrxmlfile:$filename2 /sqlserver:<sql server fqdn> This also enables you to supply a variable ($filename2 in this case) to add a date and time stamp to the filename as with the other exports... $filename2 = "c:backup{0:yyyy.MM.dd-HH.mm}-RTCPersistentData.hrxml" -f (Get-Date) Thanks

  • Anonymous
    January 01, 2003
    Hi Tracy, I've put together your script with some of the suggestion above, this is the result. I've removed the need to edit teh script, every information about the name of the server, the SQL DB etc etc is get from the Lync infrastructure. I've tested this script in some customers working environment, everything was fine. I hope this could help some other Lync guy :-) Regards. Luca


Backup Script for Microsoft Lync 2010

Put this into "C:Backup" folder

cd C:Backup Import-Module 'C:Program FilesCommon FilesMicrosoft Lync Server 2010ModulesLyncLync.psd1'

Get FQDN

$sysinfo = Get-WmiObject -Class Win32_ComputerSystem $fqdn = “{0}.{1}” -f $sysinfo.Name, $sysinfo.Domain

Backup CSConfig

New-Item c:BackupCSconfig -type directory -force $CSconfigFile = "C:BackupCSconfig{0:yyyy.MM.dd-HH.mm}-CSconfig.zip" -f (Get-Date) export-csconfiguration -Filename $CSconfigFile -Force:$True

Backup LISConfig

New-Item c:BackupLISconfig -type directory -force $LISconfigFile = "c:backupLISconfig{0:yyyy.MM.dd-HH.mm}-LISconfig.zip" -f (Get-Date) export-cslisconfiguration -Filename $LISconfigFile

Backup All SQL databases

New-Item c:BackupSQL -type directory -force $SQLInstance = Get-CsConfigurationStoreLocation $SQLFQDN = Get-CsService -CentralManagement | Select-Object PoolFqdn $SQLServer = $SQLFQDN.PoolFqdn.tolower() osql -E -S $SQLInstance -i C:Backupbackup.sql if ($SQLServer -ne $fqdn.tolower()) { invoke-expression 'ROBOCOPY.EXE $SQLServerC$BackupSQL c:BackupSQL . /E /B /PURGE /R:1 /W:2' }

Backup Contact Lists and Conference Directories

New-Item c:BackupRTCPersistentData -type directory -force $RTCPersistentDataFile = "c:backupRTCPersistentData{0:yyyy.MM.dd-HH.mm}-RTCPersistentData.hrxml" -f (Get-Date) invoke-expression 'C:"Program Files""Common Files""Microsoft Lync Server 2010"Supportdbimpexp.exe /hrxmlfile:$RTCPersistentDataFile /sqlserver:$SQLInstance'

Backup File Store for every Pool

New-Item c:BackupFileStore -type directory -force Get-CSService -filestore | Select-Object UncPath,PoolFqdn | ForEach-Object {$Pool = "C:BackupFileStore"+$.PoolFqdn; invoke-expression 'ROBOCOPY.EXE $.UncPath $Pool . /E /B /PURGE /R:1 /W:2'}

Backup Certificates with Private Keys

New-Item c:BackupCert -type directory -force dir cert:localmachinemy |   Where-Object { $.hasPrivateKey } |   Foreach-Object { [system.IO.file]::WriteAllBytes(     "c:BackupCert$($.thumbprint).pfx",     ($_.Export('PFX', 'secret')) ) } cd C:Backup

Backup Voice Configurations

New-Item c:BackupVoice -type directory -force $DialPlan = "c:BackupVoice{0:yyyy.MM.dd}-DialPlan.xml" -f (Get-Date) Get-CsDialPlan | Export-Clixml -path $DialPlan $VoicePolicy = "c:BackupVoice{0:yyyy.MM.dd}-VoicePolicy.xml" -f (Get-Date) Get-CsVoicePolicy | Export-Clixml -path $VoicePolicy $VoiceRoute = "c:BackupVoice{0:yyyy.MM.dd}-VoiceRoute.xml" -f (Get-Date) Get-CsVoiceRoute | Export-Clixml -path $VoiceRoute $PSTNUsage = "c:BackupVoice{0:yyyy.MM.dd}-PSTNUsage.xml" -f (Get-Date) Get-CsPstnUsage | Export-Clixml -path $PSTNUsage $VoiceConfiguration = "c:BackupVoice{0:yyyy.MM.dd}-VoiceConfiguration.xml" -f (Get-Date) Get-CsVoiceConfiguration | Export-Clixml -path $VoiceConfiguration $TrunkConfiguration = "c:BackupVoice{0:yyyy.MM.dd}-TrunkConfiguration.xml" -f (Get-Date) Get-CsTrunkConfiguration | Export-Clixml -path $TrunkConfiguration

  • Anonymous
    April 27, 2011
    The comment has been removed

  • Anonymous
    June 24, 2011
    I added this section to the backup.ps1 script and it seems to do the trick.    Thanks for your comments. New-Item c:BackupVoice -type directory -force Get-CsDialPlan | Export-Clixml -path c:backupVoiceDialPlan.xml Get-CsVoicePolicy | Export-Clixml -path c:backupVoiceVoicePolicy.xml Get-CsVoiceRoute | Export-Clixml -path c:backupVoiceVoiceRoute.xml Get-CsPstnUsage | Export-Clixml -path c:backupVoicePSTNUsage.xml Get-CsVoiceConfiguration | Export-Clixml -path c:backupVoiceVoiceConfiguration.xml Get-CsTrunkConfiguration | Export-Clixml -path c:backupVoiceTrunkConfiguration.xml

  • Anonymous
    July 18, 2011
    您好! 我只能给你中文说...看你会不会看中文... 你上面加了Voice的...没写到你的博文中去.也没加到你的backup.ps1中去! 再有. 你的Sql备份也太简单了些吧! 我在研究中. Sql备分正常应该.按数据库分别产生目录.... 每个数据库一个目录.如果每一次备份.都应该是产生一个新文件。况且..应该..删除一个月前.或者一个星期前的备份... 这些在你的sql中都没考虑到... 如果你能看懂中文.希望... 你改下你的sql... 谢谢...一直观注中....! LiuJinFeng@msn.com

  • Anonymous
    July 18, 2011
    The comment has been removed

  • Anonymous
    July 18, 2011
    Hi LiuJinFeng,  I used a translator to understand what you wrote, however it did not do the best translation to english.  Just to verify, I think you are making comments about the SQL backup portion of the backup.ps1 script.   From my experience, most companies that I have deployed Lync for want to backup the SQL databases seperately and keep them with their other SQL databases.  This way they can manage how long they are kept and they can add the dates to the backup files.  

  • Anonymous
    July 19, 2011
    Hi Traci Herr,Sorry.我对英语的写作不好.能看懂欠写的.. 我在努力改你写的东西..在项目中去运用! 如果有兴趣可以再交流.backup.sql我已改成了我想要的. 另外对你的语句进行了加工..不是所有的文件放在一个大目录中. 再有..好多文件也加上了备份日期...但是...像产生的配置文件...你的有两个是加日期的.. 但是后须你在博中回答问题的那些都没加日期...被我改了.. 针对所有产生的备份文件.我在前面加年月日了..也就每天产生文件. 但是产是产生了...如何来删除呢.还是一个问题. 如果你能提供更完善的,那就太感谢你! 附: #New-Item c:BackupVoice -type directory -force #Get-CsDialPlan         | Export-Clixml -path E:Lync_Backup2_ConfigDialPlan.xml $DialPlan  = "E:Lync_Backup2_Config{0:yyyy.MM.dd}-DialPlan.xml" -f (Get-Date) Get-CsDialPlan         | Export-Clixml -path $DialPlan #Get-CsVoicePolicy     | Export-Clixml -path E:Lync_Backup2_ConfigVoicePolicy.xml $VoicePolicy  = "E:Lync_Backup2_Config{0:yyyy.MM.dd}-VoicePolicy.xml" -f (Get-Date) Get-CsVoicePolicy     | Export-Clixml -path $VoicePolicy #Get-CsVoiceRoute       | Export-Clixml -path E:Lync_Backup2_ConfigVoiceRoute.xml $VoiceRoute  = "E:Lync_Backup2_Config{0:yyyy.MM.dd}-VoiceRoute.xml" -f (Get-Date) Get-CsVoiceRoute     | Export-Clixml -path $VoiceRoute #Get-CsPstnUsage       | Export-Clixml -path E:Lync_Backup2_ConfigPSTNUsage.xml $PSTNUsage  = "E:Lync_Backup2_Config{0:yyyy.MM.dd}-PSTNUsage.xml" -f (Get-Date) Get-CsPstnUsage     | Export-Clixml -path $PSTNUsage #Get-CsVoiceConfiguration | Export-Clixml -path E:Lync_Backup2_ConfigVoiceConfiguration.xml $VoiceConfiguration  = "E:Lync_Backup2_Config{0:yyyy.MM.dd}-VoiceConfiguration.xml" -f (Get-Date) Get-CsVoiceConfiguration     | Export-Clixml -path $VoiceConfiguration #Get-CsTrunkConfiguration | Export-Clixml -path E:Lync_Backup2_ConfigTrunkConfiguration.xml $TrunkConfiguration  = "E:Lync_Backup2_Config{0:yyyy.MM.dd}-TrunkConfiguration.xml" -f (Get-Date) Get-CsTrunkConfiguration     | Export-Clixml -path $TrunkConfiguration

  • Anonymous
    July 19, 2011
    @ECHO OFF REM For Standard Edition "C:Program FilesCommon FilesMicrosoft Lync Server 2010Supportdbimpexp.exe" /hrxmlfile:"c:backupDBImpExp.xml" 如果: CD "C:Program FilesCommon FilesMicrosoft Lync Server 2010Support" dbimpexp.exe" /hrxmlfile:"c:backupDBImpExp.xml" 不会报任何错误.. 但是.. 在*.bat中.. 执行整个PS1的时候...报文件名.目录名或者卷标语法错误.不知道你的是否报错... 试过好多次没法解决....!

  • Anonymous
    July 19, 2011
    下面是改过后的Sql... 不过也有一个问题.备份每个数据库的时候.出现.... 文件名.目录名或者卷标语法错误 但是备份是成功的....! 1.备份根据每个数据库产生一个文件夹 2.删除7天前数据库备份 3.文件命名为数据库名_年_月_日


--Backup_Sql.docx 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 DECLARE @tempfileDate VARCHAR(20) -- used for file name SET @path = 'E:Lync_Backup1_Sql'   SELECT @fileDate =REPLACE(CONVERT(VARCHAR(10),GETDATE(),120),'-',''); 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         DECLARE @DataPath nvarchar(500)       DECLARE @DirTree TABLE (subdirectory nvarchar(255), depth INT)       SET @DataPath = @path + @name       INSERT INTO @DirTree(subdirectory, depth)   EXEC master.sys.xp_dirtree @DataPath   IF NOT EXISTS (SELECT 1 FROM @DirTree WHERE subdirectory = @name)   EXEC master.dbo.xp_create_subdir @DataPath       SET @fileName = @path + @name +''+@name+ '' + @fileDate + '.BAK'         BACKUP DATABASE @name TO DISK = @fileName         DECLARE @TempFilePath varchar(255)       DECLARE @TempFileName varchar(255)       set @TempFilePath= @path + @name +'';       set @TempFileName=@TempFilePath+@name+ '' + REPLACE(CONVERT(VARCHAR(10),DATEADD(day,-7,GETDATE()),120),'-','');       set @TempFileName='del"'+@TempFileName+&#39;.bak"';       --print @TempFileName       exec     master..xp_cmdshell @TempFileName       FETCH NEXT FROM db_cursor INTO @name   END   CLOSE db_cursor   DEALLOCATE db_cursor

  • Anonymous
    July 21, 2011
    This is Backup.sql.Please See! This is very good! Thank my firends.

EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE; --Backup_Sql.docx 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 DECLARE @tempfileDate VARCHAR(20) -- used for file name SET @path = 'E:Lync_Backup1_Sql'   SELECT @fileDate =REPLACE(CONVERT(VARCHAR(10),GETDATE(),120),'-',''); 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         DECLARE @DataPath nvarchar(500)       DECLARE @DirTree TABLE (subdirectory nvarchar(255), depth INT)       SET @DataPath = @path + @name       INSERT INTO @DirTree(subdirectory, depth)   EXEC master.sys.xp_dirtree @DataPath   IF NOT EXISTS (SELECT 1 FROM @DirTree WHERE subdirectory = @name)   EXEC master.dbo.xp_create_subdir @DataPath       SET @fileName = @path+@name+''+@name+'_'+@fileDate+&#39;.BAK'         BACKUP DATABASE @name TO DISK = @fileName       DECLARE @TempFilePath varchar(255)       DECLARE @TempFileName varchar(255)       set @TempFilePath= @path + @name +'';       set @TempFileName=@TempFilePath+@name+'_'+REPLACE(CONVERT(VARCHAR(10),DATEADD(day,-7,GETDATE()),120),'-&#39;,'');       set @TempFileName='del"'+@TempFileName+&#39;.bak"';       print @TempFileName       declare @result int       exec xp_fileexist @TempFileName, @result output       if @result=1           exec     master..xp_cmdshell @TempFileName       FETCH NEXT FROM db_cursor INTO @name   END   CLOSE db_cursor   DEALLOCATE db_cursor

  • Anonymous
    August 26, 2011
    Nice job Traci! How about a description of how to use each of the items you've automated the backup for...in a RESTORE process? Thanks,

  • Anonymous
    January 30, 2012
    Job well done Traci, like TygaB said above, how about the restore process?

  • Anonymous
    March 18, 2012
    LOL, I think this was written as a backup-only solutiuon, the writer of the article wasnt interested in restore anytime. Or the owner of the blog doesnt read our comments?

  • Anonymous
    October 17, 2012
    Dear LucaVitali, I have tested your PS, and it runs smoothly, but still have a little bug as below: You should modify the backup.sql file: SET @path = 'C:Backup' to SET @path = 'C:BackupSQL'   Then, all the DB backup file can capture into c:backupsql. Thanks, Nemo

  • Anonymous
    January 08, 2013
    Hi Traci Herr Isn't better to use "robocopy src dst /MIR" for lyncShare directory? Should speed-up backup process significantly. Regards, Marko