You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将Azure Recovery Services PowerShell脚本转为.NET ARM SDK调用

Azure Recovery Services数据库恢复:PowerShell转C# SDK实现

我需要将用于从Azure Recovery Services恢复数据库的PowerShell脚本转换为C# Azure Resource Manager SDK实现,但无法匹配PowerShell Cmdlet与SDK中的等效调用(命名规则差异、版本变更导致文档缺失)。以下是核心PowerShell脚本、已完成的C#初始化代码,以及关键Cmdlet对应的SDK等效实现示例:

核心PowerShell脚本

function Restore-OTADatabaseFromAzure {
    param (
        [string] $SourceSqlInstanceName,
        [string] $SourceSqlAGName,
        [string] $SourceDatabaseName,
        [string] $NewDatabaseName,
        [string] $HaNode,
        [string] $DataPath,
        [string] $LogPath
    )

    try {
        Select-azSubscription -Subscription $subscription
        
        $vault = Get-AzRecoveryServicesVault  -ResourceGroupName $resourceGroupName -Name $vaultName  -Verbose 

        $backupItem = Get-AzRecoveryServicesBackupItem -BackupManagementType AzureWorkload -WorkloadType MSSQL -Name "SQLDataBase;$($SourceSqlAGName);$($SourceDatabaseName)" -VaultId $vault.ID  -ProtectionStatus Healthy

        $startDate = (Get-Date).AddDays(-10).ToUniversalTime()
        $endDate = (Get-Date).ToUniversalTime()
        $recoveryPoints = Get-AzRecoveryServicesBackupRecoveryPoint -Item $backupItem -VaultId $vault.ID -StartDate $startdate -EndDate $endDate
        $latestRecoveryPoint = Get-AzRecoveryServicesBackupRecoveryPoint -Item $backupItem -VaultId $vault.ID -RecoveryPointId $recoveryPoints[0].RecoveryPointId

        $TargetContainer =  Get-AzRecoveryServicesBackupContainer -ContainerType AzureVMAppContainer -VaultId $vault.ID -FriendlyName $HaNode.ToLower()

        $TargetInstance = Get-AzRecoveryServicesBackupProtectableItem -WorkloadType MSSQL -ItemType SQLInstance -Name "sqlinstance;ota" -ServerName "servername..." -VaultId $vault.ID

        $recoveryconfig = Get-AzRecoveryServicesBackupWorkloadRecoveryConfig -RecoveryPoint $latestRecoveryPoint -TargetItem $TargetInstance -AlternateWorkloadRestore -VaultId $vault.ID -TargetContainer $TargetContainer 

        $recoveryconfig.RestoredDBName = $NewDatabaseName
        $recoveryconfig.targetPhysicalPath[0].TargetPath = "$($DataPath)$($NewDatabaseName).mdf"
        $recoveryconfig.targetPhysicalPath[1].TargetPath = "$($LogPath)\$($NewDatabaseName).ldf"

        $RestoreJob = Restore-AzRecoveryServicesBackupItem -WLRecoveryConfig $recoveryconfig -VaultId $vault.ID 

        do {
            $RestoreJob = Get-AzRecoveryServicesBackupJob -JobId $RestoreJob.JobID -VaultId $vault.ID
            Write-Host "Restoring: $($RestoreJob.Status), $($RestoreJob.StartTime), $($RestoreJob.EndTime), $($RestoreJob.Duration), $($RestoreJob.Operation)"
            Start-Sleep -Seconds 5
        } while (($RestoreJob.Status -ne "Completed") -And ($RestoreJob.Status -ne "Failed"))

        return $RestoreJob.Status -eq "Completed"
    }
    catch {
        return $false
    }
}

已完成的C#初始化代码

// using Azure.Identity;
var options = new ClientCertificateCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
};

var clientCertCredential = new ClientCertificateCredential(
    tenantId, clientId, clientCertificate, options);

ArmClient client = new ArmClient(clientCertCredential);

SubscriptionResource subscription = client.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
ResourceGroupResource resourceGroup = await subscription.GetResourceGroups().GetAsync(resourceGroupName);

// 对应 Get-AzRecoveryServicesVault
RecoveryServicesVaultResource vault = await resourceGroup.GetRecoveryServicesVaultAsync(vaultName);

关键Cmdlet对应的C# SDK等效实现示例

1. 获取备份容器(Get-AzRecoveryServicesBackupContainer)

