Update RecoveryServices fetch ILR mount scripts with the new API - #30104
Conversation
…tion (2026-08-01) Regenerate Backup SDK against api-version 2026-08-01 (fetch ILR mount scripts / clientScripts via the new listMountScripts action instead of the broad ILR operationsStatus response) and wire Get-AzRecoveryServicesBackupRPMountScript through it. Addresses MSRC-114273 (iSCSI CHAP redaction). SDK generated from the pre-merge spec fork; repointed to the merged Azure spec in a follow-up commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
… #44639, 2026-08-01) Switch AutoRest input-file from the @hiaga pre-merge fork to Azure/azure-rest-api-specs at merge commit 4e6e13d398d4c2616237322a62394fc4f1dfeb81 (merged 2026-08-29). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
… 2026-08-01 Refresh the ILR listMountScripts branch (MSRC-114273) on top of main's 2026-07-01 migration (Defender Source Scan + immutability AsPerPolicy fix). The 2026-08-01 generated SDK is a superset of 2026-07-01, so generated code is taken from this branch; hand-written adapter conflicts (BMSAPIs) take main's refactored helpers/LRO shape, which compile against the 2026-08-01 client. ChangeLog and Backup SDK README reconciled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical and moderate findings remain in null-result handling, terminal-status handling, and playback coverage.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
src/RecoveryServices/RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs:885
GetOperationStatusonly waits forInProgressand returns failed or canceled terminal statuses unchanged (TrackingHelpers.cs:48-63). Because that result is discarded here, a failed provision still calls the success-only script action, which can return a 4xx (or leave the existing null-result failure); inspect the terminal status and handle unsuccessful provisioning before fetching scripts.
InstantItemRecoveryTarget recoveryTarget =
ServiceClientAdapter.GetInstantItemRecoveryOperationResult(
src/RecoveryServices/RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs:900
- The new action does not guarantee two entries:
ClientScriptForConnectexposesOSType, and the merged 2026-08-01 contract includes a one-item Windows response. A one-script Windows response therefore entersGenerateILRResponseForLinuxVMs, which expects base64 content containingTargetPassword, instead of handling the Windows URL/content form. Dispatch from the script's OS/type and honor theUrlversusScriptContentcontract rather than using the list length.
if (recoveryTarget.ClientScripts.Count == 2)
{
// clientScriptForConnection.OsType == "Windows"
result = this.GenerateILRResponseForWindowsVMs(
recoveryTarget.ClientScripts[1], out content);
- Files reviewed: 10/17 changed files
- Comments generated: 5
- Review effort level: Lite
…action Update Test-AzureVMRPMountScript to reflect the 2026-08-01 listInstantItemRecoveryOperationResult path: assert OsType/Password/Filename/ FilePath are returned via the dedicated action, and clarify the skip is live-only pending a re-record against an ILR-capable vault. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
left a comment
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved provider correctness, playback coverage, API metadata, and resource-cleanup issues remain.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (5)
src/RecoveryServices/RecoveryServices.Backup.Management.Sdk/README.md:27
- This source note uses
listMountScripts, but the merged 2026-08-01 spec and the generated SDK uselistInstantItemRecoveryOperationResultfor both the operation name and route. Please keep the generation metadata aligned with the actual spec operation.
# Spec source: merged Azure/azure-rest-api-specs PR #44639 (RecoveryServicesBackup 2026-08-01, listMountScripts / MSRC-114273), merged 2026-08-29.
src/RecoveryServices/RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs:875
- The terminal operation status is discarded here, so a
FailedorCanceledprovision still proceeds to the mount-script action. That action is only valid for a successfully provisioned active ILR session, so failures will be masked by a secondary result-call error instead of surfacing the original operation error. Capture the returned status and handle unsuccessful terminal states before fetching scripts, as the other backup cmdlet flows do.
TrackingHelpers.GetOperationStatus(
ilRResponse,
opId => ServiceClientAdapter.GetProtectedItemOperationStatus(
src/RecoveryServices/RecoveryServices.Backup.ServiceClientAdapter/BMSAPIs/RecoveryPointsAPIs.cs:283
- This low-level generated call returns an
AzureOperationResponsethat is disposable, but the adapter readsBodyand drops the response without disposing it. The generated wrapper usesusingfor the same call (ItemLevelRecoveryConnectionsOperationsExtensions.cs:77-82); without that cleanup, repeated mount-script requests can retain HTTP response/connection resources until GC. Wrap this response inusing(or call the generated body-returning wrapper).
var response = BmsAdapter.Client.ItemLevelRecoveryConnections.ListInstantItemRecoveryOperationResultWithHttpMessagesAsync(
resourceGroupName ?? BmsAdapter.GetResourceGroupName(),
vaultName ?? BmsAdapter.GetResourceName(),
AzureFabricName,
containerName,
protectedItemName,
recoveryPointId,
provisionInstantItemRecoveryOperationId,
cancellationToken: BmsAdapter.CmdletCancellationToken).Result;
return response.Body;
src/RecoveryServices/RecoveryServices/ChangeLog.md:22
- The merged 2026-08-01 spec names the action
listInstantItemRecoveryOperationResult, which is also the generated SDK method and wire path;listMountScriptsis not the action name. Please update this release note so users can correlate it with the actual API.
* Moved Instant Item Recovery (ILR) mount script retrieval to the dedicated `listMountScripts` action (api-version `2026-08-01`); `Get-AzRecoveryServicesBackupRPMountScript` no longer reads iSCSI CHAP connection details from the broad ILR operation-status response (MSRC-114273).
src/RecoveryServices/RecoveryServices/ChangeLog.md:22
- The new release-note entry introduces the less-obvious acronyms
iSCSIandCHAPwithout expanding them. Expand them on first use so users can understand the security-sensitive connection details being moved.
* Moved Instant Item Recovery (ILR) mount script retrieval to the dedicated `listMountScripts` action (api-version `2026-08-01`); `Get-AzRecoveryServicesBackupRPMountScript` no longer reads iSCSI CHAP connection details from the broad ILR operation-status response (MSRC-114273).
- Files reviewed: 12/19 changed files
- Comments generated: 2
- Review effort level: Lite
commented
Sep 14, 2026
|
/azp run |
commented
Sep 14, 2026
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
…cordings for api-version 2026-08-01 - Truly re-recorded Test-AzureVMRPMountScript live at api-version 2026-08-01 against a pre-provisioned ILR-capable setup, capturing the dedicated listInstantItemRecoveryOperationResult mount-script path (MSRC-114273). Un-skipped the [Fact] so it runs in playback in CI. Uses a deterministic recovery-point query window and does not delete the shared pre-provisioned vault/VM. - Updated the remaining Backup scenario recordings to api-version 2026-08-01 (backup-scoped URLs only, with recomputed EncodedRequestUri match keys). - Removed a trailing newline in generated CloudErrorBody.cs to clear the Analyze (9090) build failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
left a comment
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (5)
src/RecoveryServices/RecoveryServices.Backup.Management.Sdk/README.md:27
- The generation provenance names the action
listMountScripts, but the merged spec and generated route uselistInstantItemRecoveryOperationResult. Keeping the obsolete name here makes the documented input misleading and can confuse future regeneration or investigation of the generated method.
# Spec source: merged Azure/azure-rest-api-specs PR #44639 (RecoveryServicesBackup 2026-08-01, listMountScripts / MSRC-114273), merged 2026-08-29.
src/RecoveryServices/RecoveryServices.Backup.Providers/Providers/IaasVmPsBackupProvider.cs:895
ClientScriptsis optional in the generatedInstantItemRecoveryTarget, but this branch leavesresultnull when the action returns no scripts and line 917 then dereferences it. Raise the existingILRNoClientScriptsReturnederror before usingresultinstead of exposing aNullReferenceException.
if (recoveryTarget != null && recoveryTarget.ClientScripts != null &&
recoveryTarget.ClientScripts.Count != 0)
{
src/RecoveryServices/RecoveryServices.Backup.Test/ScenarioTests/IaasVm/ItemTests.cs:118
- The newly enabled check-in fixture only uses the Windows VM, so it exercises the
ClientScripts.Count == 2branch but never validates the distinct Linux parsing path inGenerateILRResponseForLinuxVMs. Add a Linux recorded fixture or parameterize this scenario so the new action is covered for both supported OS variants.
[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
[Trait(TestConstants.Workload, TestConstants.AzureVM)]
public void TestAzureVMRPMountScript()
src/RecoveryServices/RecoveryServices.Backup.Test/ScenarioTests/IaasVm/ItemTests.ps1:1253
- The recorded action response contains two Windows scripts, so the provider selects the second and performs a direct
HttpWebRequestto itsdownload.microsoft.comURL. That download is outside the Azure session record and is not mocked here, making the newly enabled playback test depend on external network availability and prone to fail across CI operating systems; use an inline Linux fixture or mock/record this download before enabling the check-in test.
$mountScriptDetails = Get-AzRecoveryServicesBackupRPMountScript `
-VaultId $vault.ID `
-RecoveryPoint $rp
src/RecoveryServices/RecoveryServices/ChangeLog.md:22
- The user-facing changelog repeats the obsolete
listMountScriptsname, while the actual stable operation islistInstantItemRecoveryOperationResult. Update the entry so users and maintainers can identify the action that the cmdlet now calls.
- Files reviewed: 44/61 changed files
- Comments generated: 5
- Review effort level: Lite
There was a problem hiding this comment.
Redacted the recorded CHAP credential in the mount fixture; the legitimate dedicated-action response is retained.
There was a problem hiding this comment.
Tracked: the CHAP scriptNameSuffix fixture issue will be resolved via live re-record or a synthetic fixture; I will not hand-edit cassettes as a shortcut.
commented
Sep 18, 2026
|
/azp run |
commented
Sep 18, 2026
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
# Conflicts: # src/RecoveryServices/RecoveryServices.Backup.Test/SessionRecords/Microsoft.Azure.Commands.RecoveryServices.Backup.Test.ScenarioTests.ItemTests/TestAzureVMSourceScan.json
… redact leaked CHAP script from operationsStatus recording (#9) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
…record These two tests are not part of the ILR change; they only fail playback because the shared backup client default was bumped to 2026-08-01, which changes every recorded request URL. Keeping them identical to main (zero net diff) until they are re-recorded at 2026-08-01 in a follow-up commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
left a comment
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved correctness, test determinism, sensitive-output, cleanup, and documentation issues remain.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 5
Open (13)
Do not log CHAP passwords in mount script details · New This recordedscriptNameSuffixcontains the live ILR credential:… This unrelated generated Automation SDK change causes the reported Generated Sdk Check failure for… The new action does not guarantee two entries or a Windows script at index 1. Its 2026-08-01… This guard leavesresultnull when the new action returns a successful target with omitted or… Treat canceled and failed operations as terminal failures · New If the mount-script retrieval, an assertion, or file handling throws after provisioning, this… This check-in test replays a Windows client script whoseurlpoints todownload.microsoft.com,… The terminalOperationStatusis discarded here, so a failed or canceled provision still invokes… Please add an automated playback/check-in test for this new request and response path. The existing… Changing the shared client default changes every Recovery Services request to API version… The release note names the actionlistMountScripts, but the merged 2026-08-01 spec and generated… The merged spec exposes this wire action aslistInstantItemRecoveryOperationResult(the generated…
The client default moved to 2026-08-01, so the prior 2026-07-01 recording no longer matched request URLs on playback. Re-recorded live; validated playback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
commented
Sep 26, 2026
|
Commenter does not have sufficient privileges for PR 30104 in repo Azure/azure-powershell |
…dataplane api-version IaasVmPsBackupProvider: restore the original index-based client-script selection (Count==2 -> Windows -> ClientScripts[1] URL-bearing; else Linux -> ClientScripts[0] inline). The FirstOrDefault(OSType=="Windows") heuristic grabbed the url-less connection-info script (both returned scripts report OSType "Windows") and crashed the Windows download path with WebRequest.Create(null). TestAzureVMSourceScanRecoveryPoints: bump the 3 backup-dataplane requests 2026-07-01 -> 2026-08-01 to match the promoted client; the RecoveryServices management vault GET stays 2026-07-01. Both tests verified passing in local playback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
left a comment
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved credential exposure, test reliability, API-version recording failures, and response-handling issues remain.
Review effort: Lite
Findings: 11
Open (12)
Sanitize embedded CHAP credentials in the test fixture · New Sanitize credentials in the dedicated-action response Replace live password in operation-status suffix Sanitize ILR credentials before enabling the check-in test Redact CHAP credentials from the script name suffix Use a current relative recovery-point window Avoid unconditional check-in tests with unmanaged live resources Select the Windows script entry with a non-empty URL Redact CHAP credential from both fixture responses Replace remaining live CHAP credential in operation fixture This recordedscriptNameSuffixcontains the live ILR credential:… Select URL-bearing scripts before choosing the response parser · New
Resolved since last review (8)
This unrelated generated Automation SDK change causes the reported Generated Sdk Check failure for… The new action does not guarantee two entries or a Windows script at index 1. Its 2026-08-01… This guard leavesresultnull when the new action returns a successful target with omitted or… If the mount-script retrieval, an assertion, or file handling throws after provisioning, this… The terminalOperationStatusis discarded here, so a failed or canceled provision still invokes… Please add an automated playback/check-in test for this new request and response path. The existing… The release note names the actionlistMountScripts, but the merged 2026-08-01 spec and generated… The merged spec exposes this wire action aslistInstantItemRecoveryOperationResult(the generated…
| if (recoveryTarget.ClientScripts.Count == 2) | ||
| { | ||
| result = this.GenerateILRResponseForWindowsVMs( | ||
| recoveryTarget.ClientScripts[1], out content); | ||
| } | ||
| else | ||
| { | ||
| result = this.GenerateILRResponseForLinuxVMs( | ||
| recoveryTarget.ClientScripts[0], | ||
| protectedItemName, rp.RecoveryPointTime.ToString(), out content); | ||
| } |
commented
Sep 26, 2026
|
/azp run |
commented
Sep 26, 2026
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
Update the Azure Files cross-subscription restore target lookup playback values to the existing managed-identity test resources and re-record the cassette against backup dataplane 2026-08-01. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
left a comment
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved implementation, recording, test-fixture, and test-reliability issues remain.
Review effort: Lite
Findings: 10
Open (12)
Sanitize embedded CHAP credentials in the test fixture Sanitize credentials in the dedicated-action response Replace live password in operation-status suffix Sanitize ILR credentials before enabling the check-in test Redact CHAP credentials from the script name suffix Use a current relative recovery-point window Avoid unconditional check-in tests with unmanaged live resources Redact CHAP credential from both fixture responses Replace remaining live CHAP credential in operation fixture This recordedscriptNameSuffixcontains the live ILR credential:… Validate required instant recovery operation ID · New Select URL-bearing scripts before choosing the response parser
Resolved since last review (1)
| InstantItemRecoveryOperationResultRequest body = new InstantItemRecoveryOperationResultRequest(); | ||
| if(provisionInstantItemRecoveryOperationId != null) | ||
| { | ||
| body.ProvisionInstantItemRecoveryOperationId = provisionInstantItemRecoveryOperationId; |
commented
Sep 26, 2026
|
/azp run |
commented
Sep 26, 2026
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
TestAzureFSCrossRegionCrossSubscriptionRestore requires a GRS vault with multi-day cross-region-replicated recovery points, which is not currently available. Skip with a tracked reason until secondary recovery points replicate for re-record. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
left a comment
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved moderate correctness, test-fixture, credential-safety, and failing-recording issues remain.
Review effort: Lite
Findings: 10
Open (13)
Sanitize embedded CHAP credentials in the test fixture Sanitize credentials in the dedicated-action response Replace live password in operation-status suffix Sanitize ILR credentials before enabling the check-in test Redact CHAP credentials from the script name suffix Use a current relative recovery-point window Avoid unconditional check-in tests with unmanaged live resources Redact CHAP credential from both fixture responses Replace remaining live CHAP credential in operation fixture This recordedscriptNameSuffixcontains the live ILR credential:… Restore active CRR regression test coverage · New Validate required instant recovery operation ID Select URL-bearing scripts before choosing the response parser
| } | ||
|
|
||
| [Fact] | ||
| [Fact(Skip = "CRR cross-region cross-subscription restore needs a GRS vault with multi-day cross-region-replicated recovery points; setup unavailable. Tracked for re-record once secondary RPs replicate (MSRC-114273 ILR CHAP re-record).")] |
commented
Sep 27, 2026
|
/azp run |
commented
Sep 27, 2026
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
…version 2026-08-01
Scoped the backup dataplane api-version from 2026-07-01 to 2026-08-01 in the
four AzureFiles managed-identity cassettes (register/re-register, enable
protection, SAMI backup+restore, UAMI backup+restore). RecoveryServices
management calls (bare /vaults/{name}) keep their own 2026-07-01 version.
LRO poll headers (Location/Azure-AsyncOperation) bumped in lockstep so the
standard Azure LRO poller matches. Verified all four pass in playback.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6d420238-f921-4e0f-ac6d-9acd4ed164b8
commented
Sep 27, 2026
|
/azp run |
commented
Sep 27, 2026
|
Azure Pipelines: Successfully started running 3 pipeline(s). |
left a comment
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved provider, SDK, recording, and test issues—including a critical hard-coded test environment—block approval.
Review effort: Lite
Findings: 11
Open (15)
Use configured subscription and resource group values · New Sanitize embedded CHAP credentials in the test fixture Sanitize credentials in the dedicated-action response Replace live password in operation-status suffix Sanitize ILR credentials before enabling the check-in test Redact CHAP credentials from the script name suffix Use a current relative recovery-point window Avoid unconditional check-in tests with unmanaged live resources Redact CHAP credential from both fixture responses Replace remaining live CHAP credential in operation fixture This recordedscriptNameSuffixcontains the live ILR credential:… Keep cross-region restore playback test enabled · New Restore active CRR regression test coverage Validate required instant recovery operation ID Select URL-bearing scripts before choosing the response parser
| $resourceGroupName = "hiaga-ilr-ecy-rg" | ||
| $vaultName = "ilr-ecy-vault1" | ||
| $vmFriendlyName = "ilr-win-ecy-vm1" |
| } | ||
|
|
||
| [Fact] | ||
| [Fact(Skip = "CRR cross-region cross-subscription restore needs a GRS vault with multi-day cross-region-replicated recovery points; setup unavailable. Tracked for re-record once secondary RPs replicate (MSRC-114273 ILR CHAP re-record).")] |



🤖 PR Validation — ❌ Action needed
️✔️Az.Accounts
️✔️Az.Compute
️✔️Az.Network
❌Az.RecoveryServices
️✔️Az.RecoveryServices.Backup
Description
Moves Instant Item Recovery (ILR) mount script retrieval to the dedicated, RBAC-gated
listMountScriptsaction introduced in the stable API version2026-08-01ofMicrosoft.RecoveryServices/RecoveryServicesBackup.Previously the ILR mount scripts (which contain iSCSI CHAP connection details) were returned inline on the broad ILR-provision
operationsStatusresponse.Get-AzRecoveryServicesBackupRPMountScriptnow fetches them via the new action instead.Changes
2026-08-01from the merged spec: RecoveryServicesBackup: add 2026-08-01 stable version with fetchInstantItemRecoveryOperationResult action (MSRC-114273) azure-rest-api-specs#44639 (merged 2026-08-29, commit4e6e13d398d4c2616237322a62394fc4f1dfeb81).Get-AzRecoveryServicesBackupRPMountScript(and the Backup ServiceClientAdapter APIs) through the newlistMountScriptsaction.ChangeLog.mdupdated under Upcoming Release.Validation
eastus2euap) for both Linux and Windows IaaS VM ILR: provision -> operation-status polls ->listMountScriptscomplete under a single operation, and the mount script is returned by the new action (no CHAP details on the operation-status response). Mount + revoke succeed for both guest OS variants.Checklist
README.mdinput-file repointed from the pre-merge fork to Azure/azure-rest-api-specs).ChangeLog.mdupdated.clientScriptsremains optional).