Replicate Hyper-V VMs to Azure with PowerShell in the classic portal

Overview

Azure Site Recovery contributes to your business continuity and disaster recovery (BCDR) strategy by orchestrating replication, failover and recovery of virtual machines in a number of deployment scenarios. For a full list of deployment scenarios see the Azure Site Recovery overview.

This article shows you how to use PowerShell to automate common tasks you need to perform when you set up Azure Site Recovery to replicate Hyper-V virtual machines in System Center VMM clouds to Azure storage.

The article includes prerequisites for the scenario, and shows you how to set up a Site Recovery vault, install the Azure Site Recovery Provider on the source VMM server, register the server in the vault, add an Azure storage account, install the Azure Recovery Services agent on Hyper-V host servers, configure protection settings for VMM clouds that will be applied to all protected virtual machines, and then enable protection for those virtual machines. Finish up by testing the failover to make sure everything's working as expected.

If you run into problems setting up this scenario, post your questions on the Azure Recovery Services Forum.

Note

Azure has two different deployment models for creating and working with resources: Resource Manager and Classic. This article covers using the Classic deployment model.

Before you start

Make sure you have these prerequisites in place:

Azure prerequisites

VMM prerequisites

  • You'll need VMM server running on System Center 2012 R2.
  • You'll need at least one cloud on the VMM server you want to protect. The cloud should contain:
    • One or more VMM host groups.
    • One or more Hyper-V host servers or clusters in each host group .
    • One or more virtual machines on the source Hyper-V server.

Hyper-V prerequisites

  • The host Hyper-V servers must be running at least Windows Server 2012 with Hyper-V role or Microsoft Hyper-V Server 2012 and have the latest updates installed.
  • If you're running Hyper-V in a cluster note that cluster broker isn't created automatically if you have a static IP address-based cluster. You'll need to configure the cluster broker manually. To do this, in Server Manager > Failover Cluster Manager, connect to the cluster, click Configure Role and select Hyper-V Replica Broker in the Select Role screen of the High Availability wizard.
  • Any Hyper-V host server or cluster for which you want to manage protection must be included in a VMM cloud.

Network mapping prerequisites

When you protect virtual machines in Azure network mapping maps between VM networks on the source VMM server and target Azure networks to enable the following:

  • All machines which fail over on the same network can connect to each other, irrespective of which recovery plan they are in.
  • If a network gateway is setup on the target Azure network, virtual machines can connect to other on-premises virtual machines.
  • If you don’t configure network mapping only virtual machines that fail over in the same recovery plan will be able to connect to each other after failover to Azure.

If you want to deploy network mapping you'll need the following:

  • The virtual machines you want to protect on the source VMM server should be connected to a VM network. That network should be linked to a logical network that is associated with the cloud.
  • An Azure network to which replicated virtual machines can connect after failover. You'll select this network at the time of failover. The network should be in the same region as your Azure Site Recovery subscription.

PowerShell prerequisites

Make sure you have Azure PowerShell ready to go. If you are already using PowerShell, you'll need to upgrade to version 0.8.10 or later. For information about setting up PowerShell, see How to install and configure Azure PowerShell. Once you have set up and configured PowerShell, you can view all of the available cmdlets for the service here.

To learn about tips that can help you use the cmdlets, such as how parameter values, inputs, and outputs are typically handled in Azure PowerShell, see Get Started with Azure Cmdlets.

Step 1: Set the subscription

In PowerShell, run these cmdlets:

$UserName = "<user@live.com>"
$Password = "<password>"
$AzureSubscriptionName = "prod_sub1"

$SecurePassword = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $securePassword
Add-AzureAccount -Credential $Cred;
$AzureSubscription = Select-AzureSubscription -SubscriptionName $AzureSubscriptionName

Replace the elements within the "< >" with your specific information.

Step 2: Create a Site Recovery vault

In PowerShell, replace the elements within the "< >" with your specific information, and run these commands:


