/// <summary>
        /// Set PE protection.
        /// </summary>
        private void SetPEReprotect()
        {
            if ((this.Direction == Constants.PrimaryToRecovery &&
                 this.ProtectionEntity.ActiveLocation == Constants.RecoveryLocation) ||
                (this.Direction == Constants.RecoveryToPrimary &&
                 this.ProtectionEntity.ActiveLocation == Constants.PrimaryLocation))
            {
                throw new ArgumentException("Parameter value is not correct.", "Direction");
            }

            var request = new ReprotectRequest();

            if (this.ProtectionEntity == null)
            {
                var pe = RecoveryServicesClient.GetAzureSiteRecoveryProtectionEntity(
                    this.ProtectionContainerId,
                    this.ProtectionEntityId);
                this.ProtectionEntity = new ASRProtectionEntity(pe.ProtectionEntity);

                this.ValidateUsageById(
                    this.ProtectionEntity.ReplicationProvider,
                    this.ProtectionEntityId);
            }

            request.ReplicationProviderSettings = string.Empty;

            if (this.ProtectionEntity.ReplicationProvider == Constants.HyperVReplicaAzure)
            {
                if (this.Direction == Constants.PrimaryToRecovery)
                {
                    var blob = new AzureReProtectionInput();
                    blob.HvHostVmId = this.ProtectionEntity.FabricObjectId;
                    blob.VmName     = this.ProtectionEntity.Name;

                    blob.OSType = this.ProtectionEntity.OS;
                    blob.VHDId  = this.ProtectionEntity.OSDiskId;

                    request.ReplicationProviderSettings = DataContractUtils.Serialize <AzureReProtectionInput>(blob);
                }
            }

            request.ReplicationProvider = this.ProtectionEntity.ReplicationProvider;
            request.FailoverDirection   = this.Direction;

            this.jobResponse = RecoveryServicesClient.StartAzureSiteRecoveryReprotection(
                this.ProtectionContainerId,
                this.ProtectionEntityId,
                request);

            this.WriteJob(this.jobResponse.Job);

            if (this.WaitForCompletion.IsPresent)
            {
                this.WaitForJobCompletion(this.jobResponse.Job.ID);
            }
        }
        /// <summary>
        /// Associates protection profile with one enterprise based and an Azure protection container
        /// </summary>
        private void EnterpriseToAzureAssociation()
        {
            if (string.Compare(
                    this.ProtectionProfile.ReplicationProvider,
                    Constants.HyperVReplicaAzure,
                    StringComparison.OrdinalIgnoreCase) != 0)
            {
                throw new InvalidOperationException(
                          string.Format(
                              Properties.Resources.IncorrectReplicationProvider,
                              this.ProtectionProfile.ReplicationProvider));
            }

            HyperVReplicaAzureProtectionProfileInput hyperVReplicaAzureProtectionProfileInput
                = new HyperVReplicaAzureProtectionProfileInput()
                {
                ApplicationConsistentSnapshotFrequencyInHours = this.ProtectionProfile.HyperVReplicaAzureProviderSettingsObject.ApplicationConsistentSnapshotFrequencyInHours,
                ReplicationInterval          = this.ProtectionProfile.HyperVReplicaAzureProviderSettingsObject.ReplicationFrequencyInSeconds,
                OnlineReplicationStartTime   = this.ProtectionProfile.HyperVReplicaAzureProviderSettingsObject.ReplicationStartTime,
                RecoveryPointHistoryDuration = this.ProtectionProfile.HyperVReplicaAzureProviderSettingsObject.RecoveryPoints,
                EncryptionEnabled            = this.ProtectionProfile.HyperVReplicaAzureProviderSettingsObject.EncryptStoredData
                };

            var storageAccount = new CustomerStorageAccount();

            storageAccount.StorageAccountName = this.ProtectionProfile.HyperVReplicaAzureProviderSettingsObject.RecoveryAzureStorageAccountName;
            storageAccount.SubscriptionId     = this.ProtectionProfile.HyperVReplicaAzureProviderSettingsObject.RecoveryAzureSubscription;

            hyperVReplicaAzureProtectionProfileInput.StorageAccounts = new System.Collections.Generic.List <CustomerStorageAccount>();
            hyperVReplicaAzureProtectionProfileInput.StorageAccounts.Add(storageAccount);

            CreateProtectionProfileInput createProtectionProfileInput =
                new CreateProtectionProfileInput(
                    string.IsNullOrEmpty(this.ProtectionProfile.Name) ? this.PrimaryProtectionContainer.Name : this.ProtectionProfile.Name,
                    this.ProtectionProfile.ReplicationProvider,
                    DataContractUtils <HyperVReplicaAzureProtectionProfileInput> .Serialize(hyperVReplicaAzureProtectionProfileInput));

            ProtectionProfileAssociationInput protectionProfileAssociationInput =
                new ProtectionProfileAssociationInput(
                    this.PrimaryProtectionContainer.ID,
                    Constants.AzureContainer);

            CreateAndAssociateProtectionProfileInput createAndAssociateProtectionProfileInput =
                new CreateAndAssociateProtectionProfileInput(
                    createProtectionProfileInput,
                    protectionProfileAssociationInput);

            this.jobResponse = RecoveryServicesClient.StartCreateAndAssociateAzureSiteRecoveryProtectionProfileJob(
                createAndAssociateProtectionProfileInput);

            this.WriteJob(this.jobResponse.Job);
        }
        /// <summary>
        /// Starts PE Planned failover.
        /// </summary>
        private void StartPEPlannedFailover()
        {
            var request = new PlannedFailoverRequest();

            if (this.ProtectionEntity == null)
            {
                var pe = RecoveryServicesClient.GetAzureSiteRecoveryProtectionEntity(
                    this.ProtectionContainerId,
                    this.ProtectionEntityId);
                this.ProtectionEntity = new ASRProtectionEntity(pe.ProtectionEntity);

                this.ValidateUsageById(this.ProtectionEntity.ReplicationProvider, Constants.ProtectionEntityId);
            }

            if (this.ProtectionEntity.ReplicationProvider == Constants.HyperVReplicaAzure)
            {
                if (this.Direction == Constants.PrimaryToRecovery)
                {
                    var blob = new AzureFailoverInput();
                    blob.VaultLocation = this.GetCurrentValutLocation();
                    request.ReplicationProviderSettings = DataContractUtils.Serialize <AzureFailoverInput>(blob);
                }
                else
                {
                    var blob = new AzureFailbackInput();
                    blob.CreateRecoveryVmIfDoesntExist = false;
                    blob.SkipDataSync = this.Optimize == Constants.ForDowntime ? true : false;
                    request.ReplicationProviderSettings = DataContractUtils.Serialize <AzureFailbackInput>(blob);
                }
            }
            else
            {
                request.ReplicationProviderSettings = string.Empty;
            }

            request.ReplicationProvider = this.ProtectionEntity.ReplicationProvider;
            request.FailoverDirection   = this.Direction;

            this.jobResponse =
                RecoveryServicesClient.StartAzureSiteRecoveryPlannedFailover(
                    this.ProtectionContainerId,
                    this.ProtectionEntityId,
                    request);
            this.WriteJob(this.jobResponse.Job);

            if (this.WaitForCompletion.IsPresent)
            {
                this.WaitForJobCompletion(this.jobResponse.Job.ID);
            }
        }
        /// <summary>
        /// Associates protection profile with enterprise based protection containers
        /// </summary>
        private void EnterpriseToEnterpriseAssociation()
        {
            if (string.Compare(
                    this.ProtectionProfile.ReplicationProvider,
                    Constants.HyperVReplica,
                    StringComparison.OrdinalIgnoreCase) != 0)
            {
                throw new InvalidOperationException(
                          string.Format(
                              Properties.Resources.IncorrectReplicationProvider,
                              this.ProtectionProfile.ReplicationProvider));
            }

            HyperVReplicaProtectionProfileInput hyperVReplicaProtectionProfileInput
                = new HyperVReplicaProtectionProfileInput()
                {
                ApplicationConsistentSnapshotFrequencyInHours = this.ProtectionProfile.HyperVReplicaProviderSettingsObject.ApplicationConsistentSnapshotFrequencyInHours,
                ReplicationFrequencyInSeconds = this.ProtectionProfile.HyperVReplicaProviderSettingsObject.ReplicationFrequencyInSeconds,
                OnlineReplicationStartTime    = this.ProtectionProfile.HyperVReplicaProviderSettingsObject.ReplicationStartTime,
                CompressionEnabled            = this.ProtectionProfile.HyperVReplicaProviderSettingsObject.CompressionEnabled,
                OnlineReplicationMethod       = (string.Compare(this.ProtectionProfile.HyperVReplicaProviderSettingsObject.ReplicationMethod, Constants.OnlineReplicationMethod, StringComparison.OrdinalIgnoreCase) == 0) ? true : false,
                RecoveryPoints            = this.ProtectionProfile.HyperVReplicaProviderSettingsObject.RecoveryPoints,
                ReplicationPort           = this.ProtectionProfile.HyperVReplicaProviderSettingsObject.ReplicationPort,
                AllowReplicaDeletion      = this.ProtectionProfile.HyperVReplicaProviderSettingsObject.AllowReplicaDeletion,
                AllowedAuthenticationType = (ushort)((string.Compare(this.ProtectionProfile.HyperVReplicaProviderSettingsObject.Authentication, Constants.AuthenticationTypeKerberos, StringComparison.OrdinalIgnoreCase) == 0) ? 1 : 2),
                };

            CreateProtectionProfileInput createProtectionProfileInput =
                new CreateProtectionProfileInput(
                    //// Name of the protection profile as the name of the protection container if not given
                    string.IsNullOrEmpty(this.ProtectionProfile.Name) ? this.PrimaryProtectionContainer.Name : this.ProtectionProfile.Name,
                    this.ProtectionProfile.ReplicationProvider,
                    DataContractUtils <HyperVReplicaProtectionProfileInput> .Serialize(hyperVReplicaProtectionProfileInput));

            ProtectionProfileAssociationInput protectionProfileAssociationInput =
                new ProtectionProfileAssociationInput(
                    this.PrimaryProtectionContainer.ID,
                    this.RecoveryProtectionContainer.ID);

            CreateAndAssociateProtectionProfileInput createAndAssociateProtectionProfileInput =
                new CreateAndAssociateProtectionProfileInput(
                    createProtectionProfileInput,
                    protectionProfileAssociationInput);

            this.jobResponse = RecoveryServicesClient.StartCreateAndAssociateAzureSiteRecoveryProtectionProfileJob(
                createAndAssociateProtectionProfileInput);

            this.WriteJob(this.jobResponse.Job);
        }
        /// <summary>
        /// Starts PE Test failover.
        /// </summary>
        private void StartPETestFailover()
        {
            var request = new TestFailoverRequest();

            if (this.ProtectionEntity == null)
            {
                var pe = RecoveryServicesClient.GetAzureSiteRecoveryProtectionEntity(
                    this.ProtectionContainerId,
                    this.ProtectionEntityId);
                this.ProtectionEntity = new ASRProtectionEntity(pe.ProtectionEntity);

                this.ValidateUsageById(
                    this.ProtectionEntity.ReplicationProvider,
                    Constants.ProtectionEntityId);
            }

            request.ReplicationProviderSettings = string.Empty;

            if (this.ProtectionEntity.ReplicationProvider == Constants.HyperVReplicaAzure)
            {
                if (this.Direction == Constants.PrimaryToRecovery)
                {
                    var blob = new AzureFailoverInput();
                    blob.VaultLocation = this.GetCurrentValutLocation();
                    request.ReplicationProviderSettings = DataContractUtils.Serialize <AzureFailoverInput>(blob);
                }
            }

            request.ReplicationProvider = this.ProtectionEntity.ReplicationProvider;
            request.FailoverDirection   = this.Direction;

            request.NetworkID   = this.networkId;
            request.NetworkType = this.networkType;

            this.jobResponse =
                RecoveryServicesClient.StartAzureSiteRecoveryTestFailover(
                    this.ProtectionContainerId,
                    this.ProtectionEntityId,
                    request);
            this.WriteJob(this.jobResponse.Job);

            if (this.WaitForCompletion.IsPresent)
            {
                this.WaitForJobCompletion(this.jobResponse.Job.ID);
            }
        }
        /// <summary>
        /// Starts RP Planned failover.
        /// </summary>
        private void StartRpUnPlannedFailover()
        {
            RpUnplannedFailoverRequest request = new RpUnplannedFailoverRequest();

            if (this.RecoveryPlan == null)
            {
                var rp = RecoveryServicesClient.GetAzureSiteRecoveryRecoveryPlan(
                    this.RPId);
                this.RecoveryPlan = new ASRRecoveryPlan(rp.RecoveryPlan);

                this.ValidateUsageById(
                    this.RecoveryPlan.ReplicationProvider,
                    Constants.RPId);
            }

            request.ReplicationProviderSettings = string.Empty;

            if (this.RecoveryPlan.ReplicationProvider == Constants.HyperVReplicaAzure)
            {
                request.ReplicationProvider = this.RecoveryPlan.ReplicationProvider;
                if (this.Direction == Constants.PrimaryToRecovery)
                {
                    var blob = new AzureFailoverInput();
                    blob.VaultLocation = this.GetCurrentValutLocation();
                    request.ReplicationProviderSettings = DataContractUtils.Serialize <AzureFailoverInput>(blob);
                }
            }

            request.ReplicationProvider = this.RecoveryPlan.ReplicationProvider;
            request.FailoverDirection   = this.Direction;
            request.PrimaryAction       = this.PerformSourceSideActions;

            this.jobResponse = RecoveryServicesClient.StartAzureSiteRecoveryUnplannedFailover(
                this.RPId,
                request);

            this.WriteJob(this.jobResponse.Job);

            if (this.WaitForCompletion.IsPresent)
            {
                this.WaitForJobCompletion(this.jobResponse.Job.ID);
            }
        }
        /// <summary>
        /// Create Azure Site Recovery Azure Network Mapping.
        /// </summary>
        /// <param name="primaryServerId">Primary server Id</param>
        /// <param name="primaryNetworkId">Primary network Id</param>
        /// <param name="recoveryNetworkName">Recovery server Id</param>
        /// <param name="recoveryNetworkId">Recovery network Id</param>
        /// <returns>Job response</returns>
        public JobResponse NewAzureSiteRecoveryAzureNetworkMapping(
            string primaryServerId,
            string primaryNetworkId,
            string recoveryNetworkName,
            string recoveryNetworkId)
        {
            CreateAzureNetworkMappingInput createAzureNetworkMappingInput =
                new CreateAzureNetworkMappingInput();

            createAzureNetworkMappingInput.PrimaryServerId     = primaryServerId;
            createAzureNetworkMappingInput.PrimaryNetworkId    = primaryNetworkId;
            createAzureNetworkMappingInput.RecoveryNetworkName = recoveryNetworkName;
            createAzureNetworkMappingInput.RecoveryNetworkId   = recoveryNetworkId;

            NetworkMappingInput networkMappingInput = new NetworkMappingInput();

            networkMappingInput.NetworkTargetType         = NetworkTargetType.Azure.ToString();
            networkMappingInput.CreateNetworkMappingInput =
                DataContractUtils.Serialize <CreateAzureNetworkMappingInput>(createAzureNetworkMappingInput);
            return(this.GetSiteRecoveryClient()
                   .NetworkMappings
                   .Create(networkMappingInput, this.GetRequestHeaders()));
        }
 /// <summary>
 /// Serializes the supplied object to the string.
 /// </summary>
 /// <typeparam name="T">The object type.</typeparam>
 /// <param name="obj">Object to serialize</param>
 /// <returns>Serialized string.</returns>
 public static string Serialize <T>(T obj)
 {
     return(DataContractUtils <T> .Serialize(obj));
 }
        /// <summary>
        /// ProcessRecord of the command.
        /// </summary>
        public override void ExecuteCmdlet()
        {
            switch (this.ParameterSetName)
            {
            case ASRParameterSets.ByPEObject:
                this.Id = this.ProtectionEntity.ID;
                this.ProtectionContainerId = this.ProtectionEntity.ProtectionContainerId;
                this.targetNameOrId        = this.ProtectionEntity.Name;
                this.alreadyEnabled        = this.ProtectionEntity.Protected;

                break;

            case ASRParameterSets.ByIDs:
                this.targetNameOrId = this.Id;
                ProtectionEntityResponse protectionEntityResponse =
                    RecoveryServicesClient.GetAzureSiteRecoveryProtectionEntity(
                        this.ProtectionContainerId,
                        this.Id);
                this.alreadyEnabled = protectionEntityResponse.ProtectionEntity.Protected;
                this.targetNameOrId = protectionEntityResponse.ProtectionEntity.Name;

                break;
            }

            if (this.alreadyEnabled &&
                this.Protection.Equals(Constants.EnableProtection, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException(
                          string.Format(
                              Properties.Resources.ProtectionEntityAlreadyEnabled,
                              this.targetNameOrId));
            }
            else if (!this.alreadyEnabled &&
                     this.Protection.Equals(Constants.DisableProtection, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException(
                          Properties.Resources.ProtectionEntityAlreadyDisabled,
                          this.targetNameOrId);
            }

            this.ConfirmAction(
                this.Force.IsPresent || 0 != string.CompareOrdinal(this.Protection, Constants.DisableProtection),
                string.Format(Properties.Resources.DisableProtectionWarning, this.targetNameOrId),
                string.Format(Properties.Resources.DisableProtectionWhatIfMessage, this.Protection),
                this.targetNameOrId,
                () =>
            {
                try
                {
                    if (this.Protection == Constants.EnableProtection)
                    {
                        string profileId = string.Empty;
                        var input        = new EnableProtectionInput();

                        if (this.ProtectionEntity == null)
                        {
                            var pe = RecoveryServicesClient.GetAzureSiteRecoveryProtectionEntity(
                                this.ProtectionContainerId,
                                this.Id);
                            this.ProtectionEntity = new ASRProtectionEntity(pe.ProtectionEntity);
                        }

                        // Get the replciation provider from profile object otherwise assume its E2E.
                        // Let the call go without profileId set.
                        string replicationProvider = null;

                        if (this.ProtectionProfile != null)
                        {
                            profileId           = this.ProtectionProfile.ID;
                            replicationProvider = this.ProtectionProfile.ReplicationProvider;
                        }
                        else
                        {
                            string pcId = this.ProtectionContainerId ?? this.ProtectionEntity.ProtectionContainerId;
                            var pc      = RecoveryServicesClient.GetAzureSiteRecoveryProtectionContainer(
                                pcId);

                            // PC will have all profiles associated with same replciation providers only.
                            replicationProvider =
                                pc.ProtectionContainer.AvailableProtectionProfiles.Count < 1 ?
                                null :
                                pc.ProtectionContainer.AvailableProtectionProfiles[0].ReplicationProvider;

                            if (replicationProvider != Constants.HyperVReplica)
                            {
                                throw new Exception("Please provide the protection profile object. It can be chosen from available protection profiles of the protection container.");
                            }
                        }

                        if (this.ParameterSetName == ASRParameterSets.ByIDs)
                        {
                            this.ValidateUsageById(replicationProvider, "Id");
                        }

                        if (replicationProvider == Constants.HyperVReplicaAzure)
                        {
                            input.ProtectionProfileId             = this.ProtectionProfile.ID;
                            AzureEnableProtectionInput azureInput = new AzureEnableProtectionInput();
                            azureInput.HvHostVmId = this.ProtectionEntity.FabricObjectId;
                            azureInput.VmName     = this.ProtectionEntity.Name;

                            azureInput.OSType = this.OS;
                            if (string.IsNullOrWhiteSpace(this.OS))
                            {
                                azureInput.OSType = this.ProtectionEntity.OS;
                            }

                            if (string.IsNullOrWhiteSpace(this.OSDiskName))
                            {
                                azureInput.VHDId = this.ProtectionEntity.OSDiskId;
                            }
                            else
                            {
                                foreach (var disk in this.ProtectionEntity.Disks)
                                {
                                    if (disk.Name == this.OSDiskName)
                                    {
                                        azureInput.VHDId = disk.Id;
                                        break;
                                    }
                                }
                            }

                            input.ReplicationProviderInput = DataContractUtils.Serialize <AzureEnableProtectionInput>(azureInput);
                        }
                        else if (string.IsNullOrWhiteSpace(profileId))
                        {
                            input = null;
                        }
                        else
                        {
                            input.ReplicationProviderInput = string.Empty;
                            input.ProtectionProfileId      = profileId;
                        }

                        this.jobResponse =
                            RecoveryServicesClient.EnableProtection(
                                this.ProtectionContainerId,
                                this.Id,
                                input);
                    }
                    else
                    {
                        this.jobResponse =
                            RecoveryServicesClient.DisbleProtection(
                                this.ProtectionContainerId,
                                this.Id);
                    }

                    this.WriteJob(this.jobResponse.Job);

                    if (this.WaitForCompletion.IsPresent)
                    {
                        this.WaitForJobCompletion(this.jobResponse.Job.ID);
                    }
                }
                catch (Exception exception)
                {
                    this.HandleException(exception);
                }
            });
        }