Managing Hyper-V Replica from PowerShell
One of the new virtualization features of Windows Server “8” is Hyper-V Replica. This feature addresses the disaster recovery aspect of your IT information system. In this post I will go into more detail of this feature; what it is, the targeted scenarios, how it works and how to use/manage it from PowerShell.
What is Hyper-V Replica?
Hyper-V Replica is a feature targeted at business continuity and disaster recovery. What is a disaster? Merriam-Webster dictionary: “a sudden calamitous event bringing great damage, loss, or destruction.” Hopefully you never experience a disaster within your IT environment. If you do, it should be a once in a lifetime event. For sure, it should not happen on a weekly, monthly or yearly basis. So keep the definition of disaster in mind when evaluating this feature and avoid thinking of it as a high availability solution.
Hyper-V Replica is a built-in Hyper-V feature; there is no out of band feature you install or enable to get this working. The feature enables you to configure replication of virtual machines. The name maybe could have been VM Replica since Hyper-V is not being replicated. On the other side, Hyper-V Replica means the replication feature is part of Hyper-V, not a separate feature in the management partition.
Being a Hyper-V feature has the following benefits:
· Application agnostic, operates at the VM level
· Storage agnostic, any combination of SAN, DAS or SMB works
· Can be used in clustered and non-clustered configuration
What are the depicted scenarios?
Hyper-V Replica has been designed around the following scenarios.
Main office to branch office; when the main office experiences a disaster, the branch office can recover the service by failing over the replicated virtual machine.
Hosting environment where the virtual machines are being replicated between the main datacenters. In case of a datacenter disaster, the hoster can continue services.
Similar to the hosting scenario except that the customer enables replication from its datacenter to the hosting datacenter. So the hoster is mainly offering Hyper-V Replica service to the customer for disaster recovery purpose.
How does it work?
In all the above scenarios, recovery is possible by failing over the virtual machine and continuing service from the virtual machine to or from the recovery site. There are technical differences though so how does Hyper-V Replica enable replication between organizations for example? What about band-width consumption, virtual machine deployment?
Let’s start with the replication scenario within a single organization. In this scenario all machines are within the same forest and therefore can authenticate each other. In this case, Hyper-V Replica offers integrated authentication using Kerberos and replicates over HTTP. Traffic is not encrypted in this case.
In the scenario where replication occurs between organizations, integrated authentication is not an option. Hyper-V Replica offers certificate based authentication and will replicate using HTTPS. Traffic is encrypted in this case.
In both cases Hyper-V Replica allows for replication between any authenticated replication server or replication between specific replication servers. Servers can be specified using fully or partially qualified domain names (vmhost1.contoso.com or *.contoso.com).
You can specify where the replicated virtual machines are stored as a global setting or specify this for each separate replication server. When replication is configured to allow only from specific servers, you have the options to set a security tag. This tag is being used as an additional authentication layer in the group of replication servers. It prevents replication to the same virtual machine from different organizations.
In all cases, bandwidth is not of much concern. Replication is very robust and can sustain poor network connectivity from both a capacity and latency standpoint.
Using Hyper-V Replica
Hyper-V Replica is disabled by default. You configure Hyper-V Replica under Hyper-V Settings using either Hyper-V Manager or PowerShell. Since anyone can use Hyper-V Manager, I will use PowerShell to configure a host for replication.
First, let’s find the cmdlets related to replication.
Get-Command –Module Hyper-V *repl*
This returns everything in the Hyper-V module that has the string “repl” in it. Look at this list and you can figure that you can roughly divide them by setting replication, getting information about replication, starting, stopping, suspending and resuming and removing replication and importing initial replication.
There is another one related to Hyper-V Replica and covers the failover functionality:
You configure the replication settings on the host using Set-VMReplicationServer. First, retrieve the settings using Get-VMReplicationServer.
I have three hosts named vmhost1, vmhost2 and vmhost3. Vmhost1 and vmhost3 have replication enabled and are replicating a virtual machine already.
Get-VMReplicationServer –ComputerName vmhost2
RepEnabled is false so replication is disabled. The other values are defaults and apply when you just enable replication. There is more information to retrieve. Read my other posts first to get up-to-speed with using PowerShell with Hyper-V.
Get-VMReplicationServer –ComputerName vmhost2 | Format-List *
This gives you more information regarding replication on host vmhost2.
Setting replication is obviously done with the Set-VMReplicationServer cmdlet. First, the syntax.
The ReplicationEnabled switch, a Boolean (true, false), enables/disables replication. Could it be that easy?
Set-VMReplicationServer –ReplicationEnabled 1 –ComputerName vmhost2
Just for once I will show what this looks like in Hyper-V Manager.
At this point, replication has been enabled and a replication request from any authenticated server will work using HTTP. Replication will use a default location of c:\vm if none is specified.
If you want to allow replication only from specific servers, there are additional steps to take. Suppose I want to configure replication allowing replication only from vmhost1. Looking at the Set-VMReplicationServer cmdlet, there is no option for a replication server. You need to specify a replication server using New-VMReplicationAuthorizationEntry. Before you can do this, you must first set the ReplicationAllowedFromAnyServer switch to false. Then add a VMReplicationAuthorizationEntry using the New-VMReplicationAuthorizationEntry cmdlet.
Add an entry for vmhost1.contoso.com.
New-VMReplicationAuthorizationEntry -AllowedPrimaryServer vmhost1.contoso.com –KeepPrimaryStorageLocation –SecurityTag Production –ComputerName vmhost2
The KeepPrimaryStorageLocation uses c:\vm in this case. But you could specify a different location for each Primary Server entry. I specified a SecurityTag of ‘Production’ as an extra identifier.
If you want to modify this VMReplicationAuthorizationEntry, you use the Set-VMReplicationAuthorizationEntry cmdlet.
You can change the storage location for example using:
Set-VMReplicationAuthorizationEntry –AllowedPrimaryServer vmhost1.contoso.com –ReplicaStorageLocation c:\replica –ComputerName vmhost2
All the above commands were executed from a management server running PowerShell and using the –ComputerName switch to apply the settings to. I could also have opened a remote PowerShell window and executed these locally on vmhost2.
An alternative to the above command would like this.
Get-VMReplicationAuthorizationEntry | Set-VMReplicationAuthorizationEntry -ReplicaStorageLocation c:\replica
If the ReplicaStorageLocation of c:\replica does not exist, it will be created for you.
I have created another entry for host vmhost3. The output below shows the current settings.
Hyper-V Replica has been configured on host vmhost2. It allows replication from vmhost1 and vmhost3, using integrated authentication. There is a listener on TCP port 80 as you can see from a netstat output below.
Let’s enumerate the status on all hosts.
(1..3) | % (get-VMReplicationServer –ComputerName vmhost$_}
Add the ComputerName (host) to the table output:
(1..3) | % (get-VMReplicationServer –ComputerName vmhost$_} | Format-Table repenabled, authtype, intauth, certauth, anyserver, moninterval, monstarttime, computername
Notice that only vmhost2 has been configured to allow replication from specific servers. The other hosts allow replication from any server.
With replication enabled I can now replicate a virtual machine to another host. I have one virtual machine on vmhost2.
Enabling replication of a virtual machine is done using the Set-VMReplication cmdlet.
This is partially the output of this command. I will focus on the first method here.
First you enable replication by configuring the virtual machine for replication. Then you start the initial replication and from there replication is enabled and running. Below I configure replication for virtual machine contoso2.
Set-VMReplication –VMName contoso2 –ReplicaServerName vmhost1.contoso.com –ReplicaServerPort 80
Replication has now been configured. In the output above I also issued a Get-VMReplication command which will output any virtual machine and status for which replication has been configured. In the case of contoso2, the state outputs ‘ReadyForInitialReplication’. The health reports ‘Warning’ because nothing has been replicated yet. You can look at the “Replication Health’ with Hyper-V Manager or output all info this cmdlet reports:
Get-VMReplication | Format-List *
Now you see everything Hyper-V has on this virtual machine regarding replication.
The second and final step is to start the initial replication. The initial replication is the full replication of the virtual machine configuration and data. You start initial replication using the Start-VMInitialReplication cmdlet.
Start-VMInitialReplication –VMName contoso2
You can see with Get-VMReplication that the state has changed to InitialReplicationInProgress.
After a couple of minutes, the state changes to Replicating.
You can also query for replication status info using the Measure-VMReplication cmdlet.
This shows the most recent information regarding the replication of contoso2. Approximately 5 GB has been replicated on average. But there is more info to display.
This output shows it has replicated approximately 10 GB, which is true because this virtual machine uses a differencing disk. Contoso2 is a virtual machine with a so called parent. By using a differencing disk, I can save disk space on my demo machines. So I use a Windows Server “8” base, master or parent disk and changes get written to the differencing disk. Because of this dependency, Hyper-V Replica has replicated these dependencies as well. Looking at the location on vmhost1, I see a folder called Hyper-V Replica under c:\vm. In that folder I see GUID’s for the replicated virtual machines. In one folder I can see the virtual hard disks of contoso2 and any dependencies the disk has to other disks.
At this point, contoso2 is being replicated to vmhost1. What info can we retrieve from vmhost1?
Vmhost1 reports that it is receiving (being a replica) contoso2 from the primary server vmhost2 using port 80 and integrated authentication.
Let’s look what Get-VM returns on vmhost1…
It actually lists four virtual machines. Contoso1 and contoso2 are off but replicating. This means that you will see every replicated virtual machine in your list of virtual machines. After all, it is a virtual machine but with a special state. You cannot start these virtual machines. They are now tied to a replication relation and, unless this relationship is broken, cannot be started.
So everything works as expected. Contoso2 is being replicated to vmhost1. When everything is fine, this will continue forever. Any changes in the virtual hard disk(s) are being replicated. This is a delta-replication mechanism so indeed only the changes are being replicated. This differs of course from the initial replication where nothing had been replicated before and everything had to be sent over the network. But once everything is copied, only changes get replicated.
I could also have ‘replicated’ the initial configuration by importing the virtual machine at vmhost1. This prevents the network load as you could deploy the virtual machine on other media. Ship the media to the location of vmhost1, import contoso2 and then start the initial replication. This greatly differs from the network copy however. It will resynchronize the contents but does so by looking for the changes between the data. You can easily verify this with Resource Monitor or Network Monitor. The amount of network traffic will be a fraction of the initial replication network copy.
Now I get to the point where I want to do a planned failover. This basically involves reversing the replication. How to do that?
1. Stop (shut down) contoso2.
Stop-VM –VMName contoso2 –ComputerName vmhost2
2. Prepare contoso2 for failover on vmhost2 (Primary Server).
Start-VMFailover –VMName contoso2 –ComputerName vmhost2 –Prepare
3. Prepare contoso2 for failover on vmhost1 (Replica Server).
Start-VMFailover –VMName contoso2 –ComputerName vmhost1
4. Reverse the replication from vmhost1 to vmhost2.
Set-VMReplication -VMName contoso2 -ComputerName vmhost1 –Reverse
5. Start the VM
Start-VM –VMName contoso2 –ComputerName vmhost1
That is the procedure for a planned failover. When it is unplanned, you don’t have access to the primary server but must start the replicated virtual machine to get the service up and running. Then you need to ‘force’ the failover on the replication server. In other words, the planned failover is performed at the primary server where the unplanned failover is performed at the replica server.
Vmhost2 has a virtual machine ws8-vm1 that is replicating to vmhost1. Simply issue this command:
Start-VMFailover –VMName ws8-vm1 –ComputerName vmhost1
Before failing over a virtual machine (so unplanned failover) you may wish to test the virtual machine. Hyper-V Replica also provides for testing a virtual machine before failing over.
Start-VMFailover –VMName ws8-vm1 –ComputerName vmhost2 -AsTest
Remember that ws8-vm1 exists on vmhost2, but as a replica. Running this command simply creates a virtual machine copy of ws8-vm1 which you can test. To finish the test, issue:
Stop-VMFailover –VMName ws8-vm1 –ComputerName vmhost2
Notice the name of the virtual machine. The test failover is linked to a virtual machine, in this case ws8-vm1. You don’t specify “ws8-vm1 – test” but the original virtual machine name. Hyper-V will then remove the test virtual machine.
In another post I will add the code for setting the test failover network but due to a bug in the Beta build, setting it from PowerShell does not work.
For a very, very good document on Hyper-V Replica, download the Understanding and Troubleshooting Guide, written by Chuck Timon, here.