$VaultName = "<testvault123>"
$VaultGeo  = "<Southeast Asia>"
$OutputPathForSettingsFile = "<c:\>"
New-AzureSiteRecoveryVault -Location $VaultGeo -Name $VaultName;
$vault = Get-AzureSiteRecoveryVault -Name $VaultName;

Step 3: Generate a vault registration key

Generate a registration key in the vault. After you download the Azure Site Recovery Provider and install it on the VMM server, you'll use this key to register the VMM server in the vault.

  1. Get the vault setting file and set the context:

    
    $VaultName = "<testvault123>"
    $VaultGeo  = "<Southeast Asia>"
    $OutputPathForSettingsFile = "<c:\>"
    
    $VaultSetingsFile = Get-AzureSiteRecoveryVaultSettingsFile -Location $VaultGeo -Name $VaultName -Path $OutputPathForSettingsFile;
    
  2. Set the vault context by running the following commands:

    
    $VaultSettingFilePath = $vaultSetingsFile.FilePath
    $VaultContext = Import-AzureSiteRecoveryVaultSettingsFile -Path $VaultSettingFilePath -ErrorAction Stop
    

Step 4: Install the Azure Site Recovery Provider

  1. On the VMM machine, create a directory by running the following command:

    
    pushd C:\ASR\
    
  2. Extract the files using the downloaded provider by running the following command

    
    AzureSiteRecoveryProvider.exe /x:. /q
    
  3. Install the provider using the following commands:

    
    .\SetupDr.exe /i
    
    
    $installationRegPath = "hklm:\software\Microsoft\Microsoft System Center Virtual Machine Manager Server\DRAdapter"
    do
    {
      $isNotInstalled = $true;
      if(Test-Path $installationRegPath)
      {
          $isNotInstalled = $false;
      }
    }While($isNotInstalled)
    

    Wait for the installation to finish.

  4. Register the server in the vault using the following command:

    
    $BinPath = $env:SystemDrive+"\Program Files\Microsoft System Center 2012 R2\Virtual Machine Manager\bin"
    pushd $BinPath
    $encryptionFilePath = "C:\temp\"
    .\DRConfigurator.exe /r /Credentials $VaultSettingFilePath /vmmfriendlyname $env:COMPUTERNAME /dataencryptionenabled $encryptionFilePath /startvmmservice
    

Step 5: Create an Azure storage account

If you don't have an Azure storage account, create a geo-replication enabled account by running the following command:


$StorageAccountName = "teststorageacc1"
$StorageAccountGeo  = "Southeast Asia"

New-AzureStorageAccount -StorageAccountName $StorageAccountName -Label $StorageAccountName -Location $StorageAccountGeo;

Note that the storage account must be in the same region as the Azure Site Recovery service, and be associated with the same subscription.

Step 6: Install the Azure Recovery Services Agent

From the Azure portal, install the Azure Recovery Services agent on each Hyper-V host server located in the VMM clouds you want to protect.

Run the following command on all VMM hosts:


marsagentinstaller.exe /q /nu

