// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Samples.HyperV.Replica
{
using System;
using System.Globalization;
using System.Management;
using Microsoft.Samples.HyperV.Common;
static class ManageReplication
{
///
/// Enables replication for a virtual machine to a specified server using
/// integrated authentication.
///
/// The name of the virtual machine to enable replication.
/// The name of the recovery server.
internal static void
CreateReplicationRelationship(
string name,
string recoveryServerName)
{
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
string vmPath = vm.Path.Path;
using (ManagementObject replicationSettingData =
ReplicaUtilities.GetReplicationSettings(vm))
{
replicationSettingData["RecoveryConnectionPoint"] = recoveryServerName;
replicationSettingData["AuthenticationType"] = 1;
replicationSettingData["RecoveryServerPortNumber"] = 80;
replicationSettingData["CompressionEnabled"] = 1;
// Keep 24 recovery points.
replicationSettingData["RecoveryHistory"] = 24;
// Replicate changes after every 300 seconds.
replicationSettingData["ReplicationInterval"] = 300;
// Take VSS snapshot every one hour.
replicationSettingData["ApplicationConsistentSnapshotInterval"] = 1;
// Include all disks for replication.
replicationSettingData["IncludedDisks"] = WmiUtilities.GetVhdSettings(vm);
string settingDataEmbedded =
replicationSettingData.GetText(TextFormat.WmiDtd20);
using (ManagementObject replicationService =
ReplicaUtilities.GetVirtualMachineReplicationService(scope))
{
using (ManagementBaseObject inParams =
replicationService.GetMethodParameters("CreateReplicationRelationship"))
{
inParams["ComputerSystem"] = vmPath;
inParams["ReplicationSettingData"] = settingDataEmbedded;
using (ManagementBaseObject outParams =
replicationService.InvokeMethod("CreateReplicationRelationship",
inParams,
null))
{
WmiUtilities.ValidateOutput(outParams, scope);
}
}
}
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"Replication is successfully enabled for virtual machine \"{0}\"", name));
}
}
}
///
/// Removes the specified replication relationship for a virtual machine.
///
/// The name of the virtual machine to remove replication for.
/// The replication relationship (Primary(0) or Extended(1)) to be removed.
internal static void
RemoveReplicationRelationshipEx(
string name,
UInt16 relationshipType)
{
if (relationshipType > 1)
{
throw new ArgumentException("Replication relationship should be either 0 or 1");
}
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
string vmPath = vm.Path.Path;
//
// Retrieve the specified Msvm_ReplicationRelationship object.
//
using (ManagementObject replicationRelationship =
ReplicaUtilities.GetReplicationRelationshipObject(vm, relationshipType))
{
if (replicationRelationship == null)
{
throw new ManagementException(string.Format(CultureInfo.CurrentCulture,
"No Msvm_ReplicationRelationship object with relationship type {0} could be found",
relationshipType));
}
string replicationRelationshipEmbedded =
replicationRelationship.GetText(TextFormat.WmiDtd20);
using (ManagementObject replicationService =
ReplicaUtilities.GetVirtualMachineReplicationService(scope))
{
using (ManagementBaseObject inParams =
replicationService.GetMethodParameters("RemoveReplicationRelationshipEx"))
{
inParams["ComputerSystem"] = vmPath;
inParams["ReplicationRelationship"] = replicationRelationshipEmbedded;
using (ManagementBaseObject outParams =
replicationService.InvokeMethod("RemoveReplicationRelationshipEx",
inParams,
null))
{
WmiUtilities.ValidateOutput(outParams, scope);
}
}
}
}
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"{0} replication is successfully removed for virtual machine \"{1}\"",
relationshipType == 0 ? "Primary" : "Extended",
name));
}
}
///
/// Reverses replication for a virtual machine to original primary server.
/// Virtual machine on primary should be in correct state and should be associated with
/// the recovery server.
///
/// The name of the virtual machine to reverse replication.
internal static void
ReverseReplicationRelationship(
string name)
{
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
string vmPath = vm.Path.Path;
using (ManagementObject replicationSettingData = ReplicaUtilities.GetReplicationSettings(vm))
{
//
// Simply reverse the recovery server name with that of primary, other
// properties are already populated.
//
replicationSettingData["RecoveryConnectionPoint"] =
replicationSettingData["PrimaryConnectionPoint"];
string settingDataEmbedded = replicationSettingData.GetText(TextFormat.WmiDtd20);
using (ManagementObject replicationService =
ReplicaUtilities.GetVirtualMachineReplicationService(scope))
{
using (ManagementBaseObject inParams =
replicationService.GetMethodParameters("ReverseReplicationRelationship"))
{
inParams["ComputerSystem"] = vmPath;
inParams["ReplicationSettingData"] = settingDataEmbedded;
using (ManagementBaseObject outParams =
replicationService.InvokeMethod("ReverseReplicationRelationship",
inParams,
null))
{
WmiUtilities.ValidateOutput(outParams, scope);
}
}
}
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"Replication is successfully reversed for virtual machine \"{0}\"", name));
}
}
}
///
/// Starts replication over network for a given virtual machine.
///
/// The name of the virtual machine to start replication for.
internal static void
StartReplication(
string name)
{
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
//
// Call the Msvm_ReplicationService::StartReplication method.
// Note the input parameters values are as below -
// InitialReplicationType - 1 for transfer over network
// 2 for exporting the initial replication to the location specified
// in InitialReplicationExportLocation parameter.
// 3 for replication with a restored copy on recovery.
// InitialReplicationExportLocation - null or export location path when InitialReplicationType is 2.
// StartTime - null or scheduled start time in UTC.
//
string vmPath = vm.Path.Path;
using (ManagementObject replicationService =
ReplicaUtilities.GetVirtualMachineReplicationService(scope))
{
using (ManagementBaseObject inParams =
replicationService.GetMethodParameters("StartReplication"))
{
inParams["ComputerSystem"] = vmPath;
inParams["InitialReplicationType"] = 1;
inParams["InitialReplicationExportLocation"] = null;
inParams["StartTime"] = null;
using (ManagementBaseObject outParams =
replicationService.InvokeMethod("StartReplication", inParams, null))
{
WmiUtilities.ValidateOutput(outParams, scope);
}
}
}
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"Replication is successfully started for virtual machine \"{0}\"", name));
}
}
///
/// Creates test replica virtual machine for a given replica virtual machine.
///
/// The name of the virtual machine to create test replica
/// virtual machine for.
internal static void
TestReplicaSystem(
string name)
{
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
//
// Call the Msvm_ReplicationService::TestReplicaSystem method.
// Note the input paramters values are as below -
// SnapshotSettingData - null for latest recovery point.
// OR Embedded instance of CIM_VirtualSystemSettingData
// pointing to recovery snapshot.
//
string vmPath = vm.Path.Path;
using (ManagementObject replicationService =
ReplicaUtilities.GetVirtualMachineReplicationService(scope))
{
using (ManagementBaseObject inParams =
replicationService.GetMethodParameters("TestReplicaSystem"))
{
inParams["ComputerSystem"] = vmPath;
inParams["SnapshotSettingData"] = null;
using (ManagementBaseObject outParams =
replicationService.InvokeMethod("TestReplicaSystem", inParams, null))
{
WmiUtilities.ValidateOutput(outParams, scope);
}
}
}
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"Test replica virtual machine \"{0} - Test\" is successfully created for virtual machine \"{0}\"", name));
}
}
///
/// Initiates failover for a given virtual machine.
///
/// The name of the virtual machine to initiate failover for.
internal static void
InitiateFailover(
string name)
{
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
//
// Call the Msvm_ReplicationService::InitiateFailover method.
// Note the input paramters values are as below -
// SnapshotSettingData - null for latest recovery point.
// OR Embedded instance of CIM_VirtualSystemSettingData
// pointing to recovery snapshot.
//
string vmPath = vm.Path.Path;
using (ManagementObject replicationService =
ReplicaUtilities.GetVirtualMachineReplicationService(scope))
{
using (ManagementBaseObject inParams =
replicationService.GetMethodParameters("InitiateFailover"))
{
inParams["ComputerSystem"] = vmPath;
inParams["SnapshotSettingData"] = null;
using (ManagementBaseObject outParams =
replicationService.InvokeMethod("InitiateFailover", inParams, null))
{
WmiUtilities.ValidateOutput(outParams, scope);
}
}
}
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"Failover is successfully completed for virtual machine \"{0}\"", name));
}
}
///
/// Changes replication state of the specified replication relationship of a virtual machine.
///
/// The name of the virtual machine to change replication state.
/// Requested replication state.
/// The replication relationship (Primary(0) or Extended(1))
/// whose replication state is to be changed.
internal static void
RequestReplicationStateChangeEx(
string name,
UInt16 requestedState,
UInt16 relationshipType)
{
if (relationshipType > 1)
{
throw new ArgumentException("Replication relationship should be either 0 or 1");
}
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
//
// Retrieve the specified Msvm_ReplicationRelationship object.
//
using (ManagementObject replicationRelationship =
ReplicaUtilities.GetReplicationRelationshipObject(vm, relationshipType))
{
if (replicationRelationship == null)
{
throw new ManagementException(string.Format(CultureInfo.CurrentCulture,
"No Msvm_ReplicationRelationship object with relationship type {0} could be found",
relationshipType));
}
string replicationRelationshipEmbedded =
replicationRelationship.GetText(TextFormat.WmiDtd20);
using (ManagementBaseObject inParams =
vm.GetMethodParameters("RequestReplicationStateChangeEx"))
{
inParams["RequestedState"] = requestedState;
inParams["ReplicationRelationship"] = replicationRelationshipEmbedded;
using (ManagementBaseObject outParams =
vm.InvokeMethod("RequestReplicationStateChangeEx", inParams, null))
{
WmiUtilities.ValidateOutput(outParams, scope);
}
ReplicaUtilities.ReplicationState state =
(ReplicaUtilities.ReplicationState)requestedState;
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"{0} replication state for virtual machine \"{1}\" is changed to \"{2}\"",
relationshipType == 0 ? "Primary" : "Extended",
name,
state.ToString()));
}
}
}
}
///
/// Prints the information present in the specified replication relationship object associated
/// with the given vm.
///
/// The name of the virtual machine to fetch the relationship object.
/// The replication relationship (Primary(0) or Extended(1))
/// whose information is to be fetched.
internal static void
GetReplicationRelationshipInfo(
string name,
UInt16 relationshipType)
{
if (relationshipType > 1)
{
throw new ArgumentException("Replication relationship should be either 0 or 1");
}
ManagementScope scope = new ManagementScope(@"root\virtualization\v2");
//
// Retrieve the Msvm_ComputerSystem.
//
using (ManagementObject vm = WmiUtilities.GetVirtualMachine(name, scope))
{
//
// Retrieve the specified Msvm_ReplicationRelationship object.
//
using (ManagementObject replicationRelationship =
ReplicaUtilities.GetReplicationRelationshipObject(vm, relationshipType))
{
if (replicationRelationship == null)
{
throw new ManagementException(string.Format(CultureInfo.CurrentCulture,
"No Msvm_ReplicationRelationship object with relationship type {0} could be found",
relationshipType));
}
//
// Print the information present in the replication relationship object.
//
ReplicaUtilities.PrintReplicationRelationshipObject(replicationRelationship);
}
}
}
}
}