Replica seeding to vCloud Director

One of the many use cases for Veeam Backup & Replication is disaster recovery, as the name of the product suggests it can certainly replicate virtual machines from a production environment to a secondary- or disaster recovery environment. While it is a very straight forward process running through a wizard selecting source and target environments and the start replicating the VM cross the network, you can even have your virtual machines replicated to a Veeam Cloud & Service Provider, VCSP, if you don’t have a disaster recovery site of your own. The VCSP can have a hypervisor environment built for either Microsoft Hyper-V, VMware vSphere or VMware vCloud Director. VMware vCloud Director is VMware’s multi-tenant solution to host Infrastructure as a Service and purpose built specifically for Service Providers.

In this post I’m describing the process of replicating VMs to a VCSP using a feature of Veeam Backup & Replication called Cloud Connect, I’m not going through how to setup Cloud Connect. If you need more information about the ins and outs of Cloud Connect please visit Luca Dell’Oca’s webpage about Cloud Connect.

In the hosted environment at the VCSP you can power on virtual machines if needed to keep your business going if there’s a catastrophic event at your own site for instance a lengthy power outage, load shedding, you can even create a fail-over plan dictating which virtual machines should be powered on and in which order they should start, making sure everything starts in the correct order.

Replicating over the network may not be optimal in all scenarios, at least not the first initial full replication cycle. Let’s say you have a few very large virtual machines that you want to protect by sending them to a disaster recovery site hosted by your Veeam Cloud Service Provider but it’s too big to actually be transferred over the network within the available backup window, what do you do?

In Veeam Backup & Replication you can seed an initial copy of the virtual machine to your service provider using some sort of transportable solution. USB drives, Tapes or solutions of that nature – using “sneaker net”. The basic concept is to get a copy of the virtual machine to the service provider so they can import the VM to their environment and when you start replicating over the network you just send the changes made to the VM that has occurred since you made the copy of the VM. No need for a full transfer of the VM cross the network!

So the 3 basic steps that needs to be taken:

  • Backup VM to a transportable storage device and send it to VCSP
  • The VCSP imports the VM to the correct Org vDC in vCloud Director
  • Set up a replication job at the customer site using the imported VM at the VSCP site as mapping VM

If the service provider has a multi-tenant virtualization layer, meaning built on VMware vCloud Director, the process is simple but has to been broken down into a few distinct steps. If you as a service provider are using VMware vCloud Director 9.7, these are the steps you take if the customer has Veem Backup & Replication installed that can be used:

Step 1 – Customer environment
Backup source VM (normal backup job or VeeamZip) to a portable storage solution. Either backup to C:\Backup and move the backupfile manually to the USB device or select “VeeamZIP…” and specify the target USB devices directly.

Step 2 – Customer environment

Step 3 – Customer environment

Step 4 – Customer environment
When the backup is completed it should be visible in the “Backups”-section in “Disk (VeeamZIP)”

Step 5 – Customer environment
Transfer the backupfile using a transportable storage solution (a USB drive can be used)

Step 6 – VCSP environment
Connect USB drive and import backup file to Veeam Backup & Replication running at the VCSP data center. Click “Import Backup” in the top section.

