/// <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> /// Syncs the owner information. /// </summary> private void SyncOwnerInformationOnPE() { // 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); LongRunningOperationResponse response = RecoveryServicesClient.UpdateAzureSiteRecoveryProtectionEntity( this.fabricName, this.protectionContainerName, Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Id, ARMResourceTypeConstants.ReplicationProtectedItems), new Object() ); JobResponse jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); if (this.WaitForCompletion) { this.WaitForJobCompletion(jobResponse.Job.Name); jobResponse = RecoveryServicesClient .GetAzureSiteRecoveryJobDetails(PSRecoveryServicesClient.GetJobIdFromReponseLocation(response.Location)); WriteObject(new ASRJob(jobResponse.Job)); } }
/// <summary> /// Write Protection Entity /// </summary> /// <param name="protectableItem"></param> private void WriteProtectionEntity(ProtectableItem protectableItem) { ReplicationProtectedItemResponse replicationProtectedItemResponse = null; if (!String.IsNullOrEmpty(protectableItem.Properties.ReplicationProtectedItemId)) { replicationProtectedItemResponse = RecoveryServicesClient.GetAzureSiteRecoveryReplicationProtectedItem( Utilities.GetValueFromArmId(this.ProtectionContainer.ID, ARMResourceTypeConstants.ReplicationFabrics), this.ProtectionContainer.Name, Utilities.GetValueFromArmId(protectableItem.Properties.ReplicationProtectedItemId, ARMResourceTypeConstants.ReplicationProtectedItems)); } if (replicationProtectedItemResponse != null && replicationProtectedItemResponse.ReplicationProtectedItem != null) { PolicyResponse policyResponse = RecoveryServicesClient.GetAzureSiteRecoveryPolicy(Utilities.GetValueFromArmId(replicationProtectedItemResponse.ReplicationProtectedItem.Properties.PolicyID, ARMResourceTypeConstants.ReplicationPolicies)); this.WriteObject(new ASRProtectionEntity(protectableItem, replicationProtectedItemResponse.ReplicationProtectedItem, policyResponse.Policy)); } else { this.WriteObject(new ASRProtectionEntity(protectableItem)); } }
/// <summary> /// Queries by Friendly name. /// </summary> private void GetByFriendlyName() { PolicyListResponse profileListResponse = RecoveryServicesClient.GetAzureSiteRecoveryPolicy(); bool found = false; foreach (Policy policy in profileListResponse.Policies) { if (0 == string.Compare(this.FriendlyName, policy.Properties.FriendlyName, true)) { this.WritePolicy(policy); found = true; } } if (!found) { throw new InvalidOperationException( string.Format( Properties.Resources.PolicyNotFound, this.FriendlyName, PSRecoveryServicesClient.asrVaultCreds.ResourceName)); } }
/// <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)); }
/// <summary> /// Writes Protection Containers. /// </summary> /// <param name="protectionContainers">List of Protection Containers</param> private void WriteProtectionContainers(IList <ProtectionContainer> protectionContainers) { List <ASRProtectionContainer> asrProtectionContainers = new List <ASRProtectionContainer>(); Dictionary <string, ASRPolicy> policyCache = new Dictionary <string, ASRPolicy>(); foreach (ProtectionContainer protectionContainer in protectionContainers) { List <ASRPolicy> availablePolicies = new List <ASRPolicy>(); List <ASRProtectionContainerMapping> asrProtectionContainerMappings = new List <ASRProtectionContainerMapping>(); // Check if container is paired then fetch policy details. if (0 == string.Compare(protectionContainer.Properties.PairingStatus, "paired", StringComparison.OrdinalIgnoreCase)) { // Get all Protection Container Mappings for specific container to find out the policies attached to container. ProtectionContainerMappingListResponse protectionContainerMappingListResponse = RecoveryServicesClient.GetAzureSiteRecoveryProtectionContainerMapping( Utilities.GetValueFromArmId(protectionContainer.Id, ARMResourceTypeConstants.ReplicationFabrics), protectionContainer.Name); asrProtectionContainerMappings = protectionContainerMappingListResponse.ProtectionContainerMappings.Select(pcm => new ASRProtectionContainerMapping(pcm)).ToList(); // TODO: This call can be made parallel to speed up processing if required later. foreach (ProtectionContainerMapping protectionContainerMapping in protectionContainerMappingListResponse.ProtectionContainerMappings) { string policyName = Utilities.GetValueFromArmId(protectionContainerMapping.Properties.PolicyId, ARMResourceTypeConstants.ReplicationPolicies).ToLower(); ASRPolicy asrPolicy = null; if (policyCache.ContainsKey(policyName)) { asrPolicy = policyCache[policyName]; } else { // Get all policies and fill up the dictionary once. PolicyListResponse policyListResponse = RecoveryServicesClient.GetAzureSiteRecoveryPolicy(); foreach (Policy policy in policyListResponse.Policies) { asrPolicy = new ASRPolicy(policy); try { policyCache.Add(asrPolicy.Name.ToLower(), asrPolicy); } catch (ArgumentException) { // In case of item already exist eat the exception. } } // Get the policy from dictionary now. asrPolicy = policyCache[policyName]; } availablePolicies.Add(asrPolicy); } } asrProtectionContainers.Add(new ASRProtectionContainer(protectionContainer, availablePolicies.Distinct().ToList(), asrProtectionContainerMappings)); } asrProtectionContainers.Sort((x, y) => x.FriendlyName.CompareTo(y.FriendlyName)); this.WriteObject(asrProtectionContainers, true); }
/// <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, 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.Server == null || string.Compare(this.Server.FabricType, Constants.HyperVSite) != 0) { throw new InvalidOperationException( Properties.Resources.ImproperServerObjectPassedForHyperVFailback); } else { failbackInput.ProviderIdForAlternateRecovery = this.Server.ID; } } 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(); 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)); } }
/// <summary> /// PE Reprotect. /// </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> /// Starts PE Planned failover. /// </summary> private void StartPEPlannedFailover() { PlannedFailoverInputProperties plannedFailoverInputProperties = new PlannedFailoverInputProperties() { FailoverDirection = this.Direction, ProviderSpecificDetails = new ProviderSpecificFailoverInput() }; PlannedFailoverInput 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) { HyperVReplicaAzureFailoverProviderInput failoverInput = new HyperVReplicaAzureFailoverProviderInput() { PrimaryKekCertificatePfx = null, SecondaryKekCertificatePfx = null, VaultLocation = this.GetCurrentValutLocation() }; input.Properties.ProviderSpecificDetails = failoverInput; } else { HyperVReplicaAzureFailbackProviderInput 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)); }