PowerShell による Azure Site Recovery のサポートを開始
このポストは、11 月 5 日に投稿された Introducing PowerShell support for Azure Site Recovery の翻訳です。
先日は、Azure Site Recovery で管理される 2 つの Hyper-V サイト間での復旧の PowerShell によるサポートを発表しました。ASR のコマンドレットは Virtual Machines の保護の有効化や、Virtual Machines の復旧処理または Virtual Machines を含む復旧プランの実行に使用できます。PowerShell によるサポートが追加されたことで、管理者が ASR サービスに対してスクリプトを作成したり、ホスティング サービス プロバイダーが災害復旧を提供するために自社のセルフサービス ポータルを拡張したりできるようになりました。
PowerShell による ASR のサポートは、Azure PowerShell の機能として、2014 年 10 月リリースの Azure PowerShell で提供されています。Azure PowerShell を既にご利用の場合は、バージョン 0.8.10 (英語) 以降にアップグレードする必要があります。Azure PowerShell のセットアップと構成が完了すると、利用可能なすべての Azure Site Recovery コマンドレット (英語) の一覧を確認できます。
ASR コンテナーのコンテキストのセットアップ
Azure Site Recovery コマンドレットの利用を開始するには、ASR コンテナーの情報で PowerShell 実行空間コンテキストをセットアップする必要があります。セットアップの際は、SCVMM のセットアップおよびコンテナーへの登録にも使用する登録キー ファイルを Azure 管理ポータルからダウンロードします。コンテキストのセットアップが完了すると、そのコンテキスト内で他のコマンドレットが実行されます。
登録済みの SCVMM サーバーの一覧表示
SCVMM サーバーのセットアップと Azure Site Recovery の登録が完了したら、Get-AzureSiteRecoveryServer (英語) コマンドレットを使用して SCVMM サーバーを表示できます。このコマンドレットでは、通信のハートビート、プロバイダーのバージョン、サーバー情報が出力され、ASR のサーバー稼働状況を監視することができます。
SCVMM クラウドの一覧表示
Azure Site Recovery では、Virtual Machines のスケール管理に SCVMM クラウドを使用しています。SCVMM での構成が完了したら、Get-AzureSiteRecoveryProtectionContainer (英語) を使用して、ASR によって検出された SCVMM クラウドの情報を表示できます。SCVMM のクラウド名またはクラウド ID を使用することで、表示するクラウドを絞り込むことができます。
Virtual Machines の一覧表示
保護コンテナーのコンテキスト内の Virtual Machines を表示することができます。ASR によって検出された SCVMM の Virtual Machines の情報を表示するには、Get-AzureSiteRecoveryProtectionEntity (英語) を使用します。保護コンテナーと同様に、SCVMM の VM ID または VM 名を使用すると、保護エンティティを絞り込むことができます。
Virtual Machines の保護
保護エンティティの一覧には、保護されている Virtual Machines と保護されていない Virtual Machines の両方が表示されます。Set-AzureSiteRecoveryProtectionEntity (英語) を使用すると、保護エンティティに対する保護管理を実行できます。これは、Azure Site Recovery のジョブを返す非同期処理です。また、Get-AzureSiteRecoveryJob (英語) を使用すれば、完了までのジョブの状態を追跡することができます。
以下は、この処理を実行する簡単なスニペットのサンプルです。
param
(
[parameter(Mandatory=$TRUE, HelpMessage="SCVMM Cloud Name")]
[ValidateNotNullOrEmpty()]
[string] $ProtectedContainerName,
[parameter(Mandatory=$TRUE, HelpMessage="List of VM names in the SCVMM cloud")]
[ValidateNotNullOrEmpty()]
[string[]] $VMList,
[parameter(Mandatory=$TRUE, HelpMessage="Protection State")]
[ValidateNotNullOrEmpty()]
[ValidateSet('ENABLE','DISABLE')]
[string] $ProtectionState
)
$ProtectedContainers = Get-AzureSiteRecoveryProtectionContainer | %{ $_.Name }
if(!$ProtectedContainers.Contains($ProtectedContainerName))
{
Write-Error "PROTECTED CONTAINER $CloudName NOT FOUND IN ASR"
return;
}
$ASRProtectedContainer = Get-AzureSiteRecoveryProtectionContainer -Name $ProtectedContainerName
Write-Output "ProtectedContainer " $ASRProtectedContainer
$JobsList = $VMList | %{
Write-Host "Starting $ProtectionState Protections on $_";
Get-AzureSiteRecoveryProtectionEntity -Name $_ -ProtectionContainer $ASRProtectedContainer | Set-AzureSiteRecoveryProtectionEntity -Protection $ProtectionState -WaitForCompletion
}
$hasFailed = $FALSE
foreach($Job in $JobsList)
{
$JobDetails = Get-AzureSiteRecoveryJob -Job $Job
if($JobDetails.Errors.Count -ne 0)
{
$hasFailed = $TRUE
Write-Host "JobID $Job.Id Failed"
foreach($JobError in $JobDetails.Errors)
{
Write-Host $JobError.ServiceErrorDetails
Write-Host $JobError.ProviderErrorDetails
Write-Host $JobError
}
Write-Host `n
}
}
Write-Host "PROPERTIES AFTER $ProtectionState DR OPERATION"
$VMList | %{ Get-AzureSiteRecoveryProtectionEntity -Name $_ -ProtectionContainer $ASRProtectedContainer }
if(!$hasFailed)
{
Write-Host "ENABLE DR OF ALL VMs COMPLETED SUCCESSFULLY"
}
復旧プランの作成と管理
Virtual Machines の保護を有効化したら、復旧プランを作成します。復旧プランでは、フェールオーバーおよび復旧を実行するために Virtual Machines をグループにまとめ、そのグループにフェールオーバーを実行する順序を指定します。Azure Site Recovery コマンドレットを使用して、Azure 管理ポータルで作成された既存の復旧プランを XML ファイル形式でダウンロードできます。この復旧プランの XML ファイルを利用して、新しい復旧プランを作成するか、既存の復旧プランを更新します。
以下は、復旧プラン管理コマンドレットの一覧です。
復旧プランの XML ファイルは次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<RecoveryPlan Id="1077cccd-e483-4320-bbcd-b04ca39a7015" Name="Contoso" PrimaryServerId="4c6e08af-7a59-4749-9ccd-0ea089ad264c"
SecondaryServerId="fc769e95-24cc-41e2-919e-1e25b2c5d50a" Description="" Version="V2014_07">
<Actions />
<ActionGroups>
<ShutdownAllActionGroup Id="ShutdownAllActionGroup">
<PreActionSequence />
<PostActionSequence />
</ShutdownAllActionGroup>
<FailoverAllActionGroup Id="FailoverAllActionGroup">
<PreActionSequence />
<PostActionSequence />
</FailoverAllActionGroup>
<BootActionGroup Id="DefaultActionGroup">
<PreActionSequence />
<PostActionSequence />
<ProtectionEntity PrimaryProtectionEntityId="aa4718c1-19c2-4c44-b749-3b87a5ed4954" />
<ProtectionEntity PrimaryProtectionEntityId="981dab28-644d-4cca-aea7-b65123eb5ee3" />
</BootActionGroup>
<BootActionGroup Id="Group2">
<PreActionSequence />
<PostActionSequence />
<ProtectionEntity PrimaryProtectionEntityId="7f24915d-5415-4d7a-86fe-6beef5b8acfd" />
<ProtectionEntity PrimaryProtectionEntityId="050414cf-03b0-4d2c-bb63-0993c047d658" />
<ProtectionEntity PrimaryProtectionEntityId="be96b86f-0257-42ce-8fe7-c627cfb90410" />
</BootActionGroup>
</ActionGroups>
<ActionGroupSequence>
<ActionGroup Id="ShutdownAllActionGroup" ActionId="ShutdownAllActionGroup" Before="FailoverAllActionGroup" />
<ActionGroup Id="FailoverAllActionGroup" ActionId="FailoverAllActionGroup" After="ShutdownAllActionGroup" Before="DefaultActionGroup" />
<ActionGroup Id="DefaultActionGroup" ActionId="DefaultActionGroup" After="FailoverAllActionGroup" Before="864672ba-0c94-4cc7-b7f0-c3d202c3aaeb" />
<ActionGroup Id="864672ba-0c94-4cc7-b7f0-c3d202c3aaeb" ActionId="Group2" After="DefaultActionGroup" />
</ActionGroupSequence>
</RecoveryPlan>
フェールオーバー
Azure Site Recovery では、テスト、計画内、計画外という 3 種類のフェールオーバーをサポートしています。いずれのフェールオーバー処理も、個別の Virtual Machines と復旧プランの両方でサポートされています。これらの機能が、PowerShell コマンドレットでも利用できるようになりました。ASR のフェールオーバーは非同期処理のため、これらのコマンドレットを実行すると Azure Site Recovery のジョブが返されます。Get-AzureSiteRecoveryJob (英語) を使用すれば、完了までのジョブの状態を追跡することができます。
以下は、この処理を実行する簡単なスニペットのサンプルです。
param
(
[parameter(Mandatory=$FALSE, HelpMessage="Name of the RP")]
[ValidateNotNullOrEmpty()]
[string] $RPName,
[parameter(Mandatory=$TRUE, HelpMessage="Failover Type")]
[ValidateNotNullOrEmpty()]
[ValidateSet('PLANNED','UNPLANNED', 'TEST')]
[string] $FailoverType,
[parameter(Mandatory=$TRUE, HelpMessage="Failover direction")]
[ValidateNotNullOrEmpty()]
[ValidateSet('PrimaryToRecovery','RecoveryToPrimary')]
[string] $FailoverDirection,
[parameter(Mandatory=$TRUE, HelpMessage="Should do commit on the RP after failover")]
[ValidateNotNullOrEmpty()]
[bool] $ShouldCommit,
[parameter(Mandatory=$TRUE, HelpMessage="Should do reverse replicate on the RP after commit")]
[ValidateNotNullOrEmpty()]
[bool] $ShouldReverseReplicate
)
##
## このルーチンでは、ジョブにエラーがないかどうかをチェックする
##
function WaitForJobCompletionAndCheck-JobErrors([string] $JobId)
{
$IsCompleted = $false
while(!$IsCompleted)
{
$Job = Get-AzureSiteRecoveryJob -Id $JobId
if($Job.Status -eq "Succeeded")
{
$IsCompleted = $true
Write-Output "Job with Id $JobId executed successfully."
return
}
if($job.Status -eq "Failed")
{
$IsCompleted = $true;
Write-Output "The Job Id $JobId has failed in execution"
}
if(!$IsCompleted -eq "Suspended" )
{
Resume-AzureSiteRecoveryJob -Job $Job
}
else
{
Write-Output "The job is still in progress"
Start-Sleep -s 15
}
}
$hasFailed = $false
$JobDetails = Get-AzureSiteRecoveryJob -Id $JobId
if($JobDetails.Errors.Count -ne 0)
{
$hasFailed = $true
Write-Error "JobID $JobId Failed"
foreach($JobError in $JobDetails.Errors)
{
Write-Error $JobError.ServiceErrorDetails
Write-Error $JobError.ProviderErrorDetails
}
}
}
$RecoveryPlans = Get-AzureSiteRecoveryRecoveryPlan | %{ $_.Name }
if(!$RecoveryPlans.Contains($RPName))
{
Write-Error "RECOVERY PLAN $RPName NOT FOUND IN ASR"
return;
}
$RecoveryPlanObject = Get-AzureSiteRecoveryRecoveryPlan -Name $RPName
Write-Output "RECOVERY PLAN DETAILS : "
Write-Output $RecoveryPlanObject
Write-Output "Starting RP $FailoverType Failover of $RPName :";
if($FailoverType.ToUpper() -eq "PLANNED")
{
$Job = Start-AzureSiteRecoveryPlannedFailoverJob -RecoveryPlan $RecoveryPlanObject -Direction $FailoverDirection
}
elseif($FailoverType.ToUpper() -eq "UNPLANNED")
{
$Job = Start-AzureSiteRecoveryUnplannedFailoverJob -RecoveryPlan $RecoveryPlanObject -Direction $FailoverDirection
}
elseif($FailoverType.ToUpper() -eq "TEST")
{
$Job = Start-AzureSiteRecoveryTestFailoverJob -RecoveryPlan $RecoveryPlanObject -Direction $FailoverDirection
}
else
{
Write-Error "Invalid RP Failover Type - $FailoverType"
}
WaitForJobCompletionAndCheck-JobErrors $Job.ID
if($ShouldCommit)
{
Write-Output "Starting RP Commit Failover for $RPName";
$RecoveryPlanObject = Get-AzureSiteRecoveryRecoveryPlan -Name $RPName
Write-Output $RecoveryPlanObject
$JobsList = Start-AzureSiteRecoveryCommitFailoverJob -RecoveryPlan $RecoveryPlanObject -Direction $FailoverDirection
WaitForJobCompletionAndCheck-JobErrors $Job.ID
}
if($ShouldReverseReplicate)
{
Write-Output "Starting RP Reverse Replication for $RPName";
$RecoveryPlanObject = Get-AzureSiteRecoveryRecoveryPlan -Name $RPName
Write-Output $RecoveryPlanObject
$JobsList = Update-AzureSiteRecoveryProtectionDirection -RecoveryPlan $RecoveryPlanObject -Direction $FailoverDirection
WaitForJobCompletionAndCheck-JobErrors $Job.ID
}
$RecoveryPlanObject = Get-AzureSiteRecoveryRecoveryPlan -Name $RPName
Write-Output $RecoveryPlanObject