Azure Site Recovery service enables businesses ensure business continuity by keeping their workloads and applications running on Virtual Machines and physical servers available if a site goes down. Site Recovery replicates these workloads running on VMs and physical servers so that they remain available in a secondary location if the primary site isn’t available. It recovers workloads to the primary site when it’s up and running again.
In this post, I want to share a PowerShell solution I developed with the Azure Resource Manager model, to automate the deployment of Site Recovery to configure and orchestrate Windows Server 2016 Hyper-V host and guest virtual machine replication and protection to Azure Cloud.
The solution consists of a PowerShell function and module that successfully deploys and configures Azure Site Recovery for a Hyper-V to Azure replication scenario without VMM :
1) The New-HyperVASRDeployment
function handles the configuration and orchestration of the Hyper-V and workloads to Azure.
2) The Install-ASRProvider
module is called within the first function to execute the download, extraction of the “.\AzureSiteRecoveryProvider.exe” file, and installation of the ASR provider and Recovery services agent on the local Hyper-V host (a windows server 2016 server).
The New-HyperVASRDeployment
function can be executed as a Runbook or run locally on the Hyper-V host within an elevated PowerShell console. It authenticates to azure using an Azure RunAsAccount. An Azure automation account will have to be provisioned.
Prerequisites:
1) The Install-ASRProvider.psm1 module can be downloaded from my GitHub repository. It must be copied to the PowerShell modules folder on the local host machine. If the solution is deployed as a runbook, this module will need to be imported into the Automation account module folder.
2) The Install-ASRProvider.psm1 module downloads the “.\AzureSiteRecoveryProvider.exe” file from https://aka.ms/downloaddra (Microsoft could change this link at anytime) to a local folder on the Hyper-V host that matches the $Path variable value specified in the Install-ASRProvider.psm1 module.
3) Ensure internet access is available on the Hyper-V Host.
4) An Azure automation account will have to be provisioned. This function was developed to run as a Runbook or locally. It authenticates to azure using an Azure RunAsAccount.
Overview
The New-HyperVASRDeployment
function (also available at my GitHub Repo) registers the Site Recovery and RecoveryServices providers for the subscription and creates a new resource group for the site recovery resources and components.
It goes on to provision the Recovery vault, storage account, Hyper-V site container and sets the recovery services context for the subscription.
The next section makes a call to the Install-ASRProvider
module that downloads, installs the ASR provider and agent, then registers the on-premise Hyper-V host with the Azure recovery services vault.
The remaining sections of the code create a replication policy, map the policy to the existing Hyper-V site, enables ASR protection on the selected Hyper-V host virtual machine workload and initiates synchronization with the Azure recovery vault.
The end result is that the virtual machine shows up in the Replicated Items blade of the Recovery Services vault as protected and 100% synchronized in Azure as shown in the screen shots below.
In the future, I hope to share a function that automates the Site Recovery failover of a protected virtual machine.
The following screen shots show the solution running within a PowerShell console:
The next set of screen shots display the registered server(Hyper-V host) in Azure, the VM Replication state in Hyper-V manager on-premise and the replication item in Azure after the successful execution of the functions:
Replication Item after successful synchronization of the Virtual machine:
<# .SYNOPSIS PowerShell Function to automate Azure Site Recovery deployment workflows for Hyper-V VMs to Azure in a non-VMM environment. .DESCRIPTION PowerShell Function to automate Azure Site Recovery deployment workflows for Hyper-V VMs to Azure in a non-VMM environment. This function was tested using a WS2016 Virtual Machine configured as a Hyper-V Host using Nested Virtualization. https://docs.microsoft.com/en-us/azure/site-recovery/site-recovery-deploy-with-powershell-resource-manager. Prerequisites: 1) The Install-ASRProvider.psm1 module must be copied to the PowerShell modules folder on the local host machine.If the solution is deployed as a runbook, this module will need imported into the Automation account module folder. 2) Ensure internet access is available. 3) An Azure automation account will have to be provisioned. This function was developed to run as a Runbook or locally. It authenticates to azure using an Azure RunAsAccount. .PARAMETER SubscriptionName Subscription name of the Recovery Vault infrastructure. .PARAMETER Location Location of the Recovery Vault . .PARAMETER ResourceGroupName ResourceGroupName to deploy the Recovery Vault infrastructure. .PARAMETER StorageAccountName StorageAccountName to store replicated VM vhds. .PARAMETER ServerFriendlyName ServerFriendlyName of the Hyper-V to be registered with the Azure Site Recovery Site. .EXAMPLE New-HyperVASRDeployment .FUNCTIONALITY PowerShell Language /#> Param( [String]$ResourceGroupName = "RGRecovery", [String]$SubscriptionName = "Free Trial", [String]$Location = "southcentralus", [String]$ServerFriendlyName = "WS2016", [String]$StorageAccountName = "storeasr0518" ) #region Azure Logon try { # Get the connection "AzureRunAsConnection " $connectionName = "AzureRunAsConnection" $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName "Logging in to Azure..." Add-AzureRmAccount ` -ServicePrincipal ` -TenantId $servicePrincipalConnection.TenantId ` -ApplicationId $servicePrincipalConnection.ApplicationId ` -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint } catch { if (!$servicePrincipalConnection) { $ErrorMessage = "Connection $connectionName not found." throw $ErrorMessage } else { Write-Error -Message $_.Exception throw $_.Exception } } Select-AzureRmSubscription -SubscriptionName $SubscriptionName #endregion Register-AzureRmResourceProvider -ProviderNamespace Microsoft.SiteRecovery Register-AzureRmResourceProvider -ProviderNamespace Microsoft.RecoveryServices #Create Recovery ResourceGroup New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location #Create Storage Account.Geo-redundant storage or locally redundant storage can be used.Geo-redundant storage is recommended. #With geo-redundant storage, data is resilient if a regional outage occurs, or if the primary region can't be recovered. $SkuName = "Standard_LRS" New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageAccountName -SkuName $SkuName -Location $Location #Create new Recovery Services Vault $RecoveryServicesVaultName = "RecoveryVaultDemo" New-AzureRmRecoveryServicesVault -Name $RecoveryServicesVaultName -ResourceGroupName $ResourceGroupName -Location $Location #Set Recovery Service Vault Context $Vault = Get-AzureRmRecoveryServicesVault -ResourceGroupName $ResourceGroupName -Name $RecoveryServicesVaultName Set-AzureRmSiteRecoveryVaultSettings -ARSVault $Vault Start-Sleep -Seconds 30 #Create new Hyper-V Site $SiteName = "HypervSiteDemo" New-AzureRmSiteRecoveryFabric -Name $SiteName -Type HyperVSite Start-Sleep -Seconds 30 $HyperVSite = Get-AzureRmSiteRecoveryFabric -Name $SiteName #The above cmdlet starts a site recovery job to create the site. Verify that the job completed successfully (Get-AzureRmSiteRecoveryJob)[0] Get-AzureRmSiteRecoveryJob -State "Succeeded" #Generate and download a registration key for the new Hyper-V site Install-ASRProvider -Vault $Vault -SiteName $SiteName -ServerFriendlyName $ServerFriendlyName -SiteIdentifier $HyperVSite.SiteIdentifier Start-Sleep -Seconds 60 #Verify the registration completed successfully Get-AzureRmSiteRecoveryServicesProvider -FriendlyName $ServerFriendlyName -Fabric (Get-AzureRmSiteRecoveryFabric -Name $HyperVSite.FriendlyName) #Create a replcation policy and map it to a Protection container $ReplicationFrequencyInSeconds = 300 $PolicyName = "ReplicaPolicy" $RecoveryPoints = 3 $StorageAccountId = (Get-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageAccountName).Id New-AzureRmSiteRecoveryPolicy -Name $PolicyName -ReplicationProvider HyperVReplicaAzure -ReplicationFrequencyInSeconds $ReplicationFrequencyInSeconds ` -RecoveryPoints $RecoveryPoints -ApplicationConsistentSnapshotFrequencyInHours 1 -RecoveryAzureStorageAccountId $StorageAccountId Start-Sleep -Seconds 30 #Get the site object/container created earlier above $Container = Get-AzureRmSiteRecoveryProtectionContainer -FriendlyName $HyperVSite.FriendlyName -Fabric (Get-AzureRmSiteRecoveryFabric) $PolicyMappingName = "ReplicaPolicyMapping" $PolicyObject = Get-AzureRmSiteRecoveryPolicy -Name $PolicyName New-AzureRmSiteRecoveryProtectionContainerMapping -Name $PolicyMappingName -Policy $PolicyObject -PrimaryProtectionContainer $Container Start-Sleep -Seconds 180 #Verify the Mapping status $ProtectionContainerMapping = Get-AzureRmSiteRecoveryProtectionContainerMapping -Name $PolicyMappingName -ProtectionContainer $Container #Get and display Site Recovery Protectable Items for the specified Container $ReplicationProtectableItem = Get-AzureRmSiteRecoveryProtectableItem -ProtectionContainer $Container #Configure Protection for specific VMs or Items and initiate DR replication $ProtectableItem = New-AzureRmSiteRecoveryReplicationProtectedItem -ProtectableItem $ReplicationProtectableItem -Name $ReplicationProtectableItem.FriendlyName -ProtectionContainerMapping $ProtectionContainerMapping ` -RecoveryAzureStorageAccountId $StorageAccountId -OSDiskName $ReplicationProtectableItem.Disks[0].Name -OS Windows -Verbose #Check the status of the DR replication job Get-AzureRmSiteRecoveryJob -Job $ProtectableItem
The following Install-ASRProvider.psm1 module is called by the New-HyperVASRDeployment above. It downloads and extracts the ASR Provider file, then installs the ASR provider and Recovery Vault Agent and registers the Server in the Azure Recovery Services Vault.
Function Install-ASRProvider{ <# .SYNOPSIS PowerShell module to automate Azure Site Recovery deployment workflows for Hyper-V VMs to Azure in a non-VMM environment. .DESCRIPTION PowerShell module to automate Azure Site Recovery deployment workflows for Hyper-V VMs to Azure in a non-VMM environment. This function was tested using a WS2016 Virtual Machine configured as a Hyper-V Host using Nested Virtualization. https://docs.microsoft.com/en-us/azure/site-recovery/site-recovery-deploy-with-powershell-resource-manager The Install-ASRProvider.psm1 module downloads the ".\AzureSiteRecoveryProvider.exe" file from "https://aka.ms/downloaddra"(Microsoft could change this link at anytime) to a local folder on the Hyper-V host that matches the $Path variable value in the Install-ASRProvider.psm1 module. .PARAMETER Vault Vault Object. .PARAMETER Path File Path . .PARAMETER SiteName SiteName. .PARAMETER ServerFriendlyName ServerFriendlyName. .PARAMETER SiteIdentifier SiteIdentifier. .FUNCTIONALITY PowerShell Language /#> Param( [System.Object]$Vault, [String]$SiteName, [String]$ServerFriendlyName, [String]$SiteIdentifier ) [string]$ScriptPath = Split-Path (get-variable myinvocation -scope script).value.Mycommand.Definition -Parent #Download site recovery provider file and credential file Invoke-WebRequest -Uri "https://aka.ms/downloaddra" -OutFile "c:\ars\AzureSiteRecoveryProvider.exe" $Path = "C:\ARS\" $CredsFile = Get-AzureRmRecoveryServicesVaultSettingsFile -Vault $Vault -SiteIdentifier $SiteIdentifier -SiteFriendlyName $SiteName -Path $Path $CredsFile.FilePath #region extract the ASR Provider files, Install the ASR provider and Recovery Vaullt Agent and verify the Server Registration #Extract Provider files Set-Location -Path $Path Start-Process -FilePath (".\AzureSiteRecoveryProvider.exe") -ArgumentList "/x:. /q" -Wait #Install ASR Provider C:\ARS\SETUPDR.EXE /i #Register the Hyper-V host in the vault $RegisterPath = "C:\Program Files\Microsoft Azure Site Recovery Provider\" Set-Location -Path $RegisterPath Start-Process (".\DRConfigurator.exe") -ArgumentList "/r /friendlyname $ServerFriendlyName /Credentials $($CredsFile.FilePath)" Set-Location -Path "\" }