Step 7: Configure cloud protection settings

  1. Create a cloud protection profile to Azure by running the following command:

    
    $ReplicationFrequencyInSeconds = "300";
    $ProfileResult = New-AzureSiteRecoveryProtectionProfileObject -ReplicationProvider HyperVReplica -RecoveryAzureSubscription $AzureSubscriptionName -RecoveryAzureStorageAccount $StorageAccountName -ReplicationFrequencyInSeconds     $ReplicationFrequencyInSeconds;
    
  2. Get a protection container by running the following commands:

    
    $PrimaryCloud = "testcloud"
    $protectionContainer = Get-AzureSiteRecoveryProtectionContainer -Name $PrimaryCloud;
    
  3. Start the association of the protection container with the cloud:

    
    $associationJob = Start-AzureSiteRecoveryProtectionProfileAssociationJob -ProtectionProfile $profileResult -PrimaryProtectionContainer $protectionContainer;        
    
  4. After the job has finished, run the following command:

     $job = Get-AzureSiteRecoveryJob -Id $associationJob.JobId;
     if($job -eq $null -or $job.StateDescription -ne "Completed")
     {
     $isJobLeftForProcessing = $true;
     }
    
  5. After the job has finished processing, run the following command:

     Do
     {
     $job = Get-AzureSiteRecoveryJob -Id $associationJob.JobId;
     Write-Host "Job State:{0}, StateDescription:{1}" -f Job.State, $job.StateDescription;
     if($job -eq $null -or $job.StateDescription -ne "Completed")
     {
         $isJobLeftForProcessing = $true;
     }
    
     if($isJobLeftForProcessing)
     {
         Start-Sleep -Seconds 60
     }
     }While($isJobLeftForProcessing)
    

To check the completion of the operation, follow the steps in Monitor Activity.

Step 8: Configure network mapping

Before you begin network mapping verify that virtual machines on the source VMM server are connected to a VM network. In addition, create one or more Azure virtual networks. Note that multiple VM networks can be mapped to a single Azure network.

Note that if the target network has multiple subnets and one of those subnets has the same name as subnet on which the source virtual machine is located, then the replica virtual machine will be connected to that target subnet after failover. If there is not a target subnet with a matching name, the virtual machine will be connected to the first subnet in the network.

The first command gets servers for the current Azure Site Recovery vault. The command stores the Microsoft Azure Site Recovery servers in the $Servers array variable.

$Servers = Get-AzureSiteRecoveryServer

The second command gets the site recovery network for the first server in the $Servers array. The command stores the networks in the $Networks variable.

$Networks = Get-AzureSiteRecoveryNetwork -Server $Servers[0]

The third command gets your Azure subscriptions by using the Get-AzureSubscription cmdlet, and then stores that value in the $Subscriptions variable.

$Subscriptions = Get-AzureSubscription

The fourth command gets Azure virtual networks by using the Get-AzureVNetSite cmdlet, and then that value in the $AzureVmNetworks variable.

$AzureVmNetworks = Get-AzureVNetSite

The final cmdlet creates a mapping between the primary network and the Azure virtual machine network. The cmdlet specifies the primary network as the first element of $Networks. The cmdlet specifies a virtual machine network as the first element of $AzureVmNetworks by using its ID. The command includes your Azure subscription ID.

New-AzureSiteRecoveryNetworkMapping -PrimaryNetwork $Networks[0] -AzureSubscriptionId $Subscriptions[0].SubscriptionId -AzureVMNetworkId $AzureVmNetworks[0].Id

Step 9: Enable protection for virtual machines

After servers, clouds, and networks are configured correctly, you can enable protection for virtual machines in the cloud. Note the following:

Virtual machines must meet Azure virtual machine prerequisites.

To enable protection the operating system and operating system disk properties must be set for the virtual machine. When you create a virtual machine in VMM using a virtual machine template you can set the property. You can also set these properties for existing virtual machines on the General and Hardware Configuration tabs of the virtual machine properties. If you don't set these properties in VMM you'll be able to configure them in the Azure Site Recovery portal.

  1. To enable protection, run the following command to get the protection container:

    $ProtectionContainer = Get-AzureSiteRecoveryProtectionContainer -Name $CloudName

  2. Get the protection entity (VM) by running the following command:

     $protectionEntity = Get-AzureSiteRecoveryProtectionEntity -Name $VMName -ProtectionContainer $protectionContainer
    
  3. Enable the DR for the VM by running the following command:

     $jobResult = Set-AzureSiteRecoveryProtectionEntity -ProtectionEntity $protectionEntity     -Protection Enable -Force
    

Test your deployment

