/// <summary>
        ///     Creates Replication Plan
        /// </summary>
        private void CreateRecoveryPlan()
        {
            var createRecoveryPlanInputProperties = new CreateRecoveryPlanInputProperties
            {
                FailoverDeploymentModel = this.failoverDeploymentModel,
                Groups           = new List <RecoveryPlanGroup>(),
                PrimaryFabricId  = this.primaryserver,
                RecoveryFabricId = this.recoveryserver
            };

            var recoveryPlanGroup = new RecoveryPlanGroup
            {
                GroupType = RecoveryPlanGroupType.Boot,
                ReplicationProtectedItems = new List <RecoveryPlanProtectedItem>(),
                StartGroupActions         = new List <RecoveryPlanAction>(),
                EndGroupActions           = new List <RecoveryPlanAction>()
            };

            foreach (var rpi in this.ReplicationProtectedItem)
            {
                var fabricName = Utilities.GetValueFromArmId(
                    rpi.ID,
                    ARMResourceTypeConstants.ReplicationFabrics);

                var replicationProtectedItemResponse = this.RecoveryServicesClient
                                                       .GetAzureSiteRecoveryReplicationProtectedItem(
                    fabricName,
                    Utilities.GetValueFromArmId(
                        rpi.ID,
                        ARMResourceTypeConstants.ReplicationProtectionContainers),
                    rpi.Name);

                string VmId = null;

                if (replicationProtectedItemResponse.Properties.ProviderSpecificDetails.GetType() ==
                    typeof(HyperVReplicaAzureReplicationDetails))
                {
                    VmId = ((HyperVReplicaAzureReplicationDetails)replicationProtectedItemResponse
                            .Properties.ProviderSpecificDetails).VmId;
                }
                else if (replicationProtectedItemResponse.Properties.ProviderSpecificDetails
                         .GetType() ==
                         typeof(HyperVReplicaReplicationDetails))
                {
                    VmId = ((HyperVReplicaReplicationDetails)replicationProtectedItemResponse
                            .Properties.ProviderSpecificDetails).VmId;
                }
                else if (replicationProtectedItemResponse.Properties.ProviderSpecificDetails
                         .GetType() ==
                         typeof(HyperVReplicaBlueReplicationDetails))
                {
                    VmId = ((HyperVReplicaBlueReplicationDetails)replicationProtectedItemResponse
                            .Properties.ProviderSpecificDetails).VmId;
                }
                else if (replicationProtectedItemResponse.Properties.ProviderSpecificDetails
                         .GetType() ==
                         typeof(InMageAzureV2ReplicationDetails))
                {
                    VmId = ((InMageAzureV2ReplicationDetails)replicationProtectedItemResponse
                            .Properties.ProviderSpecificDetails).VmId;
                }
                else if (replicationProtectedItemResponse.Properties.ProviderSpecificDetails
                         .GetType() ==
                         typeof(InMageReplicationDetails))
                {
                    VmId = ((InMageReplicationDetails)replicationProtectedItemResponse
                            .Properties.ProviderSpecificDetails).VmId;
                }
                else if (replicationProtectedItemResponse.Properties.ProviderSpecificDetails.GetType() == typeof(A2AReplicationDetails))
                {
                    A2AReplicationDetails a2aReplicationDetails =
                        ((A2AReplicationDetails)replicationProtectedItemResponse
                         .Properties
                         .ProviderSpecificDetails);
                    if (a2aReplicationDetails.FabricObjectId.IndexOf(
                            Constants.ClassicCompute,
                            StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        createRecoveryPlanInputProperties.FailoverDeploymentModel =
                            Management.RecoveryServices.SiteRecovery.Models.FailoverDeploymentModel.Classic;
                    }
                    else if (a2aReplicationDetails.FabricObjectId.IndexOf(
                                 Constants.Compute,
                                 StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        createRecoveryPlanInputProperties.FailoverDeploymentModel =
                            Management.RecoveryServices.SiteRecovery.Models.FailoverDeploymentModel.ResourceManager;
                    }
                }

                var recoveryPlanProtectedItem = new RecoveryPlanProtectedItem();
                recoveryPlanProtectedItem.Id = replicationProtectedItemResponse.Id;
                recoveryPlanProtectedItem.VirtualMachineId = VmId;
                recoveryPlanGroup.ReplicationProtectedItems.Add(recoveryPlanProtectedItem);
            }

            createRecoveryPlanInputProperties.Groups.Add(recoveryPlanGroup);

            // Add zone to zone details.
            if (this.ParameterSetName == ASRParameterSets.AzureZoneToZone)
            {
                var recoveryPlanA2AInput = new RecoveryPlanA2AInput
                {
                    PrimaryZone  = this.PrimaryZone,
                    RecoveryZone = this.RecoveryZone
                };

                createRecoveryPlanInputProperties.ProviderSpecificInput = new List <RecoveryPlanProviderSpecificInput>();
                createRecoveryPlanInputProperties.ProviderSpecificInput.Add(recoveryPlanA2AInput);
            }


            var createRecoveryPlanInput =
                new CreateRecoveryPlanInput {
                Properties = createRecoveryPlanInputProperties
            };

            this.CreateRecoveryPlan(
                this.Name,
                createRecoveryPlanInput);
        }
        /// <summary>
        ///     Helper method for Azure to Azure replication scenario.
        /// </summary>
        private void AzureToAzureReplication(EnableProtectionInput input)
        {
            var providerSettings = new A2AEnableProtectionInput()
            {
                FabricObjectId      = this.AzureVmId,
                RecoveryContainerId =
                    this.ProtectionContainerMapping.TargetProtectionContainerId,
                VmDisks                          = new List <A2AVmDiskInputDetails>(),
                VmManagedDisks                   = new List <A2AVmManagedDiskInputDetails>(),
                RecoveryResourceGroupId          = this.RecoveryResourceGroupId,
                RecoveryCloudServiceId           = this.RecoveryCloudServiceId,
                RecoveryAvailabilitySetId        = this.RecoveryAvailabilitySetId,
                RecoveryBootDiagStorageAccountId = this.RecoveryBootDiagStorageAccountId,
                RecoveryAzureNetworkId           = this.RecoveryAzureNetworkId,
                RecoverySubnetName               = this.RecoveryAzureSubnetName,
                RecoveryAvailabilityZone         = this.RecoveryAvailabilityZone
            };

            if (!string.IsNullOrEmpty(this.ReplicationGroupName))
            {
                providerSettings.MultiVmGroupName = this.ReplicationGroupName;
            }

            if (!string.IsNullOrEmpty(this.RecoveryCloudServiceId))
            {
                providerSettings.RecoveryResourceGroupId = null;
            }

            if (this.AzureToAzureDiskReplicationConfiguration == null)
            {
                if (this.AzureVmId.ToLower().Contains(ARMResourceTypeConstants.Compute.ToLower()))
                {
                    var vmName             = Utilities.GetValueFromArmId(this.AzureVmId, ARMResourceTypeConstants.VirtualMachine);
                    var vmRg               = Utilities.GetValueFromArmId(this.AzureVmId, ARMResourceTypeConstants.ResourceGroups);
                    var subscriptionId     = Utilities.GetValueFromArmId(this.AzureVmId, ARMResourceTypeConstants.Subscriptions);
                    var tempSubscriptionId = this.ComputeManagementClient.GetComputeManagementClient.SubscriptionId;
                    this.ComputeManagementClient.GetComputeManagementClient.SubscriptionId = subscriptionId;
                    var virtualMachine = this.ComputeManagementClient.GetComputeManagementClient.
                                         VirtualMachines.GetWithHttpMessagesAsync(vmRg, vmName).GetAwaiter().GetResult().Body;
                    this.ComputeManagementClient.GetComputeManagementClient.SubscriptionId = tempSubscriptionId;

                    if (virtualMachine == null)
                    {
                        throw new Exception("Azure Vm not found");
                    }

                    // if managed disk
                    if (virtualMachine.StorageProfile.OsDisk.ManagedDisk != null)
                    {
                        if (this.RecoveryAzureStorageAccountId != null)
                        {
                            throw new Exception("Recovery Storage account is not required for managed disk vm to protect");
                        }
                        var osDisk = virtualMachine.StorageProfile.OsDisk;
                        providerSettings.VmManagedDisks.Add(new A2AVmManagedDiskInputDetails
                        {
                            DiskId = osDisk.ManagedDisk.Id,
                            RecoveryResourceGroupId             = this.RecoveryResourceGroupId,
                            PrimaryStagingAzureStorageAccountId = this.LogStorageAccountId,
                            RecoveryReplicaDiskAccountType      = osDisk.ManagedDisk.StorageAccountType,
                            RecoveryTargetDiskAccountType       = osDisk.ManagedDisk.StorageAccountType
                        });
                        if (virtualMachine.StorageProfile.DataDisks != null)
                        {
                            foreach (var dataDisk in virtualMachine.StorageProfile.DataDisks)
                            {
                                providerSettings.VmManagedDisks.Add(new A2AVmManagedDiskInputDetails
                                {
                                    DiskId = dataDisk.ManagedDisk.Id,
                                    RecoveryResourceGroupId             = this.RecoveryResourceGroupId,
                                    PrimaryStagingAzureStorageAccountId = LogStorageAccountId,
                                    RecoveryReplicaDiskAccountType      = dataDisk.ManagedDisk.StorageAccountType,
                                    RecoveryTargetDiskAccountType       = dataDisk.ManagedDisk.StorageAccountType
                                });
                            }
                        }
                    }
                    else
                    {
                        if (this.RecoveryAzureStorageAccountId == null)
                        {
                            throw new Exception("Recovery Storage account is required for non-managed disk vm to protect");
                        }

                        var osDisk = virtualMachine.StorageProfile.OsDisk;
                        providerSettings.VmDisks.Add(new A2AVmDiskInputDetails
                        {
                            DiskUri = osDisk.Vhd.Uri,
                            RecoveryAzureStorageAccountId       = this.RecoveryAzureStorageAccountId,
                            PrimaryStagingAzureStorageAccountId = LogStorageAccountId
                        });
                        if (virtualMachine.StorageProfile.DataDisks != null)
                        {
                            foreach (var dataDisk in virtualMachine.StorageProfile.DataDisks)
                            {
                                providerSettings.VmDisks.Add(new A2AVmDiskInputDetails
                                {
                                    DiskUri = dataDisk.Vhd.Uri,
                                    RecoveryAzureStorageAccountId       = this.RecoveryAzureStorageAccountId,
                                    PrimaryStagingAzureStorageAccountId = LogStorageAccountId
                                });
                            }
                        }
                    }
                }
                else
                {
                    throw new Exception("Pass Disk details for Classic VMs");
                }
            }
            else
            {
                foreach (ASRAzuretoAzureDiskReplicationConfig disk in this.AzureToAzureDiskReplicationConfiguration)
                {
                    if (disk.IsManagedDisk)
                    {
                        providerSettings.VmManagedDisks.Add(new A2AVmManagedDiskInputDetails
                        {
                            DiskId = disk.DiskId,
                            RecoveryResourceGroupId             = disk.RecoveryResourceGroupId,
                            PrimaryStagingAzureStorageAccountId = disk.LogStorageAccountId,
                            RecoveryReplicaDiskAccountType      = disk.RecoveryReplicaDiskAccountType,
                            RecoveryTargetDiskAccountType       = disk.RecoveryTargetDiskAccountType,
                            RecoveryDiskEncryptionSetId         = disk.RecoveryDiskEncryptionSetId,
                            DiskEncryptionInfo =
                                Utilities.A2AEncryptionDetails(
                                    disk.DiskEncryptionSecretUrl,
                                    disk.DiskEncryptionVaultId,
                                    disk.KeyEncryptionKeyUrl,
                                    disk.KeyEncryptionVaultId)
                        });
                    }
                    else
                    {
                        providerSettings.VmDisks.Add(new A2AVmDiskInputDetails
                        {
                            DiskUri = disk.VhdUri,
                            RecoveryAzureStorageAccountId =
                                disk.RecoveryAzureStorageAccountId,
                            PrimaryStagingAzureStorageAccountId =
                                disk.LogStorageAccountId,
                        });
                    }
                }
            }

            providerSettings.DiskEncryptionInfo =
                Utilities.A2AEncryptionDetails(
                    this.DiskEncryptionSecretUrl,
                    this.DiskEncryptionVaultId,
                    this.KeyEncryptionKeyUrl,
                    this.KeyEncryptionVaultId);

            input.Properties.ProviderSpecificDetails = providerSettings;
        }
        /// <summary>
        ///     Helper method for E2A and H2A scenario.
        /// </summary>
        private void EnterpriseAndHyperVToAzure(EnableProtectionInput input)
        {
            var providerSettings = new HyperVReplicaAzureEnableProtectionInput();

            providerSettings.HvHostVmId        = this.ProtectableItem.FabricObjectId;
            providerSettings.VmName            = this.ProtectableItem.FriendlyName;
            providerSettings.TargetAzureVmName = string.IsNullOrEmpty(this.RecoveryVmName)
                                                    ? this.ProtectableItem.FriendlyName
                                                    : this.RecoveryVmName;

            if (!string.IsNullOrEmpty(this.RecoveryAzureNetworkId))
            {
                providerSettings.TargetAzureNetworkId = this.RecoveryAzureNetworkId;
            }

            if (!string.IsNullOrEmpty(this.RecoveryAzureSubnetName))
            {
                providerSettings.TargetAzureSubnetId = this.RecoveryAzureSubnetName;
            }

            if (!string.IsNullOrEmpty(this.LogStorageAccountId))
            {
                providerSettings.LogStorageAccountId = this.LogStorageAccountId;
            }

            // Id disk details are missing in input PE object, get the latest PE.
            if (string.IsNullOrEmpty(this.ProtectableItem.OS))
            {
                // Just checked for OS to see whether the disk details got filled up or not
                var protectableItemResponse = this.RecoveryServicesClient
                                              .GetAzureSiteRecoveryProtectableItem(
                    Utilities.GetValueFromArmId(
                        this.ProtectableItem.ID,
                        ARMResourceTypeConstants.ReplicationFabrics),
                    this.ProtectableItem.ProtectionContainerId,
                    this.ProtectableItem.Name);

                this.ProtectableItem = new ASRProtectableItem(protectableItemResponse);
            }

            if (string.IsNullOrWhiteSpace(this.OS))
            {
                providerSettings.OsType = (string.Compare(
                                               this.ProtectableItem.OS,
                                               Constants.OSWindows,
                                               StringComparison.OrdinalIgnoreCase) ==
                                           0) ||
                                          (string.Compare(
                                               this.ProtectableItem.OS,
                                               Constants.OSLinux) ==
                                           0)
                                ? this.ProtectableItem.OS
                                : Constants.OSWindows;
            }
            else
            {
                providerSettings.OsType = this.OS;
            }

            if (string.IsNullOrWhiteSpace(this.OSDiskName))
            {
                providerSettings.VhdId = this.ProtectableItem.OSDiskId;
            }
            else
            {
                foreach (var disk in this.ProtectableItem.Disks)
                {
                    if (0 == string.Compare(disk.Name, this.OSDiskName, true))
                    {
                        providerSettings.VhdId = disk.Id;
                        break;
                    }
                }
            }

            if (this.RecoveryAzureStorageAccountId != null)
            {
                providerSettings.TargetStorageAccountId =
                    this.RecoveryAzureStorageAccountId;
            }

            var deploymentType = Utilities.GetValueFromArmId(
                this.RecoveryAzureStorageAccountId,
                ARMResourceTypeConstants.Providers);

            if (deploymentType.ToLower()
                .Contains(Constants.Classic.ToLower()))
            {
                providerSettings.TargetAzureV1ResourceGroupId =
                    this.RecoveryResourceGroupId;
                providerSettings.TargetAzureV2ResourceGroupId = null;
            }
            else
            {
                providerSettings.TargetAzureV1ResourceGroupId = null;
                providerSettings.TargetAzureV2ResourceGroupId =
                    this.RecoveryResourceGroupId;
            }

            input.Properties.ProviderSpecificDetails = providerSettings;
        }
        private void VMwareToAzureReplication(EnableProtectionInput input)
        {
            var providerSettings = new InMageAzureV2EnableProtectionInput
            {
                ProcessServerId = this.ProcessServer.Id,
                MasterTargetId  =
                    this.ProcessServer.Id,     // Assumption: PS and MT are same.
                RunAsAccountId       = this.Account.AccountId,
                StorageAccountId     = this.RecoveryAzureStorageAccountId,
                TargetAzureNetworkId = this.RecoveryAzureNetworkId,
                TargetAzureSubnetId  = this.RecoveryAzureSubnetName,
                LogStorageAccountId  = this.LogStorageAccountId,
                MultiVmGroupName     = this.ReplicationGroupName,
                DiskType             = this.DiskType,
                MultiVmGroupId       = this.ReplicationGroupName,
                TargetAzureVmName    = string.IsNullOrEmpty(this.RecoveryVmName)
                                            ? this.ProtectableItem.FriendlyName
                                            : this.RecoveryVmName,
                EnableRdpOnTargetOption = Constants.NeverEnableRDPOnTargetOption,
                DiskEncryptionSetId     = this.DiskEncryptionSetId
            };

            if (this.IsParameterBound(c => c.InMageAzureV2DiskInput))
            {
                List <InMageAzureV2DiskInputDetails> inmageAzureV2DiskInput = InMageAzureV2DiskInput.Select(
                    p => new InMageAzureV2DiskInputDetails()
                {
                    DiskId              = p.DiskId,
                    DiskType            = p.DiskType,
                    LogStorageAccountId = p.LogStorageAccountId,
                    DiskEncryptionSetId = p.DiskEncryptionSetId
                }).ToList();
                providerSettings.DisksToInclude = inmageAzureV2DiskInput;
            }

            providerSettings.TargetAzureV2ResourceGroupId =
                this.RecoveryResourceGroupId;

            // Check if the Replication Group Name is valid.
            if (this.ReplicationGroupName != null)
            {
                // Get all the Protected Items in the Protection Container.
                var fabricName = Utilities.GetValueFromArmId(
                    this.ProtectableItem.ID,
                    ARMResourceTypeConstants.ReplicationFabrics);
                var protectionContainerName = Utilities.GetValueFromArmId(
                    this.ProtectableItem.ID,
                    ARMResourceTypeConstants.ReplicationProtectionContainers);
                var listReplicationProtectedItems =
                    this.RecoveryServicesClient
                    .GetAzureSiteRecoveryReplicationProtectedItem(
                        fabricName,
                        protectionContainerName);

                // Loop over all the Protected Items and find if the Multi VM Group already exists.
                var flag = false;
                foreach (var rpi in listReplicationProtectedItems)
                // Check if the Replication Protected Item is an InMageAzureV2 Instance.
                {
                    if (rpi.Properties.ProviderSpecificDetails is InMageAzureV2ReplicationDetails)
                    {
                        // Get the InMageAzureV2 specific details.
                        var providerSpecificDetails =
                            (InMageAzureV2ReplicationDetails)rpi.Properties
                            .ProviderSpecificDetails;

                        // Compare the Multi VM Group Name.
                        if (string.Compare(
                                this.ReplicationGroupName,
                                providerSpecificDetails.MultiVmGroupName,
                                StringComparison.OrdinalIgnoreCase) ==
                            0)
                        {
                            // Multi VM Group found.
                            // Set the values in the InMageAzureV2 Provider specific input.
                            providerSettings.MultiVmGroupName =
                                providerSpecificDetails.MultiVmGroupName;
                            providerSettings.MultiVmGroupId =
                                providerSpecificDetails.MultiVmGroupId;
                            flag = true;
                            break;
                        }
                    }
                }

                // Check if the Multi VM Group was found or is to be created now.
                if (flag == false)
                {
                    // Multi VM Group was not found.
                    // Create a new Multi VM Group and Set the values in the
                    // InMageAzureV2 Provider specific input.
                    providerSettings.MultiVmGroupName = this.ReplicationGroupName;
                    providerSettings.MultiVmGroupId   = Guid.NewGuid().ToString();
                }
            }

            // Set the InMageAzureV2 Provider specific input in the Enable Protection Input.
            input.Properties.ProviderSpecificDetails = providerSettings;
        }
        /// <summary>
        ///     ProcessRecord of the command.
        /// </summary>
        public override void ExecuteSiteRecoveryCmdlet()
        {
            base.ExecuteSiteRecoveryCmdlet();

            if (this.ShouldProcess(this.Name, VerbsCommon.New))
            {
                var policy = this.RecoveryServicesClient.GetAzureSiteRecoveryPolicy(
                    Utilities.GetValueFromArmId(
                        this.ProtectionContainerMapping.PolicyId,
                        ARMResourceTypeConstants.ReplicationPolicies));
                var policyInstanceType = policy.Properties.ProviderSpecificDetails;

                var enableProtectionProviderSpecificInput =
                    new EnableProtectionProviderSpecificInput();
                var inputProperties = new EnableProtectionInputProperties
                {
                    PolicyId = this.ProtectionContainerMapping.PolicyId,
                    // A2A there is no ProtectableItem
                    ProtectableItemId       = this.ProtectableItem == null ? null : this.ProtectableItem.ID,
                    ProviderSpecificDetails = enableProtectionProviderSpecificInput
                };

                var input = new EnableProtectionInput {
                    Properties = inputProperties
                };

                switch (this.ParameterSetName)
                {
                case ASRParameterSets.EnterpriseToEnterprise:
                    if (!(policyInstanceType is HyperVReplicaPolicyDetails) &&
                        !(policyInstanceType is HyperVReplicaBluePolicyDetails))
                    {
                        throw new PSArgumentException(
                                  string.Format(
                                      Resources.ContainerMappingParameterSetMismatch,
                                      this.ProtectionContainerMapping.Name,
                                      policyInstanceType));
                    }
                    break;

                case ASRParameterSets.EnterpriseToAzure:
                case ASRParameterSets.HyperVSiteToAzure:
                    if (!(policyInstanceType is HyperVReplicaAzurePolicyDetails))
                    {
                        throw new PSArgumentException(
                                  string.Format(
                                      Resources.ContainerMappingParameterSetMismatch,
                                      this.ProtectionContainerMapping.Name,
                                      policyInstanceType));
                    }
                    EnterpriseAndHyperVToAzure(input);
                    break;

                case VMwareToAzureWithDiskType:
                case VMwareToAzureParameterSet:
                    if (!(policyInstanceType is InMageAzureV2PolicyDetails))
                    {
                        throw new PSArgumentException(
                                  string.Format(
                                      Resources.ContainerMappingParameterSetMismatch,
                                      this.ProtectionContainerMapping.Name,
                                      policyInstanceType));
                    }

                    VMwareToAzureReplication(input);
                    break;

                case ASRParameterSets.AzureToAzureWithoutDiskDetails:
                case ASRParameterSets.AzureToAzure:
                    if (!(policyInstanceType is A2APolicyDetails))
                    {
                        throw new PSArgumentException(
                                  string.Format(
                                      Properties.Resources.ContainerMappingParameterSetMismatch,
                                      this.ProtectionContainerMapping.Name,
                                      policyInstanceType));
                    }
                    AzureToAzureReplication(input);
                    break;

                default:
                    break;
                }

                this.response = this.RecoveryServicesClient.EnableProtection(
                    Utilities.GetValueFromArmId(
                        this.ProtectionContainerMapping.ID,
                        ARMResourceTypeConstants.ReplicationFabrics),
                    Utilities.GetValueFromArmId(
                        this.ProtectionContainerMapping.ID,
                        ARMResourceTypeConstants.ReplicationProtectionContainers),
                    this.Name,
                    input);

                this.jobResponse = this.RecoveryServicesClient.GetAzureSiteRecoveryJobDetails(
                    PSRecoveryServicesClient.GetJobIdFromReponseLocation(this.response.Location));

                this.WriteObject(new ASRJob(this.jobResponse));

                if (this.WaitForCompletion.IsPresent)
                {
                    this.WaitForJobCompletion(this.jobResponse.Name);

                    this.jobResponse = this.RecoveryServicesClient.GetAzureSiteRecoveryJobDetails(
                        PSRecoveryServicesClient
                        .GetJobIdFromReponseLocation(this.response.Location));

                    this.WriteObject(new ASRJob(this.jobResponse));
                }
            }
        }
示例#6
0
        /// <summary>
        ///     ProcessRecord of the command.
        /// </summary>
        public override void ExecuteSiteRecoveryCmdlet()
        {
            base.ExecuteSiteRecoveryCmdlet();

            if (this.ShouldProcess(
                    this.InputObject.FriendlyName,
                    VerbsCommon.Set))
            {
                var replicationProtectedItemResponse = this.RecoveryServicesClient
                                                       .GetAzureSiteRecoveryReplicationProtectedItem(
                    Utilities.GetValueFromArmId(
                        this.InputObject.ID,
                        ARMResourceTypeConstants.ReplicationFabrics),
                    Utilities.GetValueFromArmId(
                        this.InputObject.ID,
                        ARMResourceTypeConstants.ReplicationProtectionContainers),
                    this.InputObject.Name);

                var provider = replicationProtectedItemResponse.Properties.ProviderSpecificDetails;

                // Check for Replication Provider type HyperVReplicaAzure/InMageAzureV2/A2A
                if (!(provider is HyperVReplicaAzureReplicationDetails) &&
                    !(provider is InMageAzureV2ReplicationDetails) &&
                    !(provider is A2AReplicationDetails))
                {
                    this.WriteWarning(
                        Resources.UnsupportedReplicationProvidedForUpdateVmProperties);
                    return;
                }

                // Check for at least one option
                if (string.IsNullOrEmpty(this.Name) &&
                    string.IsNullOrEmpty(this.Size) &&
                    string.IsNullOrEmpty(this.UpdateNic) &&
                    string.IsNullOrEmpty(this.RecoveryNetworkId) &&
                    string.IsNullOrEmpty(this.PrimaryNic) &&
                    this.UseManagedDisk == null &&
                    this.IsParameterBound(c => c.RecoveryAvailabilitySet) &&
                    string.IsNullOrEmpty(this.RecoveryCloudServiceId) &&
                    string.IsNullOrEmpty(this.RecoveryResourceGroupId) &&
                    string.IsNullOrEmpty(this.LicenseType) &&
                    string.IsNullOrEmpty(this.RecoveryBootDiagStorageAccountId) &&
                    this.AzureToAzureUpdateReplicationConfiguration == null)
                {
                    this.WriteWarning(Resources.ArgumentsMissingForUpdateVmProperties);
                    return;
                }

                // Both primary & recovery inputs should be present
                if (this.ASRVMNicConfiguration == null &&
                    (string.IsNullOrEmpty(this.UpdateNic) ^
                     string.IsNullOrEmpty(this.RecoveryNetworkId)))
                {
                    this.WriteWarning(Resources.NetworkArgumentsMissingForUpdateVmProperties);
                    return;
                }

                // NSG, LB and PIP only for A2A provider.
                if ((!string.IsNullOrEmpty(RecoveryNetworkSecurityGroupId) ||
                     !string.IsNullOrEmpty(RecoveryPublicIPAddressId) ||
                     RecoveryLBBackendAddressPoolId != null &&
                     RecoveryLBBackendAddressPoolId.Length > 0) &&
                    !(provider is A2AReplicationDetails))
                {
                    this.WriteWarning(
                        Resources.UnsupportedReplicationProvidedForNetworkingResources);
                    return;
                }

                if (this.ASRVMNicConfiguration != null &&
                    !(provider is A2AReplicationDetails))
                {
                    this.WriteWarning(Resources.UnsupportedReplicationProvidedForASRVMNicConfig);
                    return;
                }

                if (this.ASRVMNicConfiguration != null &&
                    !string.IsNullOrEmpty(this.UpdateNic))
                {
                    this.WriteWarning(Resources.ASRVMNicsAndUpdateNicNotAllowed);
                    return;
                }

                var vmName = this.Name;
                var vmSize = this.Size;
                var vmRecoveryNetworkId     = this.RecoveryNetworkId;
                var licenseType             = this.LicenseType;
                var recoveryResourceGroupId = this.RecoveryResourceGroupId;
                var recoveryCloudServiceId  = this.RecoveryCloudServiceId;
                var useManagedDisk          = this.UseManagedDisk;
                var availabilitySetId       = this.RecoveryAvailabilitySet;
                var primaryNic = this.PrimaryNic;
                var diskIdToDiskEncryptionMap = this.DiskIdToDiskEncryptionSetMap;
                var tfoNetworkId          = string.Empty;
                var vMNicInputDetailsList = new List <VMNicInputDetails>();
                var providerSpecificInput = new UpdateReplicationProtectedItemProviderInput();

                if (provider is HyperVReplicaAzureReplicationDetails)
                {
                    var providerSpecificDetails =
                        (HyperVReplicaAzureReplicationDetails)replicationProtectedItemResponse
                        .Properties.ProviderSpecificDetails;

                    if (string.IsNullOrEmpty(this.Name))
                    {
                        vmName = providerSpecificDetails.RecoveryAzureVmName;
                    }

                    if (string.IsNullOrEmpty(this.Size))
                    {
                        vmSize = providerSpecificDetails.RecoveryAzureVMSize;
                    }

                    if (string.IsNullOrEmpty(this.RecoveryNetworkId))
                    {
                        vmRecoveryNetworkId = providerSpecificDetails
                                              .SelectedRecoveryAzureNetworkId;
                    }

                    if (string.IsNullOrEmpty(this.LicenseType))
                    {
                        licenseType = providerSpecificDetails.LicenseType;
                    }

                    availabilitySetId = this.IsParameterBound(c => c.RecoveryAvailabilitySet)
                        ? this.RecoveryAvailabilitySet
                        : providerSpecificDetails.RecoveryAvailabilitySetId;

                    if (string.IsNullOrEmpty(this.UseManagedDisk))
                    {
                        useManagedDisk = providerSpecificDetails.UseManagedDisks;
                    }

                    if (string.IsNullOrEmpty(this.RecoveryResourceGroupId))
                    {
                        recoveryResourceGroupId =
                            providerSpecificDetails.RecoveryAzureResourceGroupId;
                    }

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.PrimaryNic)))
                    {
                        primaryNic = providerSpecificDetails.SelectedSourceNicId;
                    }

                    if (this.DiskIdToDiskEncryptionSetMap == null ||
                        this.DiskIdToDiskEncryptionSetMap.Count == 0)
                    {
                        diskIdToDiskEncryptionMap = providerSpecificDetails.AzureVmDiskDetails.
                                                    ToDictionary(x => x.DiskId, x => x.DiskEncryptionSetId);
                    }

                    var deploymentType = Utilities.GetValueFromArmId(
                        providerSpecificDetails.RecoveryAzureStorageAccount,
                        ARMResourceTypeConstants.Providers);
                    if (deploymentType.ToLower()
                        .Contains(Constants.Classic.ToLower()))
                    {
                        providerSpecificInput =
                            new HyperVReplicaAzureUpdateReplicationProtectedItemInput
                        {
                            RecoveryAzureV1ResourceGroupId = recoveryResourceGroupId,
                            RecoveryAzureV2ResourceGroupId = null
                        };
                    }
                    else
                    {
                        providerSpecificInput =
                            new HyperVReplicaAzureUpdateReplicationProtectedItemInput
                        {
                            RecoveryAzureV1ResourceGroupId = null,
                            RecoveryAzureV2ResourceGroupId = recoveryResourceGroupId,
                            UseManagedDisks           = useManagedDisk,
                            DiskIdToDiskEncryptionMap = this.DiskIdToDiskEncryptionSetMap
                        };
                    }

                    vMNicInputDetailsList = getNicListToUpdate(providerSpecificDetails.VmNics);
                }
                else if (provider is InMageAzureV2ReplicationDetails)
                {
                    var providerSpecificDetails =
                        (InMageAzureV2ReplicationDetails)replicationProtectedItemResponse.Properties.ProviderSpecificDetails;

                    if (string.IsNullOrEmpty(this.Name))
                    {
                        vmName = providerSpecificDetails.RecoveryAzureVMName;
                    }

                    if (string.IsNullOrEmpty(this.Size))
                    {
                        vmSize = providerSpecificDetails.RecoveryAzureVMSize;
                    }

                    if (string.IsNullOrEmpty(this.RecoveryNetworkId))
                    {
                        vmRecoveryNetworkId = providerSpecificDetails.SelectedRecoveryAzureNetworkId;
                    }

                    if (string.IsNullOrEmpty(this.LicenseType))
                    {
                        licenseType = providerSpecificDetails.LicenseType;
                    }

                    availabilitySetId = this.IsParameterBound(c => c.RecoveryAvailabilitySet)
                        ? this.RecoveryAvailabilitySet : providerSpecificDetails.RecoveryAvailabilitySetId;

                    if (string.IsNullOrEmpty(this.UseManagedDisk))
                    {
                        useManagedDisk = providerSpecificDetails.UseManagedDisks;
                    }

                    if (string.IsNullOrEmpty(this.RecoveryResourceGroupId))
                    {
                        recoveryResourceGroupId = providerSpecificDetails.RecoveryAzureResourceGroupId;
                    }

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.PrimaryNic)))
                    {
                        primaryNic = providerSpecificDetails.SelectedSourceNicId;
                    }

                    var deploymentType = Utilities.GetValueFromArmId(
                        providerSpecificDetails.TargetVmId,
                        ARMResourceTypeConstants.Providers);
                    if (deploymentType.ToLower()
                        .Contains(Constants.ClassicCompute.ToLower()))
                    {
                        providerSpecificInput =
                            new InMageAzureV2UpdateReplicationProtectedItemInput
                        {
                            RecoveryAzureV1ResourceGroupId = recoveryResourceGroupId,
                            RecoveryAzureV2ResourceGroupId = null
                        };
                    }
                    else
                    {
                        providerSpecificInput =
                            new InMageAzureV2UpdateReplicationProtectedItemInput
                        {
                            RecoveryAzureV1ResourceGroupId = null,
                            RecoveryAzureV2ResourceGroupId = recoveryResourceGroupId,
                            UseManagedDisks = useManagedDisk
                        };
                    }
                    vMNicInputDetailsList = getNicListToUpdate(providerSpecificDetails.VmNics);
                }
                else if (provider is A2AReplicationDetails)
                {
                    A2AReplicationDetails providerSpecificDetails = (A2AReplicationDetails)replicationProtectedItemResponse.Properties.ProviderSpecificDetails;

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.RecoveryResourceGroupId)))
                    {
                        recoveryResourceGroupId =
                            providerSpecificDetails.RecoveryAzureResourceGroupId;
                    }

                    availabilitySetId = this.IsParameterBound(c => c.RecoveryAvailabilitySet)
                        ? this.RecoveryAvailabilitySet
                        : providerSpecificDetails.RecoveryAvailabilitySet;

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.RecoveryNetworkId)))
                    {
                        vmRecoveryNetworkId = providerSpecificDetails.SelectedRecoveryAzureNetworkId;
                    }

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.RecoveryCloudServiceId)))
                    {
                        recoveryCloudServiceId =
                            providerSpecificDetails.RecoveryCloudService;
                    }

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.RecoveryBootDiagStorageAccountId)))
                    {
                        this.RecoveryBootDiagStorageAccountId = providerSpecificDetails.RecoveryBootDiagStorageAccountId;
                    }

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.TfoAzureVMName)))
                    {
                        this.TfoAzureVMName = providerSpecificDetails.TfoAzureVMName;
                    }

                    if (!this.MyInvocation.BoundParameters.ContainsKey(
                            Utilities.GetMemberName(() => this.Name)))
                    {
                        vmName = providerSpecificDetails.RecoveryAzureVMName;
                    }

                    List <A2AVmManagedDiskUpdateDetails> managedDiskUpdateDetails = null;

                    // ManagedDisk case
                    if (this.AzureToAzureUpdateReplicationConfiguration == null && providerSpecificDetails.ProtectedManagedDisks != null)
                    {
                        managedDiskUpdateDetails = new List <A2AVmManagedDiskUpdateDetails>();
                        foreach (var managedDisk in providerSpecificDetails.ProtectedManagedDisks)
                        {
                            managedDiskUpdateDetails.Add(
                                new A2AVmManagedDiskUpdateDetails(
                                    managedDisk.DiskId,
                                    managedDisk.RecoveryTargetDiskAccountType,
                                    managedDisk.RecoveryReplicaDiskAccountType,
                                    failoverDiskName: managedDisk.FailoverDiskName,
                                    tfoDiskName: managedDisk.TfoDiskName));
                        }
                    }
                    else if (this.AzureToAzureUpdateReplicationConfiguration != null && this.AzureToAzureUpdateReplicationConfiguration[0].IsManagedDisk)
                    {
                        managedDiskUpdateDetails = new List <A2AVmManagedDiskUpdateDetails>();
                        foreach (var managedDisk in this.AzureToAzureUpdateReplicationConfiguration)
                        {
                            managedDiskUpdateDetails.Add(
                                new A2AVmManagedDiskUpdateDetails(
                                    managedDisk.DiskId,
                                    managedDisk.RecoveryTargetDiskAccountType,
                                    managedDisk.RecoveryReplicaDiskAccountType,
                                    failoverDiskName: managedDisk.FailoverDiskName,
                                    tfoDiskName: managedDisk.TfoDiskName,
                                    diskEncryptionInfo: Utilities.A2AEncryptionDetails(
                                        managedDisk.DiskEncryptionSecretUrl,
                                        managedDisk.DiskEncryptionVaultId,
                                        managedDisk.KeyEncryptionKeyUrl,
                                        managedDisk.KeyEncryptionVaultId)));
                        }
                    }

                    providerSpecificInput = new A2AUpdateReplicationProtectedItemInput()
                    {
                        RecoveryCloudServiceId           = this.RecoveryCloudServiceId,
                        RecoveryResourceGroupId          = this.RecoveryResourceGroupId,
                        RecoveryBootDiagStorageAccountId = this.RecoveryBootDiagStorageAccountId,
                        ManagedDiskUpdateDetails         = managedDiskUpdateDetails,
                        TfoAzureVMName     = this.TfoAzureVMName,
                        DiskEncryptionInfo = Utilities.A2AEncryptionDetails(
                            this.DiskEncryptionSecretUrl,
                            this.DiskEncryptionVaultId,
                            this.KeyEncryptionKeyUrl,
                            this.KeyEncryptionVaultId)
                    };

                    if (this.ASRVMNicConfiguration != null &&
                        this.ASRVMNicConfiguration.Count() > 0)
                    {
                        var recoveryNetworkIds = new HashSet <string>();
                        var tfoNetworkIds      = new HashSet <string>();

                        this.ASRVMNicConfiguration.ForEach(
                            nic =>
                        {
                            if (!string.IsNullOrEmpty(nic.RecoveryVMNetworkId))
                            {
                                recoveryNetworkIds.Add(nic.RecoveryVMNetworkId);
                            }
                        });
                        this.ASRVMNicConfiguration.ForEach(
                            nic =>
                        {
                            if (!string.IsNullOrEmpty(nic.TfoVMNetworkId))
                            {
                                tfoNetworkIds.Add(nic.TfoVMNetworkId);
                            }
                        });

                        if (recoveryNetworkIds.Count() > 1)
                        {
                            this.WriteWarning(Resources.RecoveryNetworkIdConflictInASRVMNics);
                            return;
                        }

                        if (tfoNetworkIds.Count() > 1)
                        {
                            this.WriteWarning(Resources.TfoNetworkIdConflictInASRVMNics);
                            return;
                        }

                        if (!string.IsNullOrEmpty(this.RecoveryNetworkId) &&
                            !string.IsNullOrEmpty(recoveryNetworkIds.FirstOrDefault()) &&
                            !this.RecoveryNetworkId.Equals(
                                recoveryNetworkIds.First(), StringComparison.OrdinalIgnoreCase))
                        {
                            this.WriteWarning(Resources.RecoveryNetworkInformationMismatch);
                            return;
                        }

                        if (!string.IsNullOrEmpty(recoveryNetworkIds.FirstOrDefault()))
                        {
                            vmRecoveryNetworkId = recoveryNetworkIds.First();
                        }

                        tfoNetworkId = tfoNetworkIds.FirstOrDefault();
                    }

                    if (string.IsNullOrEmpty(tfoNetworkId))
                    {
                        tfoNetworkId = providerSpecificDetails.SelectedTfoAzureNetworkId;
                    }

                    vMNicInputDetailsList = getNicListToUpdate(providerSpecificDetails.VmNics);
                }

                var updateReplicationProtectedItemInputProperties =
                    new UpdateReplicationProtectedItemInputProperties
                {
                    RecoveryAzureVMName            = vmName,
                    RecoveryAzureVMSize            = vmSize,
                    SelectedRecoveryAzureNetworkId = vmRecoveryNetworkId,
                    SelectedTfoAzureNetworkId      = tfoNetworkId,
                    SelectedSourceNicId            = primaryNic,
                    VmNics      = vMNicInputDetailsList,
                    LicenseType =
                        licenseType ==
                        Management.RecoveryServices.SiteRecovery.Models.LicenseType
                        .NoLicenseType.ToString()
                                ? Management.RecoveryServices.SiteRecovery.Models.LicenseType
                        .NoLicenseType
                                : Management.RecoveryServices.SiteRecovery.Models.LicenseType
                        .WindowsServer,
                    RecoveryAvailabilitySetId = availabilitySetId,
                    ProviderSpecificDetails   = providerSpecificInput
                };

                if (provider is HyperVReplicaAzureReplicationDetails || provider is InMageAzureV2ReplicationDetails)
                {
                    updateReplicationProtectedItemInputProperties.SelectedSourceNicId = primaryNic;
                }
                var input = new UpdateReplicationProtectedItemInput
                {
                    Properties = updateReplicationProtectedItemInputProperties
                };

                var response = this.RecoveryServicesClient.UpdateVmProperties(
                    Utilities.GetValueFromArmId(
                        this.InputObject.ID,
                        ARMResourceTypeConstants.ReplicationFabrics),
                    Utilities.GetValueFromArmId(
                        this.InputObject.ID,
                        ARMResourceTypeConstants.ReplicationProtectionContainers),
                    this.InputObject.Name,
                    input);

                var jobResponse = this.RecoveryServicesClient.GetAzureSiteRecoveryJobDetails(
                    PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location));

                this.WriteObject(new ASRJob(jobResponse));
            }
        }