// 对应 Get-AzRecoveryServicesBackupContainer -ContainerType AzureVMAppContainer -VaultId $vault.ID -FriendlyName $HaNode.ToLower()
var backupContainers = vault.GetBackupContainersAsync(
    backupManagementType: BackupManagementType.AzureWorkload,
    containerType: ContainerType.AzureVMAppContainer);

var targetContainer = await backupContainers
    .FirstOrDefaultAsync(c => c.Properties.FriendlyName.Equals(HaNode.ToLower(), StringComparison.Ordinal));

2. 获取备份项(Get-AzRecoveryServicesBackupItem)

// 对应 Get-AzRecoveryServicesBackupItem -BackupManagementType AzureWorkload -WorkloadType MSSQL -Name "SQLDataBase;$SourceSqlAGName;$SourceDatabaseName" -VaultId $vault.ID -ProtectionStatus Healthy
var backupItems = vault.GetBackupItemsAsync(
    backupManagementType: BackupManagementType.AzureWorkload,
    workloadType: WorkloadType.MSSql);

var backupItem = await backupItems
    .FirstOrDefaultAsync(item => 
        item.Properties.Name == $"SQLDataBase;{SourceSqlAGName};{SourceDatabaseName}" 
        && item.Properties.ProtectionStatus == ProtectionStatus.Healthy);

3. 获取恢复点(Get-AzRecoveryServicesBackupRecoveryPoint)

// 对应 Get-AzRecoveryServicesBackupRecoveryPoint -Item $backupItem -VaultId $vault.ID -StartDate $startdate -EndDate $endDate
var startDate = DateTime.UtcNow.AddDays(-10);
var endDate = DateTime.UtcNow;

var recoveryPoints = backupItem.GetRecoveryPointsAsync(startDate, endDate);
var latestRecoveryPoint = await recoveryPoints
    .OrderByDescending(rp => rp.Properties.RecoveryPointTime)
    .FirstOrDefaultAsync();

4. 获取可保护项(Get-AzRecoveryServicesBackupProtectableItem)

// 对应 Get-AzRecoveryServicesBackupProtectableItem -WorkloadType MSSQL -ItemType SQLInstance -Name "sqlinstance;ota" -ServerName "servername..." -VaultId $vault.ID
var protectableItems = vault.GetProtectableItemsAsync(
    workloadType: WorkloadType.MSSql,
    itemType: ProtectableItemType.SqlInstance);

var targetInstance = await protectableItems
    .FirstOrDefaultAsync(item => 
        item.Properties.Name == "sqlinstance;ota" 
        && item.Properties.ServerName == "servername...");

5. 构建恢复配置并触发恢复作业

// 对应 Get-AzRecoveryServicesBackupWorkloadRecoveryConfig + Restore-AzRecoveryServicesBackupItem
var recoveryConfig = new WorkloadRestoreRequest
{
    TargetContainerId = targetContainer.Id,
    TargetProtectableItemId = targetInstance.Id,
    RecoveryPointId = latestRecoveryPoint.Id,
    RestoreType = RestoreType.AlternateWorkloadRestore,
    TargetDatabaseName = NewDatabaseName,
    TargetPhysicalPaths = new List<SQLDataDirectoryMapping>
    {
        new SQLDataDirectoryMapping
        {
            SourceLogicalName = "Data", // 根据实际数据库逻辑名称调整
            TargetPath = $"{DataPath}{NewDatabaseName}.mdf"
        },
        new SQLDataDirectoryMapping
        {
            SourceLogicalName = "Log", // 根据实际数据库逻辑名称调整
            TargetPath = $@"{LogPath}\{NewDatabaseName}.ldf"
        }
    }
};

// 触发恢复作业
var restoreOperation = await vault.RestoreBackupItemAsync(WaitUntil.Started, recoveryConfig);
var jobId = restoreOperation.Id.Split('/').Last();

// 轮询作业状态
BackupJobResource restoreJob;
do
{
    restoreJob = await vault.GetBackupJobAsync(jobId);
    Console.WriteLine($"Restoring: {restoreJob.Properties.Status}, {restoreJob.Properties.StartTime}, {restoreJob.Properties.EndTime}, {restoreJob.Properties.Duration}, {restoreJob.Properties.Operation}");
    await Task.Delay(TimeSpan.FromSeconds(5));
} while (restoreJob.Properties.Status != JobStatus.Completed && restoreJob.Properties.Status != JobStatus.Failed);

bool isSuccess = restoreJob.Properties.Status == JobStatus.Completed;

内容的提问来源于stack exchange,提问作者zu1b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:07:09