To test your deployment you can run a test failover for a single virtual machine, or create a recovery plan consisting of multiple virtual machines and run a test failover for the plan. Test failover simulates your failover and recovery mechanism in an isolated network. Note that:

  • If you want to connect to the virtual machine in Azure using Remote Desktop after the failover, enable Remote Desktop Connection on the virtual machine before you run the test failover.
  • After failover, you'll use a public IP address to connect to the virtual machine in Azure using Remote Desktop. If you want to do this, ensure you don't have any domain policies that prevent you from connecting to a virtual machine using a public address.

To check the completion of the operation, follow the steps in Monitor Activity.

Create a recovery plan

  1. Create an .xml file as a template for your recovery plan using the data below, and then save it as "C:\RPTemplatePath.xml".
  2. Change the RecoveryPlan node Id, Name, PrimaryServerId, and SecondaryServerId.
  3. Change the ProtectionEntity node PrimaryProtectionEntityId (vmid from VMM).
  4. You can add more VMs by adding more ProtectionEntity nodes.

     <#
     <?xml version="1.0" encoding="utf-16"?>
     <RecoveryPlan Id="d0323b26-5be2-471b-addc-0a8742796610" Name="rp-test"     PrimaryServerId="9350a530-d5af-435b-9f2b-b941b5d9fcd5"     SecondaryServerId="21a9403c-6ec1-44f2-b744-b4e50b792387" Description=""     Version="V2014_07">
       <Actions />
       <ActionGroups>
         <ShutdownAllActionGroup Id="ShutdownAllActionGroup">
           <PreActionSequence />
           <PostActionSequence />
         </ShutdownAllActionGroup>
         <FailoverAllActionGroup Id="FailoverAllActionGroup">
           <PreActionSequence />
           <PostActionSequence />
         </FailoverAllActionGroup>
         <BootActionGroup Id="DefaultActionGroup">
           <PreActionSequence />
           <PostActionSequence />
           <ProtectionEntity PrimaryProtectionEntityId="d4c8ce92-a613-4c63-9b03-    cf163cc36ef8" />
         </BootActionGroup>
       </ActionGroups>
       <ActionGroupSequence>
         <ActionGroup Id="ShutdownAllActionGroup" ActionId="ShutdownAllActionGroup"     Before="FailoverAllActionGroup" />
         <ActionGroup Id="FailoverAllActionGroup" ActionId="FailoverAllActionGroup"     After="ShutdownAllActionGroup" Before="DefaultActionGroup" />
         <ActionGroup Id="DefaultActionGroup" ActionId="DefaultActionGroup" After="FailoverAllActionGroup"/>
       </ActionGroupSequence>
     </RecoveryPlan>
     #>
    
  5. Fill in the data in the template:

     $TemplatePath = "C:\RPTemplatePath.xml";
    
  6. Create the RecoveryPlan:

     $RPCreationJob = New-AzureSiteRecoveryRecoveryPlan -File $TemplatePath -WaitForCompletion;
    

Run a test failover

  1. Get the RecoveryPlan object by running the following command:

    $RPObject = Get-AzureSiteRecoveryRecoveryPlan -Name $RPName;

  2. Start the test failover by running the following command:

     $jobIDResult = Start-AzureSiteRecoveryTestFailoverJob -RecoveryPlan $RPObject -Direction PrimaryToRecovery;
    

<a name=monitor> Monitor Activity

Use the following commands to monitor the activity. Note that you have to wait in between jobs for the processing to finish.

Do
{
        $job = Get-AzureSiteRecoveryJob -Id $associationJob.JobId;
        Write-Host "Job State:{0}, StateDescription:{1}" -f Job.State, $job.StateDescription;
        if($job -eq $null -or $job.StateDescription -ne "Completed")
        {
            $isJobLeftForProcessing = $true;
        }

    if($isJobLeftForProcessing)
        {
            Start-Sleep -Seconds 60
        }
}While($isJobLeftForProcessing)

Next steps

Read more about Azure Site Recovery PowerShell cmdlets. .