// 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); } } } } }