Step 7 – VCSP environment
Select the backupfile on the USB device and click “Open” (you may need to change the file type selector to “Backup files (*.vbk)” to see the backupfile.

Step 8 – VCSP environment
Now Veeam Backup & Replication will import the backup

Step 9 – VCSP environment
Right click the VM from the imported backup and select “Restore entire VM…”

Step 10 – VCSP environment

Step 11 – VCSP environment
Select “Restore to a new location, or with different settings”

Step 12 – VCSP environment
Click “Host…”

Step 13 – VCSP environment
Select a host or a cluster that is under vCloud Director management where the customer has a virtual datacenter (shows up as a resource source pool in the next few steps)

Step 14 – VCSP environment
Select the VM and click “Pool…”

Step 15 – VCSP environment
Select resource pool (Org vDC of the customer)

Step 16 – VCSP environment

Step 17 – VCSP environment

Step 18 – VCSP environment
Map network adapter to desired network in the Org vDC

Step 19 – VCSP environment

Step 20 – VCSP environment

Step 21 – VCSP environment

Step 22 – VCSP environment
Log on to vCloud Director using the flex UI (the HTML5 UI lacks the “import from vSphere” option.

If you as a service provider are using VMware vCloud Director 10 with the new HTML5 UI for providers, please note that “import from vSphere” is not available in the H5 UI. What’s even more annoying is that the flex UI has also been disable by default in vCD 10 so to be able to import the VM into the Org vDC of the customer you first need to enable the flex UI of vCD:

Enable the vCloud Director Web Console

Step 23 – VCSP environment
Import VM in vCD from vSphere

Step 24 – VCSP environment
Select “Move VM” and not “Copy VM” in Import wizard

Step 25 – VCSP environment

Step 26 – VCSP environment

Step 27 – Customer environment
Set up a new replication job at customer side

Step 28 – Customer environment
Select “Replica seeding (for low bandwidth DR sites)”

Step 29 – Customer environment
Select the source VM from the customer production hypervisor (the same used in step 1)

Step 30 – Customer environment
In the “Destination”-tab, for the “Host or cluster:”-selection. Choose “Cloud host…”

Step 31 – Customer environment
Select the Org vDC to use (same as in step 15)

Step 32 – Customer environment
Select vApp and Storage policy to be used

Step 33 – Customer environment
Select desired restore points to keep

Step 34 – Customer environment
Select desired replication mode

Step 35 – Customer environment
In the “Seeding”-tab. In the “Replica mapping” section. Select “Map replicas to exsiting VMs”, click on the VM and select edit.

Step 36 – Customer environment
Select the seeded VM from step 17

Step 37 – Customer environment

Step 38 – Customer environment
Set a desired replication schedule

Step 39 – Customer environment
If desired: Click “Run the job when I click Finish”
Click “Finish”

Step 40 – Customer environment
Verify that replication successfully finish

Step 41 – Customer environment
The replication job only transfers changed blocks since the backup/import was made

Bulk deploy Veeam Linux Proxies

In version 10 of Veeam Backup & Replication a lot of Linux love has been put in to the product. To me, one of the most interesting things is the new functionality where you can assign a Linux VM the role of a backup proxy. Historically the proxy functionality has been restricted to Windows OS only. The linux proxy does not come as a prebuilt Veeam appliance, just as with Windows proxies you still need to secure and patch the operating system. The rational behind it is easy to understand, most organizations already have some sort of patch management system in place to leverage for their production workload and you would want to have the same level of patching and security on your proxies as you have for all other workloads. I thought it would interesting to see if you could automate the deployment of proxy servers a bit. Sure enough it is a fairly simple process since Veeam Backup & Replication has a great PowerShell extension which will let you automate almost all of the tasks you can do in the GUI. As far as automating proxy servers go, my colleague Anthony Spiteri has a comprehensive project called “Project Ōtosukēru” based on Terraform which may be of interest to you as well.

As a side note, Veeam Backup & Replication version 10 contains a wide variety of new features and updates, the Veeam Vanguards made a list of their top features.

Mind you, the code below should serve as an indication of what you can do – as an example if you will. However, you use at at your own risk. I’ve put in an option to deploy to a test/lab environment (if you are lucky enough to have a lab environment) so you can start testing it out in a safe environment.

So why not combine this small project with the small Linux operating system VMware provides called PhotonOS? PhotonOS is a stripped down linux operating system we can use. Now you can certainly download an iso image and do a traditional install and set it up just the way you’d like and then convert it to a template in vSphere and make use of it that way. However I thought it would be more interesting to see how much you can automate. So instead I’m just downloading the prebuilt Linux appliance and using that as the source for my proxies.

The script performs 4 different tasks:

  • It starts by importing the settings you specified in the configuration file (config.json)
  • Download required components if they’re not available. Two components are needed: The PhotonOS OVA and a powershell script by William Lam called VMKeystrokes.ps1. VMKeystrokes is needed to change the initial password of the appliance.
  • Let’s you choose where to deploy the Linux appliance, you can pick a single host, all hosts in a specific cluster or all hosts in a specific datacenter. It will also let you choose if you’d like to deploy to a test/lab environment or to a production environment (settings fetched from config.json). The script will try to ping the IP range configured in config.json to verify that they are not being used. It then deploys the appliance to the selected target(s). Once deployed the appliance will be configured (Connecting to the specified network portgroup in vSphere, Set vCPU and vRAM, set Static IP address, firewall ports opened, configuring timezone).
  • The Linux server will then be added to Veeam Backup & Replication as a managed server. The managed server will then have the role Backup Proxy assigned to it, concurrent tasks will be set to whatever amount of vCPU’s you’ve assigned to the VM (from the configuration file).

Config.json explained
“location”: – Where files be downloaded and working directory
“ovasource”: – URL to the OVA
“ovaname”: – Name of the OVA
“ProxyBaseName”: – Base name of Proxy VM to be deployed
“ProxyvCPU”: – vCPUs to assign the Proxy VM
“ProxyvRAM”: – vRAM to assign the Proxy VM
“sshuser”: “root” – Logon account for the Proxy VM
“ovainitialpassword”: – Default password of the OVA is “changeme”
“newsshpassword”: – New password to apply for the root user on the Proxy VM

“Prod”: {
“vbrserver”: – IP adress to Veeam Backup & Replication server
“vcserver”: – IP adress to VMware vCenter Server
“network”: – Portgroup the Proxy VM will be connected to
“startipaddress”: – Start of IP pool the Proxy VMs will use
“endipaddress”: – End of IP pool the Proxy VMs till use
“vbruser”: – User to connect to Veeam Backup & Replication
“vcuser”: – User to connect to VMware vCenter Server
“vcdatacenter”: – Datacenter in vCenter to use
“gateway”: – IP address of gateway for the Proxy VM
“dns”: – IP address of DNS for the Proxy VM
“domains”: – DNS Search Domains for the Proxy VM
“ntpserver”: – NTP Server for the Proxy VM to use

The Proxy VM will be named with ProxyBaseName + IP address of the target host to where the VM is deployed with all dots replaced by dashes, i.e “VeeamProxy_10-10-50-38”.

Save the two files to c:\temp and then you’re good to go!
No more bits needed to be downloaded, the script will download what it’s required. The only thing you need to change is the settings in config.json to reflect your environment.

Download Deploy_Veeam_Linux_Proxy.ps1
Download config.json

The script will add proxies based on IP addresses to Veeam Backup & Replication in this version, but per Veeam recommendation FQDNs should be used.


  1. # Deploy_Veeam_Linux_Proxy.ps1
  2. # Version: 1.0
  3. # Author: Niclas Borgstrom, Veeam Cloud Solution Architect EMEA
  4. #
  5. # Synopsis: 
  6. # This script will download a linux appliance (based on VMware PhotonOS)
  7. # and deploy the appliance to a host, cluster or datacenter of your choice.
  8. # It will also download VMKeystrokes.ps1 by William Lam, VMware in order to 
  9. # do the initial configuration of PhotonOS.
  10. # When the OVA is deployed it will be configured with a static IP address,
  11. # firewall will be opened for Veeam Backup Proxy specific ports, vCPU and
  12. # vRAM will be changed and the VM will be added to Veeam Backup & Replication
  13. # as a managed server and then be assigned the proxy role. Concurrent tasks
  14. # will be set according to the vCPUs assigned to the VM.
  15. #
  16. # You can choose to deploy either to a production- or a test environment, if 
  17. # available. The OVA will only be deployed to powered on hosts.
  18. #
  19. # Disclaimer:
  20. # The script is for demonstration purpose only, run it at your own risk
  21. #
  22. # Credits
  23. # 'My-Logger' function by William Lam, VMware
  24. #
  25. # Prereqs:
  26. # - VMware environment managed by vCenter
  27. # - Veeam Backup & Replication already installed on a server.
  28. # - Internet access to download PhotonOS and VMKeystrokes.ps1 to change the default 
  29. #    password on the PhotonOS appliance.
  30. #
  31. # Limitations:
  32. # - Linux proxy can't be used as a 'Guest Interaction Proxy'
  33. # - Linux proxy can't be used as a 'File Backup Proxy'
  34. # - Linux Proxy only supports Hot-Add/Virtual appliance mode
  35. #
  36. # Changelog:
  37. # v 1.0: Initial release
  39. $global:BaseDirectory = "C:\temp\"
  40. $global:BaseConfig = "config.json"
  41. $verboseLogFile = $global:BaseDirectory + "Veeam_Linux_Proxy_Deployment_" + $(Get-Date -Format "yyyy-MM-dd_HH-mm") + ".log"
  43. Function My-Logger {
  44.     param(
  45.     [Parameter(Mandatory=$true)]
  46.     [String]$message
  47.     )
  49.     $timeStamp = Get-Date -Format "yyyy-MM-dd_HH:mm:ss"
  51.     Write-Host -NoNewline -ForegroundColor White "[$timestamp]"
  52.     Write-Host -ForegroundColor Green " $message"
  53.     $logMessage = "[$timeStamp] $message"
  54.     $logMessage | Out-File -Append -LiteralPath $verboseLogFile
  55. }
  57. # Load and parse the JSON configuration file 
  58. My-Logger "Loading JSON configuration file $BaseDirectory$BaseConfig"
  59. try { 
  60. 	$global:Config = Get-Content "$BaseDirectory$BaseConfig" -RAW -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | ConvertFrom-Json -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
  62. } catch { 
  63. 	My-Logger "[ERROR] The configuration files is missing!"
  64. 	Break
  65. } 
  67. # Check the configuration
  68. if (!($Config)) {
  69.     My-Logger "[ERROR] The configuration file is missing!"
  70.     Break
  71. }
  73. $location = $Config.General.location
  74. $ovasource = $Config.General.ovasource
  75. $ovaname = $Config.General.ovaname
  76. $proxybasename = $Config.General.ProxyBaseName
  77. $proxyvcpu = $Config.General.ProxyvCPU
  78. $proxyvram = $Config.General.ProxyvRAM
  79. $sshuser = $Config.General.sshuser
  80. $ovainitialpassword = $Config.General.ovainitialpassword
  81. $newsshpassword = $Config.General.newsshpassword
  83. # Set temp location
  84. Set-Location $location
  86. try {
  87. 	Add-PSSnapin -Name VeeamPSSnapin -ErrorAction Stop
  88. 	Import-Module -Name VMware.VimAutomation.Core -ErrorAction Stop
  89. } catch {
  90. 	My-Logger "[ERROR] PowerCLI or VeeamPSSnapin not installed."
  91. 	Break
  92. }
  94. # Verify that VMKeystrokes.ps1 is available
  95. My-Logger "Checking VMkeystrokes.ps1..."
  96. Clear-Host
  97. try { 
  98. 	# Dot source VMKeystrokes.ps1 if it's available
  99. 	. .\VMKeystrokes.ps1
  101. } catch {
  102. 	# If VMKeystrokes.ps1 isn't available, ask if it should be downloaded
  103. 	My-Logger "  [WARNING] Unable to find 'VMKeystrokes.ps1' in $location"
  104. 	$downloadvmkeystrokes = if(($downloadvmkeystrokes = Read-Host "`nWould you like to download it (Y/N) or press enter to accept default value [Y]") -eq '') {"Y"} else {$downloadvmkeystrokes}
  105. 	if ($downloadvmkeystrokes.ToLower() -eq "y") {
  106. 		My-Logger "  Downloading 'VMKeystrokes.ps1'"
  107. 		Invoke-WebRequest -Uri "" -OutFile ".\VMKeystrokes.ps1"
  108. 		. .\VMKeystrokes.ps1
  109. 	} else {
  110. 		My-Logger "  [ERROR] Can't continue without VMkeystrokes.ps1, exiting..."
  111. 		Break
  112. 	}
  113. }
  115. $targethosts = $null
  117. # Verify that PhotonOS it available
  118. My-Logger "Checking PhotonOS OVA..."
  119. Clear-Host
  120. if(!(Test-Path ($location + "\" + $ovaname))) {
  121. 	My-Logger "  [WARNING] Unable to find PhotonOS OVA: $($location + "\" + $ovaname)"
  122. 	$downloadova = if(($downloadova = Read-Host "`nWould you like to download it (Y/N) or press enter to accept default value [Y]") -eq '') {"Y"} else {$downloadova}
  123. 	if ($downloadova.ToLower() -eq "y") {
  124. 		My-logger "  Downloading $($location + "\" + $ovaname)"	
  125. 		Invoke-WebRequest -Uri $ovasource -OutFile $($BaseDirectory + "\" + $ovaname)
  126. 	} else {
  127. 		My-Logger "  [ERROR] PhotonOS OVA not available!"
  128. 		Break
  129. 	}
  130. }
  132. # Select where to deploy Linux Proxies
  133. Clear-Host
  134. Write-Output "`nWould you like to deploy to prod or test:`n"
  135. Write-Output "1. Production environment - $($Config.Prod.vcserver)"
  136. Write-Output "2. Test environment - $($Config.Test.vcserver)"
  137. $selectenvironment = if(($selectenvironment = Read-Host "`nSelect item or press enter to accept default value [1]") -eq '') {"1"} else {$selectenvironment}
  139. # Populate strings based on selected deployment type
  140. if ($selectenvironment -eq "1") {
  141. 	My-Logger "Deploying to Production environment $($Config.Prod.vcserver)"
  142. 	$vbrserver = $Config.Prod.vbrserver
  143. 	$vcserver = $Config.Prod.vcserver
  144. 	$network = $
  145. 	$startipaddress = $Config.Prod.startipaddress
  146. 	$endipaddress = $Config.Prod.endipaddress
  147. 	$vbruser = $Config.Prod.vbruser
  148. 	$vcuser = $Config.Prod.vcuser
  149. 	$vcdatacenter = $Config.Prod.vcdatacenter
  150. 	$gateway = $Config.Prod.gateway
  151. 	$dns = $Config.Prod.dns
  152. 	$domains = $
  153. 	$ntpserver = $Config.Prod.ntpserver
  154. } elseif ($selectenvironment -eq "2"){
  155. 	My-Logger "Deploying to Test environment $($Config.Test.vcserver)"
  156. 	$vbrserver = $Config.Test.vbrserver
  157. 	$vcserver = $Config.Test.vcserver
  158. 	$network = $
  159. 	$startipaddress = $Config.Test.startipaddress
  160. 	$endipaddress = $Config.Test.endipaddress
  161. 	$vbruser = $Config.Test.vbruser
  162. 	$vcuser = $Config.Test.vcuser
  163. 	$vcdatacenter = $Config.Test.vcdatacenter
  164. 	$gateway = $Config.Test.gateway
  165. 	$dns = $Config.Test.dns
  166. 	$domains = $
  167. 	$ntpserver = $Config.Test.ntpserver
  168. } else {
  169. 	My-Logger "[ERROR] Wrong selection..."
  170. }
  172. # Function to build a dynamic menu for infrastructure components (Datacenter, Cluster or Host)
  173. Function Get-HostList {
  174.     Param (
  175.         [Parameter(Mandatory)]
  176.         [ValidateNotNullOrEmpty()]
  177.         $ListItem,
  179.         [Parameter(Mandatory)]
  180.         [ValidateNotNullOrEmpty()]
  181.         $GetItem
  182.     )
  184.     try {
  185.         $menu = @{}
  186.         For ($i=1;$i -le $ListItem.count; $i++) { 
  187.             Write-Host "$i. $($ListItem[$i-1].Name)"
  188.             $menu.Add($i,($ListItem[$i-1].Name)) 
  189.         }
  190.         [int]$ans = if (($ans = Read-Host "`nSelect item or press enter to accept default value [1]") -eq '') {"1"} else {$ans}
  191.         $Selection = $menu.Item($ans); Invoke-Expression $($GetItem)
  192.     } catch {
  193.         Write-Host "The selection you made is unavailable, please make a valid selection between 1 and $($i-1)..."
  194.     }
  195. }
  197. # Connect to VMware vCenter Server and Veeam Backup & Replication
  198. #Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
  199. My-Logger "Connecting to VMware vCenter Server $vcserver"
  200. $vicredential = Get-Credential -UserName $vcuser -Message "Enter password for VMware vCenter server: $vcserver"
  201. Connect-VIServer $vcserver -Credential $vicredential -WarningAction SilentlyContinue
  203. My-Logger "Connecting to Veeam Backup & Replication Server $vbrserver"
  204. $vbrcredential = Get-Credential -UserName $vbruser -Message "Enter password for Veeam Backup & Replication server: $vbrserver"
  205. Connect-VBRServer -Server $vbrserver -Credential $vbrcredential -WarningAction SilentlyContinue
  207. # Select if scope of deployment
  208. Clear-Host
  209. Write-Output "`nWould you like to deploy a proxy to:`n"
  210. Write-Output "1. A Single Host"
  211. Write-Output "2. A Cluster (to all hosts in a specific cluster)"
  212. Write-Output "3. A Datacenter (to all hosts in a specific datacenter)"
  213. [int]$option = if(($option = Read-Host "`nSelect item or press enter to accept default value [2]") -eq '') {"2"} else {$option}
  215. if ($option -eq "1") {
  216. 	$MyQuery = (Get-Datacenter $vcdatacenter | Get-VMHost)
  217. 	$MyList = "Get-VMHost `$Selection | Where-Object -FilterScript { `$_.PowerState -eq 'PoweredOn' }"
  218. 	My-Logger "Deploying to Host"
  219. } elseif ($option -eq "2"){
  220. 	$MyQuery = (Get-Datacenter $vcdatacenter | Get-Cluster)
  221. 	$MyList = "Get-Cluster `$Selection | Get-VMHost | Where-Object -FilterScript { `$_.PowerState -eq 'PoweredOn' }"
  222. 	My-Logger "Deploying to Cluster"
  223. } elseif ($option -eq "3"){
  224. 	$MyQuery = (Get-Datacenter)
  225. 	$MyList = "Get-Datacenter `$Selection | Get-Cluster | Get-VMHost | Where-Object -FilterScript { `$_.PowerState -eq 'PoweredOn' }"
  226. 	My-Logger "Deploying to Datacenter"
  227. } else {
  228. 	My-Logger "Wrong selection..."
  229. }
  231. Clear-Host
  232. Write-Output "Select where to deploy Linux Proxies:`n"	
  233. $targethosts = (Get-HostList -ListItem $MyQuery -GetItem $MyList)
  235. # Verify the selected object actually contains powered on hosts
  236. if ($null -eq $targethosts) {
  237. 	My-Logger "No powered on hosts found..."
  238. 	Disconnect-VBRServer
  239. 	Disconnect-VIServer $vcserver -Confirm:$false
  240. 	Break
  241. }
  243. # Check and verify assigned IP range from config.json and verify correct IP format
  244. $deployedproxies = [ordered]@{}
  245. $iplistunverified = @()
  246. $iplistverified = @()
  247. try {
  248.     [IPADDRESS]$startip = $startipaddress
  249.     [IPADDRESS]$endip = $endipaddress
  250.     $iplistunverified += $($startip.GetAddressBytes()[3])..$($endip.GetAddressBytes()[3]) | ForEach-Object {$($startip.GetAddressBytes()[0],$startip.GetAddressBytes()[1],$startip.GetAddressBytes()[2], $_ -join '.')}
  252.     # Verify if IP addresses are available
  253.     My-Logger "Available IP addresses in range $startip to $endip :"
  254.     Clear-Host
  255.     Write-Output "Checking available IP addresses..."
  256.     foreach ($checkedip in $iplistunverified) {
  257.         if (!($(Test-Connection -BufferSize 2 -TTL 5 -ComputerName $checkedip -quiet -count 1))) {
  258.             $iplistverified += $checkedip
  259.             My-Logger "  $checkedip - available"
  260.         } else {
  261.             My-Logger "  $checkedip - in use"
  262.         }
  263.     }
  265.     if ($iplistverified.Count -lt $targethosts.count) {
  266.         My-Logger "[ERROR] Not enough IP addresses assigned, $($targethosts.count) IP addresses are needed. Please update config.json"
  267.         Disconnect-VBRServer
  268.         Disconnect-VIServer $vcserver -Confirm:$false
  269.         Break
  270.     }
  271. } catch {
  272. 	#Clear-Host
  273. 	My-Logger "[ERROR] IP address assignment is incorrect, verify in config.json"
  274. 	Disconnect-VBRServer
  275. 	Disconnect-VIServer $vcserver -Confirm:$false
  276. 	Break
  277. }
  279. # Deploy PhotonOS, change root password and assign IP settings, add VM as Managed Server and assign Proxy Role
  280. $ipincrement = 0
  281. foreach ($targethost in $targethosts) {
  282. 	My-Logger "Processing host: $targethost"
  283. 	$sw = [Diagnostics.Stopwatch]::StartNew()
  285. 	# Verify if a proxy is already present on host or deploy proxy if it's missing
  286. 	if (Get-VMHost $targethost | Get-VM | Where-Object { $_.Name -like $($ProxyBaseName + "_*") }) {
  287. 		My-Logger "  A Veeam Proxy is already deployed to host: $targethost"
  288. 	} else {	
  289. 		$ProxyName = $ProxyBaseName + "_" + ($".","-")
  290. 		My-Logger "  Importing PhotonOS OVA $ProxyName"
  291. 		$vm = Import-VApp -Source $ovaname -Name $ProxyName -VMHost $targethost -DiskStorageFormat thin
  292. 		# "VM Netork" will be used to attach NIC, must be present on host
  293. 		My-Logger "  Assigning resources to $ProxyName"
  294. 		$vm | Set-VM -NumCpu $proxyvcpu -MemoryGB $proxyvram -Confirm:$false
  295. 		$vm | Get-NetworkAdapter -Name "Network adapter 1" | Set-NetworkAdapter -Portgroup $network -Confirm:$false
  296. 		$vm | New-AdvancedSetting -Name disk.enableUUID -Value TRUE -Confirm:$false -Force:$true
  298. 		Start-VM $vm
  300. 		Wait-Tools -VM $vm
  301. 		Start-Sleep 10
  302. 		My-Logger "  VMKeystrokes: Sending user account to $vm"
  303. 		Set-VMKeystrokes -VMName $VM -StringInput $sshuser -ReturnCarriage $true
  304. 		Start-Sleep 2
  305. 		My-Logger "  VMKeystrokes: Sending inital OVA password to $vm"
  306. 		Set-VMKeystrokes -VMName $VM -StringInput $ovainitialpassword -ReturnCarriage $true
  307. 		Start-Sleep 2
  308. 		My-Logger "  VMKeystrokes: Sending initial OVA password to $vm"
  309. 		Set-VMKeystrokes -VMName $VM -StringInput $ovainitialpassword -ReturnCarriage $true
  310. 		Start-Sleep 2
  311. 		My-Logger "  VMKeystrokes: Sending new password to $vm"
  312. 		Set-VMKeystrokes -VMName $VM -StringInput $newsshpassword -ReturnCarriage $true
  313. 		Start-Sleep 2
  314. 		My-Logger "  VMKeystrokes: Sending new password to $vm"
  315. 		Set-VMKeystrokes -VMName $VM -StringInput $newsshpassword -ReturnCarriage $true
  317. 		# Install and update PhotonOS
  318. 		#
  319. 		# insert 'yum update -y' last in the $cmd section if an automatic update should be performed
  320. 		Start-Sleep 10
  321. 		$ipofvm = $iplistverified[$ipincrement]
  322. 		My-Logger "  Configuring $ProxyName with IP: $ipofvm"
  324. 		$cmd = @"
  325. 		yum install nano perl mlocate -y
  326. 		hostnamectl set-hostname $ProxyName
  327. 		iptables -A INPUT -p tcp --match multiport --dports 2500:3300 -j ACCEPT
  328. 		iptables -A OUTPUT -p icmp -j ACCEPT
  329. 		iptables -A INPUT  -p icmp  -j ACCEPT
  330. 		iptables-save >/etc/systemd/scripts/ip4save
  331. 		timedatectl set-timezone Europe/Stockholm
  332. 		echo "[Match]" > /etc/systemd/network/
  333. 		echo "Name=eth0" >> /etc/systemd/network/
  334. 		echo " " >> /etc/systemd/network/
  335. 		echo "[Network]" >> /etc/systemd/network/
  336. 		echo "Address=$ipofvm/24" >> /etc/systemd/network/
  337. 		echo "Gateway=$gateway" >> /etc/systemd/network/
  338. 		echo "DNS=$dns" >> /etc/systemd/network/
  339. 		echo "Domains=$domains" >> /etc/systemd/network/
  340. 		echo "NTP=$ntpserver" >> /etc/systemd/network/
  341. 		echo "LinkLocalAddressing=no" >> /etc/systemd/network/
  342. 		echo "IPv6AcceptRA=no" >> /etc/systemd/network/
  343. 		chmod 644 /etc/systemd/network/
  344. 		systemctl restart systemd-networkd.service
  345. 		systemctl daemon-reload
  346. "@
  348. 		My-Logger "  Invoking script on $ProxyName"
  349. 		Invoke-VMScript -VM $VM -ScriptText $cmd -GuestUser $sshuser -GuestPassword $newsshpassword -ScriptType Bash
  351. 		# Add Proxy VM to VBR as managed server and add proxy role
  352. 		if ((Get-PSSnapin VeeamPSSnapin).Version.Major -ge 10) {
  353. 			My-Logger "  Adding $ipofvm as a Veeam Managed Server"
  354. 			Add-VBRLinux -Name $ipofvm -SSHUser $sshuser -SSHPassword $newsshpassword -Description "Linux Server based on PhotonOS 3.0 Revision 2"
  355. 			My-Logger "  Adding Backup Proxy Role"
  356. 			Add-VBRViLinuxProxy -Server (Get-VBRServer -Name $ipofvm -Type Linux) -Description "Linux Backup Proxy based on PhotonOS 3.0 Revision 2" -MaxTasks $proxyvcpu -Force
  357. 			My-Logger "  Veeam Proxy was deployed to host: $targethost"
  358. 		} else {
  359. 			My-Logger "  [ERROR] You need at least Veeam Backup & Replication version 10 to add a Linux Proxy"
  360. 			Disconnect-VBRServer
  361. 			Disconnect-VIServer $vcserver -Confirm:$false
  362. 			Break
  363. 		}
  366. 		# Collect information on Proxies in hashtable for future use
  367. 		$deployedproxies.add($proxyname,$ipofvm)
  368. 		$ipincrement++
  369. 		$ipofvm = $null
  370. 		My-Logger "  Deployment of proxy took: $($sw.Elapsed.Minutes) minutes and $($sw.Elapsed.Seconds) seconds"
  371. 	}	
  372. }
  374. Clear-Host
  375. if (($deployedproxies).Count -eq 0) {
  376. 	My-Logger "[ERROR] Something went wrong, no proxies were deployed!"
  377. 	My-Logger "Check log file $verboseLogFile"
  378. 	Disconnect-VBRServer
  379. 	Disconnect-VIServer $vcserver -Confirm:$false
  380. } else {
  381. 	My-Logger "The following proxies were deployed:" 
  382. 	My-Logger $deployedproxies
  383. 	Disconnect-VBRServer
  384. 	Disconnect-VIServer $vcserver -Confirm:$false
  385. }


  1. {
  2.   "General": {
  3.     "location": "C:\\temp",
  4.     "ovasource": "",
  5.     "ovaname": "photon-hw13_uefi-3.0-9355405.ova",
  6.     "ProxyBaseName": "VeeamProxy",
  7.     "ProxyvCPU": "4",
  8.     "ProxyvRAM": "8",
  9.     "sshuser": "root",
  10.     "ovainitialpassword": "changeme",
  11.     "newsshpassword": "newsecretpassword"
  12.   },
  13.   "Test": {
  14. 	"vbrserver": "",
  15. 	"vcserver": "",
  16. 	"network": "VM Network",
  17. 	"startipaddress": "",
  18. 	"endipaddress": "",
  19. 	"vbruser": "Administrator",
  20. 	"vcuser": "administrator@vsphere.local",
  21. 	"vcdatacenter": "Datacenter",
  22. 	"gateway": "",
  23. 	"dns": "",
  24. 	"domains": "mydomain.local",
  25. 	"ntpserver": ""
  26.   },
  27.   "Prod": {
  28. 	"vbrserver": "",
  29. 	"vcserver": "",
  30. 	"network": "Prod",
  31. 	"startipaddress": "",
  32. 	"endipaddress": "",
  33. 	"vbruser": "Administrator",
  34. 	"vcuser": "administrator@vsphere.local",
  35. 	"vcdatacenter": "Datacenter",
  36. 	"gateway": "",
  37. 	"dns": "",
  38. 	"domains": "mydomain.local",
  39. 	"ntpserver": ""
  40.   }
  41. }

How to setup Veeam replication with VMware vCloud Director

Veeam Backup & Replication 9.5 update 4 has now finally been released (to the VCSP community first and the general public on the 22:nd of January). There are loads of really interesting updates and new features.

Veeam Backup & Replication 9.5 update 4

To name a few of the enhancement/new features:

  • Capacity tier: Support for object based storage, gives you access to BLOB storage from Microsoft Azure, Amazon S3 and S3 compatible as well as IBM Cloud Object Storage. This is a new addition to Scale-Out backup repository users. You have your local “performance tier” as per usual but you can offload data based on age or space to object based storage.
  • Staged restore (GDPR compliance for instance, the right to be forgotten  or other use cases where you’d need to run a script on the VM before restoring it)
  • Secure restore where you can do a virus scan on the VM before restoring
  • Direct restore to Amazon EC2 – restoring to Azure has been available for a while but now you can also choose to restore your on-premises infrastructure VMs to Amazon EC2 – combined with the functionality of the backup vendor Veeam acquired a year ago called N2WS for backing up EC2 instances we now have a whole other level of portability of our data: backup everything, restore where it makes the most sense.
  • Self-service backup and restore portal using Enterprise manager
  • Enhancements to various Veeam explorers
  • Plugins for SAP HANA and Oracle RMAN
  • Platform support: vSphere 6.7 update 1, Windows Server 2019 and vCloud Director 9.5

But going back to the fact that update 4 now is available for VCSPs (or Veeam Cloud & Service Provider), there have been some updates for VMware environments as well (VMware calls their service provider program “VCPP”). Included in the VCPP program is a great product called vCloud Director that has been around for ages but is only available for service providers to use nowadays. VMware vCloud Director is an abstraction layer on top of vCenter so up until now there has been no support for vCloud Director for Veeam Cloud Connect usage when replicating VMs from a customer to the service provider environment. The solution previously was to replicate VMs to the service provider vCenter using Cloud Connect and then manually import VMs to the correct organization from vCloud Director. With update 4 that manual step has now been removed, and the process has in fact been improved since the customer can – using cloud connect and a single port mind you! (no VPN required) – replicate virtual machines from the onsite vSphere environment directly to their own Organization and Org vDC. The customer can also set up failover plans and run those if needed all using the same vCloud Director credentials they already received from the service provider.

It’s really easy to setup, below is a video where I show you how to configure the service provider bits such as adding vCloud Director, setting up tenants but also how the customer would configure their environment i.e. how to connect to a service provider using Cloud Connect and setting up replication jobs from a local environment and replicating VMs to the service provider vCloud Director and the customers org vDC within that environment.

(The video is in swedish but just turn off the sound if you don’t understand)

You’re missing out as a Service Provider if you’re not providing backups for Office 365

Hopefully you’ve already heard, Office 365 is a big hit for just about any vertical and customer type but have you had the much, much, needed conversation with your customers on the necessity of protecting the data that’s now landed in Office 365? I’ve said it before and I’ll say it again: Microsoft is fantastic in providing availability of the service they’re providing but however they also say that any data you store in Office 365 is yours – meaning you have the responsibility to actually think about how you’re going to protect that data and in the end also providing some sort of backup mechanism that executes the backups for you. This is described in a blog post from Veeam called the Office 365 shared responsibility model, which is an essential read if you haven’t already seen it.

A few months ago Veeam released the update version of Backup for Office 365, version 2.0,  and we’re now able to not only backup the mail part of Office 365 but also Sharepoint and Onedrive.

As a Service Provider, Veeam has a program called VCSP (Veeam Cloud & Service Provider), you have the ability to provide Backup as a Service and Disaster Recovery as a Service based on a specific Veeam Backup & Replication function called Cloud Connect available only to Service Providers. Now in relation to Office 365 you have the ability to leverage Cloud Connect to provide backup for Office 365 as a service as well for your customers. So if you are a service provider today, already using Cloud Connect – Why are you not providing backup for Officec 365 as a service? If you have Cloud Connect already installed it takes less than 10 minutes to set up the new service.

So how difficult is it to set up? Not difficult at all – in fact I’ll show you in the video below (Swedish only, but it’s not rocket science so if you’re not swedish speaking it should be fairly easy to follow along anyway). But it basically boils down to these 5 steps:

  1. Install Veeam Backup for Office 365
  2. Install a certificate
  3. Enable tenants authentication with organization credentials
  4. Configure a repository for the customer
  5. Add the customer account and set up a backup job

That’s it! In the video I will also show you how to set up a restore environment at the customer site that will let them restore items themselves using their administrative Office 365 credentials using a local installation of Backup & Replication Free edition and Veeam Explorers for Exchange and Sharepoint, but there are actually a few different ways of restoring – I’m just showing one of the options. You could also have the customers logging on to the Backup server itself for instance or provide a web portal to manage the retores. When restoring items, as always with Veeam, you have multiple destinations for your restore jobs; restore back to Office 365 (as shown in the video), restore to a .pst-file or restore an item and send it as an attachment to a mail to someone. But that’s not all, you can actually restore back to an on-premises installation of Microsoft Exchangeas well  if you’d like. In fact you can use Backup for Office 365 to do backups of your on-premises Exchange server so you have not only a backup tool but a migration tool as well – working bi-directional anyway you want!

Here’s the installation and configuration video! (Swedish only)