Backing up Windows Azure Pack: Web Sites

 

Applies To: Windows Azure Pack

Backing up Windows Azure Pack: Web Sites involves three major components: the Web Sites Controller, SQL Server, and the File Server. Links to the respective sections are provided below.

A. Web Sites Controller Backup

B. SQL Server Backup

C. File Server Backup

A. Web Sites Controller Backup

In order to back up the Web Sites Controller, you can use the Backup.ps1 PowerShell script presented in this section. This script invokes the Windows Volume Shadow Service (VSS) writer to perform the backup.

Copy the Backup.ps1 script onto the Web Sites Controller, and then run the following command with Administrator privileges:

net use /Y $backupLocation /user:$backupMachineAdmin $backupMachinePassword  
.\Backup.ps1 $backupLocation $encryptionKey  

Note

The $encryptionKey flag is optional, but it is highly recommended as an added security precaution.

Warning

Do not forget the encryption key, because it is not stored for you in any way.

The Backup.ps1 script follows.

##  Script to backup the controller using the Hosting VSS writer  
  
param (  
[parameter(Position=2)]  
$backupPath,  
[parameter(Position=3)]  
$passphrase  
)  
  
function ShowHelp  
{  
    Write-Host '===================== BACKUP.PS1 HELP ====================='  
    Write-Host 'This is a script that uses the Hosting VSS writer and creates a backup of the keys and offline feed'  
    Write-Host 'Invoke it using .\Backup.ps1 and follow the prompts'  
    Write-Host 'It can also be invoked as follows:'  
    Write-Host '.\Backup.ps1 <Backup path> <passphrase to encrypt keys with>'  
Write-Host "Note: before running this script you may need to run:`r`n   'net use /Y <Backup path> /user:<username> <password>'"  
    Write-Host '==========================================================='  
}  
  
function CopyFiles  
{  
    # copy from the exposed location to where we're backing up to  
    $commands = @()  
    # $exposedDrive is the VSS shadow copy drive  
    $commands += "'D' | xcopy /Y /q /E '${exposedDrive}:\$feedLocationNQ' '$backupPath\$feedLocationNQ'"  
    $commands += "'F' | xcopy /Y /q '${systemDrive}encryptedkeys.txt' '$backupPath'"  
    # wrap each command in retry logic  
    foreach ($command in $commands)  
    {  
        $final += ('$c = 0' +"`r`n")  
        $final += ('do {'+"`r`n")  
        $final += (' $c++' + "`r`n Start-Sleep -s 2`r`n ")  
        $final += ($command + "`r`n")  
        $final += '} while (!($?) -and $c -lt 10)'+"`r`n"  
        $command = $command -replace "'", '"'  
        $final += ('if($?)'+"{'Successfully executed: $command'}`r`n")  
        $final += ("else{ 'There was a problem executing: $command'}`r`n")  
    }  
    $final | Set-Content "copyfiles.ps1"     
}  
  
