Skype for Business Backup Tool
First off I will admit that this is not ground breaking in terms of no one has done it before. I’ve ummmed and arrrrghhed about releasing this for some time as the backup script by Lasse Wedo is amazing and will do a great job. However, I believe that my script tool brings some added value to the table and offers something a little different. For this reason I have decided it is worth a release to the community.
Overview
The backup tool is a PowerShell script that has several modes of backup, ranging from a full Skype for Business backup to modular backups for backing up policies, or configurations, or topology etc. This script can be run as a scheduled task or ad-hoc using PowerShell. It can be run from a management workstation with the Skype for Business management tools installed or from a front end server. Each backup process has been written as a separate function that allows you to be selective in what you want to backup. When run, the script will create the required root and log directory on the machine using the default path C:\sfb_backup. This can be changed by editing the first few lines of the script.
Features
- Back up Topology
- Back up CMS Database
- Back up Persistent Chat Database
- Back up User Data
- Back up File Share
- Back up All Policies
- Back up All Configuration
- Back up Response Groups
- Send Email to admin on completion (Full Backup Only)
- Compress Backup file to ZIP (Full Backup Only)
- Full Logging capabilities
- Progress indicator
Requirements
The server or workstation you are running this script on, must have the Skype for Business Management Tools installed. The PowerShell Execution Security should be set to RemoteSigned, or Unrestricted mode
Set-ExecutionPolicy Unrestricted
Operation
First, open the script and set your backup directory by changing the $backupfolder variable value. Once set scroll down to the Routines section marked in the script as ## ROUTINES ##. Uncomment the commandlet(s) you want to execute and save the script. Now you can execute the script using scheduled tasks or by executing the script directly.
Estimated times for a backup to complete will vary on the amount of data held in your databases and file share. If you use Lync Phone Edition, the script will back-up all firmware installed so this can add many Gigabytes to the backup. Average backup times for a 2GB file share is about 12 minutes
Updates
20/01/2016 – Added support for backing up Shared Line Appearance and introduced compatibility for Normalization rules added by Ken Lasko’s normalization tool
Current Version
The current supported version is 3.2
Download
The script is available to download from Microsoft TechNet here
Screenshots
Backup Folder Structure
Log Files
Log File Detail
Inside the Backup Folder
Inside the Configuration Folder
Configuration Backup Detail Example
Policy Backup Folder
Policy Backup Detail
Email Example
Commandlets
Backup All – Backup-All
The Backup-All commandlet will take a full backup of the Skype for Business system by executing all the below commandlets in turn. After the backup completes the backup folder is compressed to a Zip file and you have the option to be sent an email with the backup log attached to confirm the completion of the backup.
Commandlet: Backup-All
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
MailTo |
User to Set e.g. mark@hostedhouse.co.uk |
Optional |
Specify user or distribution group email address the backup notification is to be sent to |
MailFrom |
User to Set e.g. SfbBackup@hostedhouse.co.uk |
Optional |
Specify the from address the email will be sent from. Your SMTP server should accept unauthenticated emails from the server which you are running the script from. Or the email address you use here must exist on your SMTP server. |
SMTPServer |
User to Set e.g. ex01.hostedhouse.local |
Optional |
Although listed as optional it is required if you want the email to be sent |
Example:
Backup-All –FilePath $backupfolder –LogFile $logfile –MailTo mark@hostedhouse.co.uk –MailFrom backup@hostedhouse.co.uk –SMTPServer ex01.hostedhouse.local |
Backup CMS Data – Backup-CMS
The Backup-CMS commandlet will take a backup of the Central Management Database data and save it to a zip file within the backup folder
Commandlet: Backup-CMS
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
All |
$false |
System Use Only |
This is used for internal script use and should not be declared in any function. Do not use as it will cause backup directory confusion. |
Example:
Backup-CMS –FilePath $backupfolder –LogFile $logfile |
Backup Policies – Backup-Policies
The Backup-Policies commandlet will take a backup of all the Skype for Business policies within the deployment and is backed up to the following directory <backup folder>\Policies
Commandlet: Backup-Polices
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
All |
$false |
System Use Only |
This is used for internal script use and should not be declared in any function. Do not use as it will cause backup directory confusion. |
Example:
Backup-Policies –FilePath $backupfolder –LogFile $logfile |
Backup Configuration – Backup-Configuration
The Backup-Configuration commandlet will take a backup of all the configuration settings within your deployment. This is an extensive list of configuration that is backed up to the following directory <backup folder>\Configuration
Commandlet: Backup-CMS
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
All |
$false |
System Use Only |
This is used for internal script use and should not be declared in any function. Do not use as it will cause backup directory confusion. |
Example:
Backup-Configuration –FilePath $backupfolder –LogFile $logfile |
Backup File Store – Backup-FileStore
The Backup-FileStore commandlet will take a backup of the Lync shared folder and copy its contents to <backup folder>\<share name>
Commandlet: Backup-FileStore
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
All |
$false |
System Use Only |
This is used for internal script use and should not be declared in any function. Do not use as it will cause backup directory confusion. |
Example:
Backup-FileStore –FilePath $backupfolder –LogFile $logfile |
Backup Persistent Chat Data – Backup-PChat
The Backup-PChat commandlet will take a backup of the Persistent Chat Database data and save it to a zip file within the backup folder
Commandlet: Backup-PChat
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
All |
$false |
System Use Only |
This is used for internal script use and should not be declared in any function. Do not use as it will cause backup directory confusion. |
Example:
Backup-PChat –FilePath $backupfolder –LogFile $logfile |
Backup Response Groups Data – Backup-RGS
The Backup-Rgs commandlet will take a backup of the configured response groups.
Commandlet: Backup-Rgs
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
All |
$false |
System Use Only |
This is used for internal script use and should not be declared in any function. Do not use as it will cause backup directory confusion. |
Example:
Backup-CMS –FilePath $backupfolder –LogFile $logfile |
Backup User Data – Backup-UserData
The Backup-UserData commandlet will take a backup of user’s data and save it to a zip file within the backup folder
Commandlet: Backup-UserData
Parameters:
Parameter |
Default Value |
Required |
Description |
FilePath |
$backupfolder |
Yes |
The $backupfolder variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the folder must already exist e.g. d:\backup\ |
LogFile |
$LogPath |
Yes |
The $logfile variable will use the default backup path that is set on script load. You can enter your own path if you wish but it must be literal and the file must already exist e.g. d:\backup\log\backup.log |
All |
$false |
System Use Only |
This is used for internal script use and should not be declared in any function. Do not use as it will cause backup directory confusion. |
Example:
Backup-UserData –FilePath $backupfolder –LogFile $logfile |
Restoring
With any backup you need a method of restoring the data, otherwise what’s the use of a backup right? I have resisted the temptation to create a restore script because there are that many different restore scenarios that it would almost be impossible to code a restore script, for free anyway. However, you can restore from the backups taken using a mixture of native Skype for Business commands and a little help from another awesome commandlet.
To restore open the Skype for Business Management Shell and change the working directory to your backup folder. From here you can reference easily the files you want to restore from.
Configuration Restore Example
So you have deleted a Call Park Orbit range, oops! No matter, I have a backup
Look for your backup file for the orbit range you have deleted.
Let’s restore it using this command
Import-CliXml –Path ‘.\CallPark\Call Park Orbit.xml’ | Set-CsCallParkOrbit
Now let’s check if it has restored
Life saved and I will live a bit longer! 🙂
Policy Restore Example
So you have deleted a Client Policy by mistake.. No bother we have a backup
Let’s restore the missing client policy using this command
Import-CliXml –Path ‘.\Client Policies\HQClientPolicy.xml’ | Set-CsClientPolicy
Now let’s check if it has been restored
Awesome. But… There is an additional step for user policy restores specifically, in that once restored, you are going to have to Grant users this policy again. However fear not. I have a script called Skype for Business User Detailed Report that you can run to find out which policies where assigned to users. So as long as you have run that prior to needing a restore, at least you have a starting point to work from.
On a side note, some of you with eyes for detail will realise that I have not added support for certificate backup. This is on purpose. When I was evaluating the benefit of putting this in, it was just as quick to request new certificates and apply them as it was to create PS Sessions to all servers for extraction and importing. And I prefer to keep control of certificate management manually because I have had a ton of pain with them in the past.
So hope you like this tool / script. I know it is nothing new, but hopefully will give you options.
Mark is an Independent Microsoft Teams Consultant with over 15 years experience in Microsoft Technology. Mark is the founder of Commsverse, a dedicated Microsoft Teams conference and former MVP. You can follow him on twitter @UnifiedVale
Thank you for the tool, great work.
Everything backups, but I’m getting an error on this part (I haven’t changed the backup path in the script):
10/28/2015 13:04:15 [ERROR] Failed to Export Configuration
10/28/2015 13:04:15 [DEBUG] The given path’s format is not supported.
Hey Miha
Could you send me the entire log file so I can take a look at what stage this happens.
mark@skype4b.uk
thanks
in this script you dont actually backup/dump the SQL server DB’s right? I am looking for something to do that AND truncate the logs???
Hi
The script exports the data out of the databases to zip files. It makes it a supported restore using PowerShell. To do what you want to do you need sql to backup using maintenance jobs.
Thanks
Hi. Can I run it on one of Front-End servers?
Hi
It can be run on any machine that has the SFB powershell module installed including Front Ends.
thanks
Great. Can it be added as scheduled task somehow? Or is there a better way to automate it?
P.s. Thank you for this script.
What would be your suggestion to automate it? Scheduled tasks? Or is there a better way?
Hi
I have to approve each comment to avoid spam. Yes you can add it as a scheduled task. just start program powershell.exe and in arguments add -file “c:\path\SkypeforBusinessBackupTool-V3.1.ps1” Make sure you choose the command in the file at the bottom to select your type of backup.
thanks
How do i set parameters in scheduled task? Just add after “Backup-All” command?
Any example would be great.
Hi
So at the bottom of the script there are a few commands commented out Backup-Policies, Backup-All etc. Backup-All is the active command by default. Therefore, if you want specific type of backup just uncomment the type of backup you want, save the script and then add as scheduled task like i described before (dont forget to comment out the Backup-All in this case or it will do both!). That should be it, I have it running in various places like this at the moment.
thanks
Hi Mark
I am getting a permissions issue when running this script, I am a domain admin and i have give permission on the folders and subfolders . But still getting the following error.
02/22/2016 21:04:40 [ERROR] Failed to Export Topology Configuration
02/22/2016 21:04:40 [DEBUG] Login failed for user ‘domain\first.last’.
Hi
Please make sure that your account is a member of CsAdministrator security group too
thanks
Thanks for the response , the account is part of CsAdministrator but everything is failing to backup.
I am getting
Get-ChildItem : Cannot find path ‘C:\S’ because it does not exist.
At C:\Scripts\SkypeforBusinessBackupTool-V3.3.ps1:13 char:1
+ Get-ChildItem $backupfolder -Recurse | ? {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\S:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
hi Mark,
Great work, indeed. Something I found though is that script doesn’t backup RGS correctly if multiple FE pools exist. I think there has to be a foreach loop inside Backup-Rgs() function something similar to this :
$rgs = Get-CsService -ApplicationServer | Where {$_.Applications -like “*rgs*”}
ForEach ($rg in $rgs)
{
Export-CsRgsConfiguration -Source “ApplicationServer:$($rg.PoolFqdn)” -FileName $FilePath”\$($rg.PoolFQDN)_RgsConfiguration.zip” -ErrorAction Stop
$stamp = Get-Date
Add-Content -Path $LogFile -Value “$($stamp) [INFO] Successfully Exported Topology Configuration to $($FilePath)\$($rg.PoolFQDN)_RgsConfiguration.zip”
oh man, solved this by myself first, then found an easy answer here 🙂
Hi,
Nice script!
However I am receiving error:
[ERROR] Failed to copy Lync Share
[DEBUG] …..Meeting.Active’ because it is being used by another process.
The script is failing because files are in use and cannot be copied. I found an article in Technet (applies to LYNC 2013 but should be the same to SfB) https://technet.microsoft.com/en-us/library/hh202171(v=ocs.15).aspx
A short quote from the page
“Files named Meeting.Active should not be backed up. These files are in use and locked while a meeting takes place.”
I think this could be considered in the next version of the script 🙂
Thanks, it’s due an update anyway, so I will add it to the list