/// <summary> /// Creates an E2E Policy object /// </summary> private void EnterpriseToEnterprisePolicyObject() { if (string.Compare(this.ReplicationProvider, Constants.HyperVReplica2012, StringComparison.OrdinalIgnoreCase) != 0 && string.Compare(this.ReplicationProvider, Constants.HyperVReplica2012R2, StringComparison.OrdinalIgnoreCase) != 0) { throw new InvalidOperationException( string.Format( Properties.Resources.IncorrectReplicationProvider, this.ReplicationProvider)); } PSRecoveryServicesClient.ValidateReplicationStartTime(this.ReplicationStartTime); ushort replicationFrequencyInSeconds = PSRecoveryServicesClient.ConvertReplicationFrequencyToUshort(this.ReplicationFrequencyInSeconds); var createPolicyInputProperties = new CreatePolicyInputProperties(); if (string.Compare(this.ReplicationProvider, Constants.HyperVReplica2012, StringComparison.OrdinalIgnoreCase) == 0) { createPolicyInputProperties.ProviderSpecificInput = new HyperVReplica2012PolicyInput() { AllowedAuthenticationType = (ushort)((string.Compare(this.Authentication, Constants.AuthenticationTypeKerberos, StringComparison.OrdinalIgnoreCase) == 0) ? 1 : 2), ApplicationConsistentSnapshotFrequencyInHours = this.ApplicationConsistentSnapshotFrequencyInHours, Compression = this.CompressionEnabled == true ? "Enable" : "Disable", InitialReplicationMethod = (string.Compare(this.ReplicationMethod, Constants.OnlineReplicationMethod, StringComparison.OrdinalIgnoreCase) == 0) ? "OverNetwork" : "Offline", OnlineReplicationStartTime = this.ReplicationStartTime, RecoveryPoints = this.RecoveryPoints, ReplicaDeletion = this.AllowReplicaDeletion == true ? "Required" : "NotRequired", ReplicationPort = this.ReplicationPort }; } else { createPolicyInputProperties.ProviderSpecificInput = new HyperVReplica2012R2PolicyInput() { AllowedAuthenticationType = (ushort)((string.Compare(this.Authentication, Constants.AuthenticationTypeKerberos, StringComparison.OrdinalIgnoreCase) == 0) ? 1 : 2), ApplicationConsistentSnapshotFrequencyInHours = this.ApplicationConsistentSnapshotFrequencyInHours, Compression = this.CompressionEnabled == true ? "Enable" : "Disable", InitialReplicationMethod = (string.Compare(this.ReplicationMethod, Constants.OnlineReplicationMethod, StringComparison.OrdinalIgnoreCase) == 0) ? "OverNetwork" : "Offline", OnlineReplicationStartTime = this.ReplicationStartTime, RecoveryPoints = this.RecoveryPoints, ReplicaDeletion = this.AllowReplicaDeletion == true ? "Required" : "NotRequired", ReplicationFrequencyInSeconds = replicationFrequencyInSeconds, ReplicationPort = this.ReplicationPort }; } var createPolicyInput = new CreatePolicyInput() { Properties = createPolicyInputProperties }; LongRunningOperationResponse responseBlue = RecoveryServicesClient.CreatePolicy(this.Name, createPolicyInput); JobResponse jobResponseBlue = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(responseBlue.Location)); WriteObject(new ASRJob(jobResponseBlue.Job)); }
private void GetSiteRecoveryCredentialsWithCertificate(string certificate) { var subscriptionId = DefaultContext.Subscription.Id; var site = new ASRSite(); if (!string.IsNullOrEmpty(SiteIdentifier) && !string.IsNullOrEmpty(SiteFriendlyName)) { site.ID = SiteIdentifier; site.Name = SiteFriendlyName; } try { var fileName = GenerateFileName(); var filePath = string.IsNullOrEmpty(Path) ? Utilities.GetDefaultPath() : Path; var fullFilePath = System.IO.Path.Combine(filePath, fileName); // Upload cert into ID Mgmt WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadingCertToIdmgmt)); X509Certificate2 x509 = new X509Certificate2(); byte[] data = Convert.FromBase64String(certificate); x509.Import(data); var bytes = x509.RawData; var certificateArgs = new CertificateRequest { Properties = new RawCertificateData { Certificate = bytes, AuthType = AuthType.AAD } }; var dateString = DateTime.Now.ToString("M-d-yyyy"); var friendlyName = string.Format("{0}{1}-{2}-vaultcredentials", Vault.Name, subscriptionId, dateString); var vaultCertificateResponse = RecoveryServicesClient.GetRecoveryServicesClient.VaultCertificates.CreateWithHttpMessagesAsync( Vault.ResourceGroupName, Vault.Name, friendlyName, certificateArgs.Properties, RecoveryServicesClient.GetRequestHeaders()).Result.Body; WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadedCertToIdmgmt)); var vaultCredsFileContent = GenerateVaultCredsForSiteRecovery( certificate, subscriptionId, vaultCertificateResponse, site); WriteDebug(string.Format(Resources.SavingVaultCred, fullFilePath)); AzureSession.Instance.DataStore.WriteFile(fullFilePath, Encoding.UTF8.GetBytes(vaultCredsFileContent)); var output = new VaultSettingsFilePath { FilePath = fullFilePath, }; // Output filename back to user WriteObject(output, true); } catch (Exception exception) { throw exception; } }
/// <summary> /// Upload certificate /// </summary> /// <param name="cert">management certificate</param> /// <returns>acs namespace of the uploaded cert</returns> private VaultCertificateResponse UploadCert(X509Certificate2 cert) { return(RecoveryServicesClient.UploadCertificate(cert, Vault)); }
/// <summary> /// Switches protection from one container to another or one replication provider to another. /// </summary> private void A2ARPIReprotect() { var switchProtectionInputProperties = new SwitchProtectionInputProperties() { ReplicationProtectedItemName = this.ReplicationProtectedItem.Name, ProviderSpecificDetails = new SwitchProtectionProviderSpecificInput() }; var fabricFriendlyName = this.ReplicationProtectedItem.PrimaryFabricFriendlyName; SwitchProtectionInput input = new SwitchProtectionInput() { Properties = switchProtectionInputProperties }; if (0 == string.Compare( this.ReplicationProtectedItem.ReplicationProvider, Constants.A2A, StringComparison.OrdinalIgnoreCase)) { var a2aSwitchInput = new A2ASwitchProtectionInput() { PolicyId = this.ProtectionContainerMapping.PolicyId, RecoveryContainerId = this.ProtectionContainerMapping.TargetProtectionContainerId, VmDisks = new List <A2AVmDiskInputDetails>(), RecoveryResourceGroupId = this.RecoveryResourceGroupId, RecoveryCloudServiceId = this.RecoveryCloudServiceId, RecoveryAvailabilitySetId = this.RecoveryAvailabilitySetId }; // Fetch the latest Protected item objects var replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem( this.fabricName, this.protectionContainerName, this.ReplicationProtectedItem.Name); if (fabricFriendlyName != this.ProtectionContainerMapping.TargetFabricFriendlyName) { throw new ArgumentException( string.Format(Resources.InvalidSwitchParamRPIAndProtectionContainerMapping, fabricFriendlyName, this.ProtectionContainerMapping.TargetFabricFriendlyName)); } // At a time only Disk or managedDisk details will be present. // Will check with retieved protectedItem weather correct disk mapping is passed and then create the relevant object // and pass as input to service. if (this.AzureToAzureDiskReplicationConfiguration == null || this.AzureToAzureDiskReplicationConfiguration.Length == 0) { if (fabricFriendlyName != this.ProtectionContainerMapping.TargetFabricFriendlyName && RecoveryAzureStorageAccountId == null) { throw new ArgumentException(Resources.InvalidRecoveryAzureStorageAccountId); } foreach (var disk in ((A2AReplicationDetails)replicationProtectedItemResponse .Properties.ProviderSpecificDetails) .ProtectedDisks) { a2aSwitchInput.VmDisks.Add(new A2AVmDiskInputDetails { DiskUri = disk.RecoveryDiskUri, RecoveryAzureStorageAccountId = fabricFriendlyName == this.ProtectionContainerMapping.TargetFabricFriendlyName && this.RecoveryAzureStorageAccountId == null ? disk.PrimaryDiskAzureStorageAccountId : this.RecoveryAzureStorageAccountId, PrimaryStagingAzureStorageAccountId = this.LogStorageAccountId, }); } } else { foreach (ASRAzuretoAzureDiskReplicationConfig disk in this.AzureToAzureDiskReplicationConfiguration) { if (string.IsNullOrEmpty(disk.LogStorageAccountId)) { throw new PSArgumentException( string.Format( Properties.Resources.InvalidPrimaryStagingAzureStorageAccountIdDiskInput, disk.VhdUri)); } if (string.IsNullOrEmpty(disk.RecoveryAzureStorageAccountId)) { throw new PSArgumentException( string.Format( Properties.Resources.InvalidRecoveryAzureStorageAccountIdDiskInput, disk.VhdUri)); } a2aSwitchInput.VmDisks.Add(new A2AVmDiskInputDetails { DiskUri = disk.VhdUri, RecoveryAzureStorageAccountId = disk.RecoveryAzureStorageAccountId, PrimaryStagingAzureStorageAccountId = disk.LogStorageAccountId }); } } input.Properties.ProviderSpecificDetails = a2aSwitchInput; } var response = RecoveryServicesClient.StartSwitchProtection( this.fabricName, this.protectionContainerName, input); var jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails( PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse)); }
/// <summary> /// Queries by Name. /// </summary> private void GetByName() { this.WriteJob(RecoveryServicesClient.GetAzureSiteRecoveryJobDetails(this.Name).Job); }
/// <summary> /// Helper to configure cloud /// </summary> private void Dissociate(string targetProtectionContainerId) { RemoveProtectionContainerMappingInputProperties inputProperties = new RemoveProtectionContainerMappingInputProperties() { ProviderSpecificInput = new ReplicationProviderContainerUnmappingInput() }; RemoveProtectionContainerMappingInput input = new RemoveProtectionContainerMappingInput() { Properties = inputProperties }; ProtectionContainerMappingListResponse protectionContainerMappingListResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectionContainerMapping(Utilities.GetValueFromArmId(PrimaryProtectionContainer.ID, ARMResourceTypeConstants.ReplicationFabrics), PrimaryProtectionContainer.Name); ProtectionContainerMapping protectionContainerMapping = protectionContainerMappingListResponse.ProtectionContainerMappings.SingleOrDefault(t => (t.Properties.PolicyId.CompareTo(this.Policy.ID) == 0 && t.Properties.TargetProtectionContainerId.CompareTo(targetProtectionContainerId) == 0)); if (protectionContainerMapping == null) { throw new Exception("Cloud is not paired"); } LongRunningOperationResponse response = RecoveryServicesClient.UnConfigureProtection(Utilities.GetValueFromArmId(this.PrimaryProtectionContainer.ID, ARMResourceTypeConstants.ReplicationFabrics), this.PrimaryProtectionContainer.Name, protectionContainerMapping.Name, input); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); this.WriteObject(new ASRJob(jobResponse.Job)); }
/// <summary> /// ProcessRecord of the command. /// </summary> public override void ExecuteCmdlet() { this.WriteWarningWithTimestamp( string.Format( Properties.Resources.CmdletWillBeDeprecatedSoon, this.MyInvocation.MyCommand.Name)); 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); } }); }
/// <summary> /// ProcessRecord of the command. /// </summary> public override void ExecuteSiteRecoveryCmdlet() { base.ExecuteSiteRecoveryCmdlet(); ASRRecoveryPlanGroup tempGroup; switch (this.ParameterSetName) { case ASRParameterSets.AppendGroup: RecoveryPlanGroup recoveryPlanGroup = new RecoveryPlanGroup() { GroupType = Constants.Boot, ReplicationProtectedItems = new List <RecoveryPlanProtectedItem>(), StartGroupActions = new List <RecoveryPlanAction>(), EndGroupActions = new List <RecoveryPlanAction>() }; this.RecoveryPlan.Groups.Add(new ASRRecoveryPlanGroup("Group " + (RecoveryPlan.Groups.Count - 1).ToString(), recoveryPlanGroup)); break; case ASRParameterSets.RemoveGroup: tempGroup = this.RecoveryPlan.Groups.FirstOrDefault(g => String.Compare(g.Name, RemoveGroup.Name, StringComparison.OrdinalIgnoreCase) == 0); if (tempGroup != null) { this.RecoveryPlan.Groups.Remove(tempGroup); this.RecoveryPlan = this.RecoveryPlan.RefreshASRRecoveryPlanGroupNames(); } else { throw new PSArgumentException(string.Format(Properties.Resources.GroupNotFoundInRecoveryPlan, this.RemoveGroup.Name, this.RecoveryPlan.FriendlyName)); } break; case ASRParameterSets.AddReplicationProtectedItems: foreach (ASRReplicationProtectedItem rpi in AddProtectedItems) { string fabricName = Utilities.GetValueFromArmId(rpi.ID, ARMResourceTypeConstants.ReplicationFabrics); ReplicationProtectedItemResponse replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem(fabricName, Utilities.GetValueFromArmId(rpi.ID, ARMResourceTypeConstants.ReplicationProtectionContainers), rpi.Name); tempGroup = this.RecoveryPlan.Groups.FirstOrDefault(g => String.Compare(g.Name, Group.Name, StringComparison.OrdinalIgnoreCase) == 0); if (tempGroup != null) { foreach (ASRRecoveryPlanGroup gp in this.RecoveryPlan.Groups) { if (gp.ReplicationProtectedItems == null) { continue; } if (gp.ReplicationProtectedItems.Any(pi => String.Compare(pi.Id, replicationProtectedItemResponse.ReplicationProtectedItem.Id, StringComparison.OrdinalIgnoreCase) == 0)) { throw new PSArgumentException(string.Format(Properties.Resources.VMAlreadyPartOfGroup, rpi.FriendlyName, gp.Name, this.RecoveryPlan.FriendlyName)); } } this.RecoveryPlan.Groups[RecoveryPlan.Groups.IndexOf(tempGroup)].ReplicationProtectedItems.Add(replicationProtectedItemResponse.ReplicationProtectedItem); } else { throw new PSArgumentException(string.Format(Properties.Resources.GroupNotFoundInRecoveryPlan, this.Group.Name, this.RecoveryPlan.FriendlyName)); } } break; case ASRParameterSets.RemoveReplicationProtectedItems: foreach (ASRReplicationProtectedItem rpi in RemoveProtectedItems) { string fabricName = Utilities.GetValueFromArmId(rpi.ID, ARMResourceTypeConstants.ReplicationFabrics); tempGroup = this.RecoveryPlan.Groups.FirstOrDefault(g => String.Compare(g.Name, Group.Name, StringComparison.OrdinalIgnoreCase) == 0); if (tempGroup != null) { var ReplicationProtectedItem = this.RecoveryPlan.Groups[RecoveryPlan.Groups.IndexOf(tempGroup)]. ReplicationProtectedItems. FirstOrDefault(pi => String.Compare(pi.Id, rpi.ID, StringComparison.OrdinalIgnoreCase) == 0); if (ReplicationProtectedItem != null) { this.RecoveryPlan.Groups[RecoveryPlan.Groups.IndexOf(tempGroup)].ReplicationProtectedItems.Remove(ReplicationProtectedItem); } else { throw new PSArgumentException(string.Format(Properties.Resources.VMNotFoundInGroup, rpi.FriendlyName, this.Group.Name, this.RecoveryPlan.FriendlyName)); } } else { throw new PSArgumentException(string.Format(Properties.Resources.GroupNotFoundInRecoveryPlan, this.Group.Name, this.RecoveryPlan.FriendlyName)); } } break; case ASRParameterSets.AddProtectedEntities: this.WriteWarningWithTimestamp(Properties.Resources.ParameterSetWillBeDeprecatedSoon); foreach (ASRProtectionEntity pe in AddProtectedEntities) { string fabricName = Utilities.GetValueFromArmId(pe.ID, ARMResourceTypeConstants.ReplicationFabrics); // fetch the latest PE object ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem(fabricName, pe.ProtectionContainerId, pe.Name); ReplicationProtectedItemResponse replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem(fabricName, pe.ProtectionContainerId, Utilities.GetValueFromArmId(protectableItemResponse.ProtectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems)); tempGroup = this.RecoveryPlan.Groups.FirstOrDefault(g => String.Compare(g.Name, Group.Name, StringComparison.OrdinalIgnoreCase) == 0); if (tempGroup != null) { foreach (ASRRecoveryPlanGroup gp in this.RecoveryPlan.Groups) { if (gp.ReplicationProtectedItems == null) { continue; } if (gp.ReplicationProtectedItems.Any(pi => String.Compare(pi.Id, replicationProtectedItemResponse.ReplicationProtectedItem.Id, StringComparison.OrdinalIgnoreCase) == 0)) { throw new PSArgumentException(string.Format(Properties.Resources.VMAlreadyPartOfGroup, pe.FriendlyName, gp.Name, this.RecoveryPlan.FriendlyName)); } } this.RecoveryPlan.Groups[RecoveryPlan.Groups.IndexOf(tempGroup)].ReplicationProtectedItems.Add(replicationProtectedItemResponse.ReplicationProtectedItem); } else { throw new PSArgumentException(string.Format(Properties.Resources.GroupNotFoundInRecoveryPlan, this.Group.Name, this.RecoveryPlan.FriendlyName)); } } break; case ASRParameterSets.RemoveProtectedEntities: this.WriteWarningWithTimestamp(Properties.Resources.ParameterSetWillBeDeprecatedSoon); foreach (ASRProtectionEntity pe in RemoveProtectedEntities) { string fabricName = Utilities.GetValueFromArmId(pe.ID, ARMResourceTypeConstants.ReplicationFabrics); // fetch the latest PE object ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem(fabricName, pe.ProtectionContainerId, pe.Name); tempGroup = this.RecoveryPlan.Groups.FirstOrDefault(g => String.Compare(g.Name, Group.Name, StringComparison.OrdinalIgnoreCase) == 0); if (tempGroup != null) { var ReplicationProtectedItem = this.RecoveryPlan.Groups[RecoveryPlan.Groups.IndexOf(tempGroup)]. ReplicationProtectedItems. FirstOrDefault(pi => String.Compare(pi.Id, protectableItemResponse.ProtectableItem.Properties.ReplicationProtectedItemId, StringComparison.OrdinalIgnoreCase) == 0); if (ReplicationProtectedItem != null) { this.RecoveryPlan.Groups[RecoveryPlan.Groups.IndexOf(tempGroup)].ReplicationProtectedItems.Remove(ReplicationProtectedItem); } else { throw new PSArgumentException(string.Format(Properties.Resources.VMNotFoundInGroup, pe.FriendlyName, this.Group.Name, this.RecoveryPlan.FriendlyName)); } } else { throw new PSArgumentException(string.Format(Properties.Resources.GroupNotFoundInRecoveryPlan, this.Group.Name, this.RecoveryPlan.FriendlyName)); } } break; } ; this.WriteObject(this.RecoveryPlan); }
/// <summary> /// Starts PE Planned failover. /// </summary> private void StartPEPlannedFailover() { var plannedFailoverInputProperties = new PlannedFailoverInputProperties() { FailoverDirection = this.Direction, ProviderSpecificDetails = new ProviderSpecificFailoverInput() }; var input = new PlannedFailoverInput() { Properties = plannedFailoverInputProperties }; // fetch the latest PE object ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem(this.fabricName, this.ProtectionEntity.ProtectionContainerId, this.ProtectionEntity.Name); ReplicationProtectedItemResponse replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem(this.fabricName, this.ProtectionEntity.ProtectionContainerId, Utilities.GetValueFromArmId(protectableItemResponse.ProtectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems)); PolicyResponse policyResponse = RecoveryServicesClient.GetAzureSiteRecoveryPolicy(Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Properties.PolicyID, ARMResourceTypeConstants.ReplicationPolicies)); this.ProtectionEntity = new ASRProtectionEntity(protectableItemResponse.ProtectableItem, replicationProtectedItemResponse.ReplicationProtectedItem); if (0 == string.Compare( this.ProtectionEntity.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase)) { if (this.Direction == Constants.PrimaryToRecovery) { var failoverInput = new HyperVReplicaAzureFailoverProviderInput() { PrimaryKekCertificatePfx = primaryKekCertpfx, SecondaryKekCertificatePfx = secondaryKekCertpfx, VaultLocation = this.GetCurrentVaultLocation() }; input.Properties.ProviderSpecificDetails = failoverInput; } else { var failbackInput = new HyperVReplicaAzureFailbackProviderInput() { DataSyncOption = this.Optimize == Constants.ForDowntime ? Constants.ForDowntime : Constants.ForSynchronization, //ProviderIdForAlternateRecovery = "", RecoveryVmCreationOption = "CreateVmIfNotFound" //CreateVmIfNotFound | NoAction }; input.Properties.ProviderSpecificDetails = failbackInput; } } LongRunningOperationResponse response = RecoveryServicesClient.StartAzureSiteRecoveryPlannedFailover( this.fabricName, this.protectionContainerName, Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Id, ARMResourceTypeConstants.ReplicationProtectedItems), input); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); }
/// <summary> /// ProcessRecord of the command. /// </summary> public override void ExecuteSiteRecoveryCmdlet() { base.ExecuteSiteRecoveryCmdlet(); this.WriteWarningWithTimestamp( string.Format(Properties.Resources.CmdletWillBeDeprecatedSoon, this.MyInvocation.MyCommand.Name, "New-AzureRmSiteRecoveryReplicationProtectedItem or Remove-AzureRmSiteRecoveryReplicationProtectedItem")); if (0 != string.CompareOrdinal(this.Protection, Constants.DisableProtection) || ShouldProcess(this.ProtectionEntity.FriendlyName, "Disable Protection")) { if (this.Protection == Constants.EnableProtection) { if (string.Compare(this.ParameterSetName, ASRParameterSets.DisableDR, StringComparison.OrdinalIgnoreCase) == 0) { throw new PSArgumentException(Properties.Resources.PassingPolicyMandatoryForEnablingDR); } EnableProtectionProviderSpecificInput enableProtectionProviderSpecificInput = new EnableProtectionProviderSpecificInput(); EnableProtectionInputProperties inputProperties = new EnableProtectionInputProperties() { PolicyId = this.Policy.ID, ProtectableItemId = this.ProtectionEntity.ID, ProviderSpecificDetails = enableProtectionProviderSpecificInput }; EnableProtectionInput input = new EnableProtectionInput() { Properties = inputProperties }; // Process if block only if policy is not null, policy is created for E2A or B2A and parameter set is for enable DR of E2A or B2A if (this.Policy != null && 0 == string.Compare(this.Policy.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase) && (0 == string.Compare(this.ParameterSetName, ASRParameterSets.EnterpriseToAzure, StringComparison.OrdinalIgnoreCase) || 0 == string.Compare(this.ParameterSetName, ASRParameterSets.HyperVSiteToAzure, StringComparison.OrdinalIgnoreCase))) { HyperVReplicaAzureEnableProtectionInput providerSettings = new HyperVReplicaAzureEnableProtectionInput(); providerSettings.HvHostVmId = this.ProtectionEntity.FabricObjectId; providerSettings.VmName = this.ProtectionEntity.FriendlyName; // Id disk details are missing in input PE object, get the latest PE. if (string.IsNullOrEmpty(this.ProtectionEntity.OS)) { // Just checked for OS to see whether the disk details got filled up or not ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem( Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationFabrics), this.ProtectionEntity.ProtectionContainerId, this.ProtectionEntity.Name); this.ProtectionEntity = new ASRProtectionEntity(protectableItemResponse.ProtectableItem); } if (string.IsNullOrWhiteSpace(this.OS)) { providerSettings.OSType = ((string.Compare(this.ProtectionEntity.OS, Constants.OSWindows) == 0) || (string.Compare(this.ProtectionEntity.OS, Constants.OSLinux) == 0)) ? this.ProtectionEntity.OS : Constants.OSWindows; } else { providerSettings.OSType = this.OS; } if (string.IsNullOrWhiteSpace(this.OSDiskName)) { providerSettings.VhdId = this.ProtectionEntity.OSDiskId; } else { foreach (var disk in this.ProtectionEntity.Disks) { if (0 == string.Compare(disk.Name, this.OSDiskName, true)) { providerSettings.VhdId = disk.Id; break; } } } if (RecoveryAzureStorageAccountId != null) { providerSettings.TargetStorageAccountId = RecoveryAzureStorageAccountId; } input.Properties.ProviderSpecificDetails = providerSettings; } else if (this.Policy != null && 0 == string.Compare(this.Policy.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase) && 0 == string.Compare(this.ParameterSetName, ASRParameterSets.EnterpriseToEnterprise, StringComparison.OrdinalIgnoreCase)) { throw new PSArgumentException(Properties.Resources.PassingStorageMandatoryForEnablingDRInAzureScenarios); } this.response = RecoveryServicesClient.EnableProtection( Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationFabrics), Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationProtectionContainers), this.ProtectionEntity.Name, input); } else { // fetch the latest PE object ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem(Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationFabrics), this.ProtectionEntity.ProtectionContainerId, this.ProtectionEntity.Name); ProtectableItem protectableItem = protectableItemResponse.ProtectableItem; if (!this.Force.IsPresent) { DisableProtectionInput input = new DisableProtectionInput(); input.Properties = new DisableProtectionInputProperties() { ProviderSettings = new DisableProtectionProviderSpecificInput() }; this.response = RecoveryServicesClient.DisableProtection( Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationFabrics), Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationProtectionContainers), Utilities.GetValueFromArmId(protectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems), input); } else { this.response = RecoveryServicesClient.PurgeProtection( Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationFabrics), Utilities.GetValueFromArmId(this.ProtectionEntity.ID, ARMResourceTypeConstants.ReplicationProtectionContainers), Utilities.GetValueFromArmId(protectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems) ); } } jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); if (this.WaitForCompletion.IsPresent) { this.WaitForJobCompletion(this.jobResponse.Job.Name); jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); } } }
/// <summary> /// Switches protection from one container to another or one replication provider to another. /// </summary> private void A2ARPIReprotect() { var switchProtectionInputProperties = new SwitchProtectionInputProperties() { ReplicationProtectedItemName = this.ReplicationProtectedItem.Name, ProviderSpecificDetails = new SwitchProtectionProviderSpecificInput() }; var fabricFriendlyName = this.ReplicationProtectedItem.PrimaryFabricFriendlyName; SwitchProtectionInput input = new SwitchProtectionInput() { Properties = switchProtectionInputProperties }; if (0 == string.Compare( this.ReplicationProtectedItem.ReplicationProvider, Constants.A2A, StringComparison.OrdinalIgnoreCase)) { var a2aSwitchInput = new A2ASwitchProtectionInput() { PolicyId = this.ProtectionContainerMapping.PolicyId, RecoveryContainerId = this.ProtectionContainerMapping.TargetProtectionContainerId, VmDisks = new List <A2AVmDiskInputDetails>(), VmManagedDisks = new List <A2AVmManagedDiskInputDetails>(), RecoveryResourceGroupId = this.RecoveryResourceGroupId, RecoveryCloudServiceId = this.RecoveryCloudServiceId, RecoveryAvailabilitySetId = this.RecoveryAvailabilitySetId, RecoveryBootDiagStorageAccountId = this.RecoveryBootDiagStorageAccountId }; // Fetch the latest Protected item objects var replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem( this.fabricName, this.protectionContainerName, this.ReplicationProtectedItem.Name); if (fabricFriendlyName != this.ProtectionContainerMapping.TargetFabricFriendlyName) { throw new ArgumentException( string.Format(Resources.InvalidSwitchParamRPIAndProtectionContainerMapping, fabricFriendlyName, this.ProtectionContainerMapping.TargetFabricFriendlyName)); } // unmanagedDisk case if (((A2AReplicationDetails)replicationProtectedItemResponse.Properties.ProviderSpecificDetails).ProtectedDisks != null && ((A2AReplicationDetails)replicationProtectedItemResponse.Properties.ProviderSpecificDetails).ProtectedDisks.Count > 0) { populateUnManagedDiskInputDetails(fabricFriendlyName, a2aSwitchInput, replicationProtectedItemResponse); } else if (((A2AReplicationDetails)replicationProtectedItemResponse.Properties.ProviderSpecificDetails).ProtectedManagedDisks != null && ((A2AReplicationDetails)replicationProtectedItemResponse.Properties.ProviderSpecificDetails).ProtectedManagedDisks.Count > 0) { populateManagedDiskInputDetails(a2aSwitchInput, replicationProtectedItemResponse); } // Add disk encryption related values. a2aSwitchInput.DiskEncryptionInfo = this.A2AEncryptionDetails(); input.Properties.ProviderSpecificDetails = a2aSwitchInput; } var response = RecoveryServicesClient.StartSwitchProtection( this.fabricName, this.protectionContainerName, input); var jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails( PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse)); }
/// <summary> /// Starts PE Planned failover. /// </summary> private void StartPEPlannedFailover() { var request = new PlannedFailoverRequest(); request.FailoverDirection = this.Direction; if (string.IsNullOrEmpty(this.ProtectionEntity.ReplicationProvider)) { // fetch the latest PE object // As get PE by name is failing before protection, get all & filter. // Once after we fix get pe by name, change the logic to use the same. ProtectionEntityListResponse protectionEntityListResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectionEntity( this.ProtectionEntity.ProtectionContainerId); foreach (ProtectionEntity pe in protectionEntityListResponse.ProtectionEntities) { if (0 == string.Compare(this.ProtectionEntity.FriendlyName, pe.Properties.FriendlyName, true)) { this.ProtectionEntity = new ASRProtectionEntity(pe); break; } } } request.ReplicationProvider = this.ProtectionEntity.ReplicationProvider; request.ReplicationProviderSettings = new FailoverReplicationProviderSpecificInput(); if (0 == string.Compare( this.ProtectionEntity.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase)) { if (this.Direction == Constants.PrimaryToRecovery) { AzureFailoverInput failoverInput = new AzureFailoverInput() { PrimaryKekCertificatePfx = string.Empty, SecondaryKekCertificatePfx = string.Empty, VaultLocation = this.GetCurrentValutLocation() }; request.ReplicationProviderSettings = failoverInput; } else { AzureFailbackInput failbackInput = new AzureFailbackInput() { CreateRecoveryVmIfDoesntExist = false, SkipDataSync = this.Optimize == Constants.ForDowntime ? true : false }; request.ReplicationProviderSettings = failbackInput; } } LongRunningOperationResponse response = RecoveryServicesClient.StartAzureSiteRecoveryPlannedFailover( this.protectionContainerId, this.protectionEntityId, request); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); }
/// <summary> /// Set PE protection. /// </summary> private void SetPEReprotect() { var request = new ReprotectRequest(); request.FailoverDirection = this.Direction; if (string.IsNullOrEmpty(this.ProtectionEntity.ReplicationProvider)) { // fetch the latest PE object // As get PE by name is failing before protection, get all & filter. // Once after we fix get pe by name, change the logic to use the same. ProtectionEntityListResponse protectionEntityListResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectionEntity( this.ProtectionEntity.ProtectionContainerId); foreach (ProtectionEntity pe in protectionEntityListResponse.ProtectionEntities) { if (0 == string.Compare(this.ProtectionEntity.FriendlyName, pe.Properties.FriendlyName, true)) { this.ProtectionEntity = new ASRProtectionEntity(pe); break; } } } request.ReplicationProvider = this.ProtectionEntity.ReplicationProvider; request.ReplicationProviderSettings = new FailoverReplicationProviderSpecificInput(); 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"); } if (0 == string.Compare( this.ProtectionEntity.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase)) { if (this.Direction == Constants.PrimaryToRecovery) { AzureReprotectInput reprotectInput = new AzureReprotectInput() { HvHostVmId = this.ProtectionEntity.FabricObjectId, VmName = this.ProtectionEntity.Name, OSType = this.ProtectionEntity.OS, VHDId = this.ProtectionEntity.OSDiskId }; request.ReplicationProviderSettings = reprotectInput; } } LongRunningOperationResponse response = RecoveryServicesClient.StartAzureSiteRecoveryReprotection( this.protectionContainerId, this.protectionEntityId, request); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); }
/// <summary> /// Starts RPI Planned failover. /// </summary> private void StartRPIPlannedFailover() { var plannedFailoverInputProperties = new PlannedFailoverInputProperties() { FailoverDirection = this.Direction, ProviderSpecificDetails = new ProviderSpecificFailoverInput() }; var input = new PlannedFailoverInput() { Properties = plannedFailoverInputProperties }; if (0 == string.Compare( this.ReplicationProtectedItem.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase)) { if (this.Direction == Constants.PrimaryToRecovery) { var failoverInput = new HyperVReplicaAzureFailoverProviderInput() { PrimaryKekCertificatePfx = primaryKekCertpfx, SecondaryKekCertificatePfx = secondaryKekCertpfx, VaultLocation = this.GetCurrentVaultLocation() }; input.Properties.ProviderSpecificDetails = failoverInput; } else { var failbackInput = new HyperVReplicaAzureFailbackProviderInput() { DataSyncOption = this.Optimize == Constants.ForDownTime ? Constants.ForDownTime : Constants.ForSynchronization, RecoveryVmCreationOption = String.Compare(this.CreateVmIfNotFound, Constants.Yes, StringComparison.OrdinalIgnoreCase) == 0 ? Constants.CreateVmIfNotFound : Constants.NoAction }; if (String.Compare(this.CreateVmIfNotFound, Constants.Yes, StringComparison.OrdinalIgnoreCase) == 0 && string.Compare(RecoveryServicesClient.GetAzureSiteRecoveryFabric(this.fabricName).Fabric.Properties.CustomDetails.InstanceType, Constants.HyperVSite) == 0) { if (this.ServicesProvider == null || string.Compare(this.ServicesProvider.FabricType, Constants.HyperVSite) != 0) { throw new InvalidOperationException( Properties.Resources.ImproperServerObjectPassedForHyperVFailback); } else { failbackInput.ProviderIdForAlternateRecovery = this.ServicesProvider.ID; } } input.Properties.ProviderSpecificDetails = failbackInput; } } LongRunningOperationResponse response = RecoveryServicesClient.StartAzureSiteRecoveryPlannedFailover( this.fabricName, this.protectionContainerName, this.ReplicationProtectedItem.Name, input); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); }
/// <summary> /// Queries all Protected Items under given Protection Container. /// </summary> private void GetAll() { ReplicationProtectedItemListResponse replicationProtectedItemListResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem( Utilities.GetValueFromArmId(this.ProtectionContainer.ID, ARMResourceTypeConstants.ReplicationFabrics), this.ProtectionContainer.Name); WriteReplicationProtectedItems(replicationProtectedItemListResponse.ReplicationProtectedItems); }
/// <summary> /// Starts PE Test failover. /// </summary> private void StartPETestFailover() { var testFailoverInputProperties = new TestFailoverInputProperties() { FailoverDirection = this.Direction, NetworkId = this.networkId, NetworkType = this.networkType, ProviderSpecificDetails = new ProviderSpecificFailoverInput() }; var input = new TestFailoverInput() { Properties = testFailoverInputProperties }; // fetch the latest PE object ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem(this.fabricName, this.ProtectionEntity.ProtectionContainerId, this.ProtectionEntity.Name); ReplicationProtectedItemResponse replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem(this.fabricName, this.ProtectionEntity.ProtectionContainerId, Utilities.GetValueFromArmId(protectableItemResponse.ProtectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems)); PolicyResponse policyResponse = RecoveryServicesClient.GetAzureSiteRecoveryPolicy(Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Properties.PolicyID, ARMResourceTypeConstants.ReplicationPolicies)); this.ProtectionEntity = new ASRProtectionEntity(protectableItemResponse.ProtectableItem, replicationProtectedItemResponse.ReplicationProtectedItem); if (0 == string.Compare( this.ProtectionEntity.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase)) { if (this.Direction == Constants.PrimaryToRecovery) { var failoverInput = new HyperVReplicaAzureFailoverProviderInput() { PrimaryKekCertificatePfx = primaryKekCertpfx, SecondaryKekCertificatePfx = secondaryKekCertpfx, VaultLocation = this.GetCurrentVaultLocation() }; input.Properties.ProviderSpecificDetails = failoverInput; } else { new ArgumentException(Properties.Resources.UnsupportedDirectionForTFO);// Throw Unsupported Direction Exception } } LongRunningOperationResponse response = RecoveryServicesClient.StartAzureSiteRecoveryTestFailover( this.fabricName, this.protectionContainerName, Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Id, ARMResourceTypeConstants.ReplicationProtectedItems), input); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); }
private void GetSiteRecoveryCredentialsWithCertificate(string certificate) { string subscriptionId = DefaultContext.Subscription.Id.ToString(); VaultCertificateResponse vaultCertificateResponse = null; ASRSite site = new ASRSite(); if (!string.IsNullOrEmpty(this.SiteIdentifier) && !string.IsNullOrEmpty(this.SiteFriendlyName)) { site.ID = this.SiteIdentifier; site.Name = this.SiteFriendlyName; } try { string fileName = this.GenerateFileName(); string filePath = string.IsNullOrEmpty(this.Path) ? Utilities.GetDefaultPath() : this.Path; string fullFilePath = System.IO.Path.Combine(filePath, fileName); // Upload cert into ID Mgmt WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadingCertToIdmgmt)); byte[] bytes = Encoding.ASCII.GetBytes(certificate); var certificateArgs = new CertificateRequest(); certificateArgs.Properties = new RawCertificateData(); certificateArgs.Properties.Certificate = bytes; certificateArgs.Properties.AuthType = AuthType.AAD; string dateString = DateTime.Now.ToString("M-d-yyyy"); var friendlyName = string.Format("{0}{1}-{2}-vaultcredentials", this.Vault.Name, subscriptionId, dateString); vaultCertificateResponse = RecoveryServicesClient.GetRecoveryServicesClient.VaultCertificates.CreateWithHttpMessagesAsync( this.Vault.ResourceGroupName, this.Vault.Name, friendlyName, certificateArgs, RecoveryServicesClient.GetRequestHeaders()).Result.Body; WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadedCertToIdmgmt)); string vaultCredsFileContent = GenerateVaultCredsForSiteRecovery( certificate, subscriptionId, vaultCertificateResponse, site); WriteDebug(string.Format(Resources.SavingVaultCred, fullFilePath)); AzureSession.Instance.DataStore.WriteFile(fullFilePath, Encoding.UTF8.GetBytes(vaultCredsFileContent)); VaultSettingsFilePath output = new VaultSettingsFilePath() { FilePath = fullFilePath, }; // Output filename back to user WriteObject(output, true); } catch (Exception exception) { throw exception; } }
/// <summary> /// ProcessRecord of the command. /// </summary> public override void ExecuteCmdlet() { this.WriteVerbose("Vault Settings File path: " + this.Path); ASRVaultCreds asrVaultCreds = null; if (File.Exists(this.Path)) { try { var serializer = new DataContractSerializer(typeof(ASRVaultCreds)); using (var s = new FileStream( this.Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { asrVaultCreds = (ASRVaultCreds)serializer.ReadObject(s); } } catch (XmlException xmlException) { throw new XmlException( string.Format(Properties.Resources.InvalidXml, xmlException)); } catch (SerializationException serializationException) { throw new SerializationException( string.Format(Properties.Resources.InvalidXml, serializationException)); } } else { throw new FileNotFoundException( Properties.Resources.VaultSettingFileNotFound, this.Path); } // Validate required parameters taken from the Vault settings file. if (string.IsNullOrEmpty(asrVaultCreds.ResourceName)) { throw new ArgumentException( Properties.Resources.ResourceNameNullOrEmpty, asrVaultCreds.ResourceName); } if (string.IsNullOrEmpty(asrVaultCreds.CloudServiceName)) { throw new ArgumentException( Properties.Resources.CloudServiceNameNullOrEmpty, asrVaultCreds.CloudServiceName); } try { RecoveryServicesClient.ValidateVaultSettings( asrVaultCreds.ResourceName, asrVaultCreds.CloudServiceName); this.ImportAzureSiteRecoveryVaultSettings(asrVaultCreds); this.WriteObject(new ASRVaultSettings( asrVaultCreds.ResourceName, asrVaultCreds.CloudServiceName)); } catch (Exception exception) { this.HandleException(exception); } }
/// <summary> /// ProcessRecord of the command. /// </summary> public override void ExecuteCmdlet() { try { ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem(Utilities.GetValueFromArmId(this.VirtualMachine.ID, ARMResourceTypeConstants.ReplicationFabrics), this.VirtualMachine.ProtectionContainerId, this.VirtualMachine.Name); if (protectableItemResponse.ProtectableItem.Properties.ReplicationProtectedItemId == null) { this.WriteWarning(Properties.Resources.ProtectionIsNotEnabledForVM.ToString()); return; } ReplicationProtectedItemResponse replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem(Utilities.GetValueFromArmId(this.VirtualMachine.ID, ARMResourceTypeConstants.ReplicationFabrics), this.VirtualMachine.ProtectionContainerId, Utilities.GetValueFromArmId(protectableItemResponse.ProtectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems)); // Check for Replication Provider type HyperVReplicaAzure if (0 != string.Compare( replicationProtectedItemResponse.ReplicationProtectedItem.Properties.ProviderSpecificDetails.InstanceType, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase)) { this.WriteWarning(Properties.Resources.UnsupportedReplicationProvidedForUpdateVmProperties.ToString()); return; } // Check for at least one option if (string.IsNullOrEmpty(this.Name) && string.IsNullOrEmpty(this.Size) && string.IsNullOrEmpty(this.PrimaryNic) && string.IsNullOrEmpty(this.RecoveryNetworkId)) { this.WriteWarning(Properties.Resources.ArgumentsMissingForUpdateVmProperties.ToString()); return; } // Both primary & recovery inputs should be present if (string.IsNullOrEmpty(this.PrimaryNic) ^ string.IsNullOrEmpty(this.RecoveryNetworkId)) { this.WriteWarning(Properties.Resources.NetworkArgumentsMissingForUpdateVmProperties.ToString()); return; } List <VMNicInputDetails> vMNicInputDetailsList = new List <VMNicInputDetails>(); VMNicDetails vMNicDetailsToBeUpdated; if (!string.IsNullOrEmpty(this.PrimaryNic)) { HyperVReplicaAzureReplicationDetails providerSpecificDetails = (HyperVReplicaAzureReplicationDetails)replicationProtectedItemResponse.ReplicationProtectedItem.Properties.ProviderSpecificDetails; if (providerSpecificDetails.VMNics != null) { vMNicDetailsToBeUpdated = providerSpecificDetails.VMNics.SingleOrDefault(n => string.Compare(n.NicId, this.PrimaryNic, StringComparison.OrdinalIgnoreCase) == 0); if (vMNicDetailsToBeUpdated != null) { VMNicInputDetails vMNicInputDetails = new VMNicInputDetails(); vMNicInputDetails.NicId = this.PrimaryNic; vMNicInputDetails.RecoveryVMSubnetName = this.RecoveryNicSubnetName; vMNicInputDetails.ReplicaNicStaticIPAddress = this.RecoveryNicStaticIPAddress; vMNicInputDetails.SelectionType = string.IsNullOrEmpty(this.NicSelectionType) ? Constants.SelectedByUser : this.NicSelectionType; vMNicInputDetailsList.Add(vMNicInputDetails); IEnumerable <VMNicDetails> vMNicDetailsListRemaining = providerSpecificDetails.VMNics.Where(n => string.Compare(n.NicId, this.PrimaryNic, StringComparison.OrdinalIgnoreCase) != 0); foreach (VMNicDetails nDetails in vMNicDetailsListRemaining) { vMNicInputDetails = new VMNicInputDetails(); vMNicInputDetails.NicId = nDetails.NicId; vMNicInputDetails.RecoveryVMSubnetName = nDetails.RecoveryVMSubnetName; vMNicInputDetails.ReplicaNicStaticIPAddress = nDetails.ReplicaNicStaticIPAddress; vMNicInputDetails.SelectionType = nDetails.SelectionType; vMNicInputDetailsList.Add(vMNicInputDetails); } } else { throw new PSInvalidOperationException(Properties.Resources.NicNotFoundInVMForUpdateVmProperties); } } } UpdateReplicationProtectedItemInputProperties updateReplicationProtectedItemInputProperties = new UpdateReplicationProtectedItemInputProperties() { RecoveryAzureVMName = this.Name, RecoveryAzureVMSize = this.Size, SelectedRecoveryAzureNetworkId = this.RecoveryNetworkId, VmNics = vMNicInputDetailsList }; UpdateReplicationProtectedItemInput input = new UpdateReplicationProtectedItemInput() { Properties = updateReplicationProtectedItemInputProperties }; LongRunningOperationResponse response = RecoveryServicesClient.UpdateVmProperties( Utilities.GetValueFromArmId(this.VirtualMachine.ID, ARMResourceTypeConstants.ReplicationFabrics), Utilities.GetValueFromArmId(this.VirtualMachine.ID, ARMResourceTypeConstants.ReplicationProtectionContainers), this.VirtualMachine.Name, input); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); } catch (Exception exception) { this.HandleException(exception); } }
/// <summary> /// Queries by ID. /// </summary> private void GetById() { this.WriteJob(RecoveryServicesClient.RestartAzureSiteRecoveryJob(this.Id).Job); }
/// <summary> /// Write Recovery Plan. /// </summary> /// <param name="recoveryPlan">Recovery Plan object</param> private void WriteRecoveryPlan(RecoveryPlan recoveryPlan) { var replicationProtectedItemListResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItemInRP(recoveryPlan.Name); this.WriteObject(new ASRRecoveryPlan(recoveryPlan, replicationProtectedItemListResponse.ReplicationProtectedItems)); }
/// <summary> /// Set PE protection. /// </summary> private void SetPEReprotect() { ReverseReplicationInputProperties plannedFailoverInputProperties = new ReverseReplicationInputProperties() { FailoverDirection = this.Direction, ProviderSpecificDetails = new ReverseReplicationProviderSpecificInput() }; ReverseReplicationInput input = new ReverseReplicationInput() { Properties = plannedFailoverInputProperties }; // fetch the latest PE object ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem(this.fabricName, this.ProtectionEntity.ProtectionContainerId, this.ProtectionEntity.Name); ReplicationProtectedItemResponse replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem(this.fabricName, this.ProtectionEntity.ProtectionContainerId, Utilities.GetValueFromArmId(protectableItemResponse.ProtectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems)); PolicyResponse policyResponse = RecoveryServicesClient.GetAzureSiteRecoveryPolicy(Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Properties.PolicyID, ARMResourceTypeConstants.ReplicationPolicies)); this.ProtectionEntity = new ASRProtectionEntity(protectableItemResponse.ProtectableItem, replicationProtectedItemResponse.ReplicationProtectedItem); if (0 == string.Compare( this.ProtectionEntity.ReplicationProvider, Constants.HyperVReplicaAzure, StringComparison.OrdinalIgnoreCase)) { if (this.Direction == Constants.PrimaryToRecovery) { HyperVReplicaAzureReprotectInput reprotectInput = new HyperVReplicaAzureReprotectInput() { HvHostVmId = this.ProtectionEntity.FabricObjectId, VmName = this.ProtectionEntity.FriendlyName, OSType = ((string.Compare(this.ProtectionEntity.OS, "Windows") == 0) || (string.Compare(this.ProtectionEntity.OS, "Linux") == 0)) ? this.ProtectionEntity.OS : "Windows", VHDId = this.ProtectionEntity.OSDiskId }; HyperVReplicaAzureReplicationDetails providerSpecificDetails = (HyperVReplicaAzureReplicationDetails)replicationProtectedItemResponse.ReplicationProtectedItem.Properties.ProviderSpecificDetails; reprotectInput.StorageAccountId = providerSpecificDetails.RecoveryAzureStorageAccount; input.Properties.ProviderSpecificDetails = reprotectInput; } } LongRunningOperationResponse response = RecoveryServicesClient.StartAzureSiteRecoveryReprotection( this.fabricName, this.protectionContainerName, Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Id, ARMResourceTypeConstants.ReplicationProtectedItems), input); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); }
/// <summary> /// Write Protection Container. /// </summary> /// <param name="protectionContainer">Protection Container</param> private void WriteProtectionContainer(ProtectionContainer protectionContainer) { List <ASRPolicy> availablePolicies = new List <ASRPolicy>(); ProtectionContainerMappingListResponse protectionContainerMappingListResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectionContainerMapping(Utilities.GetValueFromArmId(protectionContainer.Id, ARMResourceTypeConstants.ReplicationFabrics), protectionContainer.Name); foreach (ProtectionContainerMapping protectionContainerMapping in protectionContainerMappingListResponse.ProtectionContainerMappings) { PolicyResponse policyResponse = RecoveryServicesClient.GetAzureSiteRecoveryPolicy(Utilities.GetValueFromArmId(protectionContainerMapping.Properties.PolicyId, ARMResourceTypeConstants.ReplicationPolicies)); availablePolicies.Add(new ASRPolicy(policyResponse.Policy)); } this.WriteObject(new ASRProtectionContainer(protectionContainer, availablePolicies)); }
/// <summary> /// Queries all Protection Containers under given Fabric. /// </summary> private void GetAll() { ProtectionContainerListResponse protectionContainerListResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectionContainer(); this.WriteProtectionContainers(protectionContainerListResponse.ProtectionContainers); }
/// <summary> /// Method to execute the command /// </summary> private void GetBackupCredentialsWithCertificate(string certificate) { // for .netStandard var targetLocation = string.IsNullOrEmpty(Path) ? Utilities.GetDefaultPath() : Path; if (!Directory.Exists(targetLocation)) { throw new ArgumentException(Resources.VaultCredPathException); } var subscriptionId = DefaultContext.Subscription.Id; var displayName = Vault.Name; WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.ExecutingGetVaultCredCmdlet, subscriptionId, Vault.ResourceGroupName, Vault.Name, targetLocation)); VaultCertificateResponse vaultCertificateResponse; var channelIntegrityKey = string.Empty; try { // Upload cert into ID Mgmt WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadingCertToIdmgmt)); X509Certificate2 x509 = new X509Certificate2(); byte[] data = Convert.FromBase64String(certificate); x509.Import(data); var bytes = x509.RawData; var certificateArgs = new CertificateRequest { Properties = new RawCertificateData { Certificate = bytes, AuthType = AuthType.AAD } }; var dateString = DateTime.Now.ToString("M-d-yyyy"); var friendlyName = string.Format("{0}{1}-{2}-vaultcredentials", Vault.Name, subscriptionId, dateString); vaultCertificateResponse = RecoveryServicesClient.GetRecoveryServicesClient.VaultCertificates.CreateWithHttpMessagesAsync( Vault.ResourceGroupName, Vault.Name, friendlyName, certificateArgs.Properties, RecoveryServicesClient.GetRequestHeaders()).Result.Body; WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadedCertToIdmgmt)); } catch (Exception exception) { throw exception; } // generate vault credentials var vaultCredsFileContent = GenerateVaultCredsForBackup(certificate, subscriptionId, vaultCertificateResponse); // NOTE: One of the scenarios for this cmdlet is to generate a file which will be an input // to DPM servers. // We found a bug in the DPM UI which is looking for a particular namespace in the input file. // The below is a hack to circumvent this issue and this would be removed once the bug can be fixed. vaultCredsFileContent = vaultCredsFileContent.Replace("Microsoft.Azure.Commands.AzureBackup.Models", "Microsoft.Azure.Portal.RecoveryServices.Models.Common"); // prepare for download var fileName = string.Format("{0}_{1:ddd MMM dd yyyy}.VaultCredentials", displayName, DateTime.UtcNow); var filePath = System.IO.Path.Combine(targetLocation, fileName); WriteDebug(string.Format(Resources.SavingVaultCred, filePath)); AzureSession.Instance.DataStore.WriteFile(filePath, Encoding.UTF8.GetBytes(vaultCredsFileContent)); var output = new VaultSettingsFilePath { FilePath = filePath, }; // Output filename back to user WriteObject(output); }
/// <summary> /// Queries by ID. /// </summary> private void GetById() { RecoveryServicesClient.StopAzureSiteRecoveryJob(this.Id); }
/// <summary> /// Method to execute the command /// </summary> private void GetSiteRecoveryCredentials() { var subscription = DefaultProfile.DefaultContext.Subscription; // Generate certificate var cert = CertUtils.CreateSelfSignedCertificate( VaultCertificateExpiryInHoursForHRM, subscription.Id, Vault.Name); var site = new ASRSite(); if (!string.IsNullOrEmpty(SiteIdentifier) && !string.IsNullOrEmpty(SiteFriendlyName)) { site.ID = SiteIdentifier; site.Name = SiteFriendlyName; } var fileName = GenerateFileName(); var filePath = string.IsNullOrEmpty(Path) ? Utilities.GetDefaultPath() : Path; // Generate file. if (RecoveryServicesClient.getVaultAuthType(Vault.ResourceGroupName, Vault.Name) == 0) { var vaultCreds = RecoveryServicesClient.GenerateVaultCredential( cert, Vault, site, AuthType.ACS); // write the content to a file. var output = new VaultSettingsFilePath { FilePath = Utilities.WriteToFile(vaultCreds, filePath, fileName) }; // print the path to the user. WriteObject(output, true); } else { var fullFilePath = System.IO.Path.Combine(filePath, fileName); WriteDebug( string.Format( CultureInfo.InvariantCulture, Resources.ExecutingGetVaultCredCmdlet, subscription.Id, Vault.ResourceGroupName, Vault.Name, fullFilePath)); VaultCertificateResponse vaultCertificateResponse; try { // Upload cert into ID Mgmt WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadingCertToIdmgmt)); vaultCertificateResponse = UploadCert(cert); WriteDebug(string.Format(CultureInfo.InvariantCulture, Resources.UploadedCertToIdmgmt)); var managementCert = CertUtils.SerializeCert(cert, X509ContentType.Pfx); // generate vault credentials var vaultCredsFileContent = GenerateVaultCredsForSiteRecovery( managementCert, subscription.Id, vaultCertificateResponse, site); WriteDebug(string.Format(Resources.SavingVaultCred, fullFilePath)); AzureSession.Instance.DataStore.WriteFile(fullFilePath, Encoding.UTF8.GetBytes(vaultCredsFileContent)); var output = new VaultSettingsFilePath { FilePath = fullFilePath, }; // Output filename back to user WriteObject(output, true); } catch (Exception exception) { throw exception; } } }
/// <summary> /// Queries by friendly name. /// </summary> private void GetByFriendlyName() { bool found = false; ReplicationProtectedItemListResponse replicationProtectedItemListResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem( Utilities.GetValueFromArmId(this.ProtectionContainer.ID, ARMResourceTypeConstants.ReplicationFabrics), this.ProtectionContainer.Name); ReplicationProtectedItem replicationProtectedItem = replicationProtectedItemListResponse.ReplicationProtectedItems.SingleOrDefault(t => string.Compare(t.Properties.FriendlyName, this.FriendlyName, StringComparison.OrdinalIgnoreCase) == 0); if (replicationProtectedItem != null) { ReplicationProtectedItemResponse replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem( Utilities.GetValueFromArmId(this.ProtectionContainer.ID, ARMResourceTypeConstants.ReplicationFabrics), this.ProtectionContainer.Name, replicationProtectedItem.Name); WriteReplicationProtectedItem(replicationProtectedItemResponse.ReplicationProtectedItem); found = true; } if (!found) { throw new InvalidOperationException( string.Format( Properties.Resources.ProtectionEntityNotFound, this.FriendlyName, this.ProtectionContainer.FriendlyName)); } }
/// <summary> /// Generates vault creds file content for Site Recovery Vault /// </summary> /// <param name="cert">management certificate</param> /// <param name="subscriptionId">subscription Id</param> /// <param name="vaultCertificateResponse">vaultCertificate Response</param> /// <param name="asrSite">asrSite Info</param> /// <returns>xml file in string format</returns> private string GenerateVaultCredsForSiteRecovery(string managementCert, string subscriptionId, VaultCertificateResponse vaultCertificateResponse, ASRSite asrSite) { using (var output = new MemoryStream()) { using (var writer = XmlWriter.Create(output, GetXmlWriterSettings())) { var aadDetails = vaultCertificateResponse.Properties as ResourceCertificateAndAadDetails; var resourceProviderNamespace = string.Empty; var resourceType = string.Empty; Utilities.GetResourceProviderNamespaceAndType(Vault.ID, out resourceProviderNamespace, out resourceType); Logger.Instance.WriteDebug(string.Format( "GenerateVaultCredential resourceProviderNamespace = {0}, resourceType = {1}", resourceProviderNamespace, resourceType)); // Update vault settings with the working vault to generate file Utilities.UpdateCurrentVaultContext(new ASRVaultCreds { ResourceGroupName = Vault.ResourceGroupName, ResourceName = Vault.Name, ResourceNamespace = resourceProviderNamespace, ARMResourceType = resourceType }); //Code taken from Ibiza code var aadAudience = string.Format(CultureInfo.InvariantCulture, @"https://RecoveryServiceVault/{0}/{1}/{2}", Vault.Location, Vault.Name, aadDetails.ResourceId); var vaultCreds = new RSVaultAsrCreds { VaultDetails = new ASRVaultDetails { SubscriptionId = subscriptionId, ResourceGroup = Vault.ResourceGroupName, ResourceName = Vault.Name, ResourceId = aadDetails.ResourceId.Value, Location = Vault.Location, ResourceType = RecoveryServicesVaultType, ProviderNamespace = PSRecoveryServicesClient.ProductionRpNamespace }, ManagementCert = managementCert, Version = VaultCredentialVersionAad, AadDetails = new ASRVaultAadDetails { AadAuthority = aadDetails.AadAuthority, AadTenantId = aadDetails.AadTenantId, ServicePrincipalClientId = aadDetails.ServicePrincipalClientId, AadVaultAudience = aadAudience, ArmManagementEndpoint = aadDetails.AzureManagementEndpointAudience }, ChannelIntegrityKey = RecoveryServicesClient.GetCurrentVaultChannelIntegrityKey(), SiteId = asrSite.ID ?? String.Empty, SiteName = asrSite.Name ?? String.Empty, PrivateEndpointStateForSiteRecovery = Vault.Properties.PrivateEndpointStateForSiteRecovery }; var serializer = new DataContractSerializer(typeof(RSVaultAsrCreds)); serializer.WriteObject(writer, vaultCreds); } return(Encoding.UTF8.GetString(output.ToArray())); } }
/// <summary> /// ProcessRecord of the command. /// </summary> public override void ExecuteSiteRecoveryCmdlet() { base.ExecuteSiteRecoveryCmdlet(); var policy = RecoveryServicesClient.GetAzureSiteRecoveryPolicy( Utilities.GetValueFromArmId(this.ProtectionContainerMapping.PolicyId, ARMResourceTypeConstants.Policies)).Policy; var policyInstanceType = policy.Properties.ProviderSpecificDetails.InstanceType; switch (this.ParameterSetName) { case ASRParameterSets.EnterpriseToEnterprise: if (policyInstanceType != Constants.HyperVReplica2012 && policyInstanceType != Constants.HyperVReplica2012R2) { throw new PSArgumentException( string.Format( Properties.Resources.ContainerMappingParameterSetMismatch, this.ProtectionContainerMapping.Name, policyInstanceType)); } break; case ASRParameterSets.EnterpriseToAzure: case ASRParameterSets.HyperVSiteToAzure: if (policyInstanceType != Constants.HyperVReplicaAzure) { throw new PSArgumentException( string.Format( Properties.Resources.ContainerMappingParameterSetMismatch, this.ProtectionContainerMapping.Name, policyInstanceType)); } break; default: break; } EnableProtectionProviderSpecificInput enableProtectionProviderSpecificInput = new EnableProtectionProviderSpecificInput(); EnableProtectionInputProperties inputProperties = new EnableProtectionInputProperties() { PolicyId = this.ProtectionContainerMapping.PolicyId, ProtectableItemId = this.ProtectableItem.ID, ProviderSpecificDetails = enableProtectionProviderSpecificInput }; EnableProtectionInput input = new EnableProtectionInput() { Properties = inputProperties }; // E2A and B2A. if (0 == string.Compare(this.ParameterSetName, ASRParameterSets.EnterpriseToAzure, StringComparison.OrdinalIgnoreCase) || 0 == string.Compare(this.ParameterSetName, ASRParameterSets.HyperVSiteToAzure, StringComparison.OrdinalIgnoreCase)) { HyperVReplicaAzureEnableProtectionInput providerSettings = new HyperVReplicaAzureEnableProtectionInput(); providerSettings.HvHostVmId = this.ProtectableItem.FabricObjectId; providerSettings.VmName = this.ProtectableItem.FriendlyName; // 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 ProtectableItemResponse protectableItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectableItem( Utilities.GetValueFromArmId(this.ProtectableItem.ID, ARMResourceTypeConstants.ReplicationFabrics), this.ProtectableItem.ProtectionContainerId, this.ProtectableItem.Name); this.ProtectableItem = new ASRProtectableItem(protectableItemResponse.ProtectableItem); } 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 (RecoveryAzureStorageAccountId != null) { providerSettings.TargetStorageAccountId = RecoveryAzureStorageAccountId; } input.Properties.ProviderSpecificDetails = providerSettings; } this.response = RecoveryServicesClient.EnableProtection( Utilities.GetValueFromArmId(this.ProtectableItem.ID, ARMResourceTypeConstants.ReplicationFabrics), Utilities.GetValueFromArmId(this.ProtectableItem.ID, ARMResourceTypeConstants.ReplicationProtectionContainers), Name, input); jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); if (this.WaitForCompletion.IsPresent) { this.WaitForJobCompletion(this.jobResponse.Job.Name); jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); } }