function EncryptKeys($keysFile, $passphrase, $salt, $init, $systemDrive)  
{  
    $encryptscript = @"  
function EncryptString(`$keysFile, `$passphrase, `$salt, `$init)   
{   
    `$ret = @()  
    `$stringsToEncrypt = (Get-Content `$keysFile)  
    foreach (`$stringToEncrypt in `$stringsToEncrypt)  
    {  
        `$r = new-Object System.Security.Cryptography.RijndaelManaged  
        `$pass = [Text.Encoding]::UTF8.GetBytes(`$passphrase)  
        `$salt = [Text.Encoding]::UTF8.GetBytes(`$salt)  
        `$r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes `$pass, `$salt, 'SHA1', 5).GetBytes(32) #256/8   
        `$r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes(`$init) )[0..15]        
        `$c = `$r.CreateEncryptor()   
        `$ms = new-Object IO.MemoryStream   
        `$cs = new-Object Security.Cryptography.CryptoStream `$ms,`$c,'Write'  
        `$sw = new-Object IO.StreamWriter `$cs   
        `$sw.Write(`$stringToEncrypt)   
        `$sw.Close()   
        `$cs.Close()   
        `$ms.Close()   
        `$r.Clear()   
        [byte[]]`$result = `$ms.ToArray()   
        `$ret += [Convert]::ToBase64String(`$result)  
    }  
    return `$ret  
}  
  
"@      
    $encryptscript += "EncryptString '$keysFile' '$passphrase' '$salt' '$init' > '${systemDrive}encryptedkeys.txt'"  
    # $encryptscript += \"`r`ndel ${systemDrive}keys.txt\"  
    $encryptscript | set-content "encryptkeys.ps1"  
}  
  
if ($backupPath -and $backupPath.Contains('/?'))  
{   
    ShowHelp  
    return  
}  
Write-Host 'Starting the backup process. Run with /? to see help.'  
Write-Host "Note: before running this script you may need to run:`r`n   'net use /Y <backupPath> /user:<username> <password>'"  
# argument parsing  
if (!$backupPath)  
{  
    $backupPath = Read-Host "Please enter the fully qualified backup path (e.g. \\backupmachine\C$\backuplocation)"  
}  
if (!$passphrase)  
{  
    $passphrase = Read-Host "Please enter a passphrase to encrypt keys (leave blank for no encryption)"  -AsSecureString  
if (!$passphrase)  
{  
$passphrase = ""  
}  
else  
{  
$passphrase = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($passphrase))  
}  
}  
  
$usedDisks = ((Get-WmiObject -Class Win32_LogicalDisk).DeviceID|%{$_ -replace ':',''})  
foreach ($l in ([char[]]([char]'a'..[char]'z')))  
{  
    if ($usedDisks -notcontains $l)  
    {  
        $exposedDrive = $l  
        break  
    }  
}  
  
$logfile = "backup.log"  
$metadataLocation = 'metadata.cab'  
# expand environment variables  
$backupPath = ([System.Environment]::ExpandEnvironmentVariables($backupPath))  
$systemDrive = [System.Environment]::ExpandEnvironmentVariables('%systemdrive%\')  
$feedLocation = "${systemDrive}HostingOfflineFeed"  
$feedLocation = ([System.Environment]::ExpandEnvironmentVariables($feedLocation))  
$feedLocationNQ = Split-Path $feedLocation -NoQualifier  
$feedLocationNQ = $feedLocationNQ.TrimStart('\')  
$letterLocation = Split-Path $feedLocation -Qualifier   
$letterLocation = $letterLocation -replace ':',''   
# create powershell scripts  
EncryptKeys "${systemDrive}keys.txt" $passphrase "salt12345" "init12345" $systemDrive  
CopyFiles  
# backup using diskshadow  
$diskshadowScript += "set context persistent`r`n"  
$diskshadowScript += "set metadata ${letterLocation}:\${metadataLocation}`r`n"  
$diskshadowScript += "begin backup`r`n"  
$diskshadowScript += "add volume ${feedLocation} alias ${feedLocationNQ}`r`n"  
$diskshadowScript += "writer verify {079462f1-1079-48dd-b3fb-ccb2f2934ecf}`r`n"  
$diskshadowScript += "create`r`n"  
# copy files  
$diskshadowScript += "expose %${feedLocationNQ}% ${exposedDrive}: `r`n"  
$diskshadowScript += "exec ${env:windir}\System32\WindowsPowerShell\v1.0\powershell.exe .\encryptkeys.ps1`r`n"  
$diskshadowScript += "exec ${env:windir}\System32\WindowsPowerShell\v1.0\powershell.exe .\copyfiles.ps1`r`n"  
$diskshadowScript += "unexpose %${feedLocationNQ}%`r`n"  
$diskshadowScript += "end backup`r`n"  
$diskshadowScript += "delete shadows all`r`n"  
$diskshadowScript += "exit`r`n"  
$diskshadowScript | Set-Content "diskshadow1.txt"  
write-host "===================== BEGINNING BACKUP ===================="  
diskshadow /s "diskshadow1.txt" > $logfile  
write-host "===================== BACKUP COMPLETE ====================="  
write-host "======================= CLEANING UP ======================="  
#  CLEAN UP  
del ${letterLocation}:\${metadataLocation} # metadata.cab  
del "diskshadow1.txt"  
write-host "===================== DONE CLEANING UP ===================="  
write-host "=============== SEE BACKUP.LOG FOR DETAILS ================"  
del "copyfiles.ps1"  
del "encryptkeys.ps1"  
del "${systemDrive}encryptedkeys.txt"  
del "${systemDrive}keys.txt"  
  

B. SQL Server Backup

In backing up SQL Server, you must back up the Hosting database, the Resource Metering database, and the master database. Because each user's SQL environment is different, no one script can fit every user's requirements. The following example script is provided for illustrative purposes only and is unsupported. The script that you create must be run with administrative privileges.

Sample SQL Server Backup Script

Note

This script is not supported by Microsoft.

param ([string] $backupUser = "Administrator", $backupPassword, $sqlServer, $sqlUser = "sa", $sqlPassword, $backupLocation = "\\backupMachine\c$\Backup")  
sqlcmd -S $sqlServer -U $sqlUser -P $sqlPassword -Q "BACKUP DATABASE [Hosting] TO DISK='C:\HostingOfflineFeed\Hosting.bak'"  
sqlcmd -S $sqlServer -U $sqlUser -P $sqlPassword -Q "BACKUP DATABASE [ResourceMetering] TO DISK='C:\HostingOfflineFeed\ResourceMetering.bak'"  
sqlcmd -S $sqlServer -U $sqlUser -P $sqlPassword -Q "BACKUP DATABASE [master] TO DISK='C:\HostingOfflineFeed\master.bak'"  
net use $backupLocation /user:$backupUser $backupPassword  
xcopy /Y /q C:\HostingOfflineFeed\Hosting.bak $backupLocation\  
xcopy /Y /q C:\HostingOfflineFeed\ResourceMetering.bak $backupLocation\  
xcopy /Y /q C:\HostingOfflineFeed\master.bak $backupLocation\  
del C:\HostingOfflineFeed\Hosting.bak  
del C:\HostingOfflineFeed\ResourceMetering.bak  
del C:\HostingOfflineFeed\master.bak  

C. File Server Backup

When backing up the File Server, you must back up the WebSites share, the ACLs for the previously stated folder, and the File Server Resource Manager (FSRM) quotas for the WebSites share.

Note

The Certificate share isn't used in Windows Azure Pack Web Sites V2 Update Rollup 6 or later. If you're running an earlier version of Windows Azure Pack Web Sites V2, make sure to back up the Certificates share and ACLs.

Because each user's File Server environment is different, no one script can fit every user's requirements. The following example scripts are provided for illustrative purposes only and are unsupported. The scripts that you create must be run with administrative privileges.

Sample File Server Backup Script

Note

This script is not supported by Microsoft.

param ([string] $backupUser = "Administrator", $backupPassword, $websiteFolder = "C:\websites", $backupLocation = "\\backupmachine\c$\backup" )
net use $backupLocation /user:$backupUser $backupPassword
xcopy /Y /q /E $websiteFolder $backupLocation\ 

Sample FSRM Quota Data Backup Script

Note

This script is not supported by Microsoft.

param ([string] $backupUser = "Administrator", $backupPassword, $backupLocation = "\\machine\c$\backup")
net use \\$backupLocation /user:$backupUser $backupPassword
dirquota template export /File:C:\templates.xml
xcopy /Y /q C:\templates.xml $backupLocation\
net stop srmReports
net stop srmSvc
net stop quota
net stop Datascrn
robocopy "C:\System Volume Information\SRM" $backupLocation\SRM /E /ZB /R:3 /W:5
net start Datascrn
net start quota
net start srmSvc
net start srmReports 

See Also

Restoring Windows Azure Pack: Web Sites
Deploy Windows Azure Pack: Web Sites