PowershellスクリプトにてWindowsServerバックアップを行う

WindowsServer標準機能であるWindowsServerバックアップを利用し、Powershellスクリプトで稼働中サーバのシステムバックアップを取得する方法についてです。

1. 動作確認環境

2. 前提条件

  • バックアップ対象サーバに"WindowsServerバックアップ"の機能がインストールされていること。

WindowsServer2012であれば、以下の手順で機能を追加可能です。

  1. タスクバー等からサーバマネージャを起動。
  2. [管理] - [役割と機能の追加]を選択。
  3. [開始する前に]で[次へ]を押下。
  4. [インストールの種類]で"役割ベースまたは機能ベースのインストール"を選択し、[次へ]を押下。
  5. [サーバーの選択]で対象サーバを選択し、[次へ]を押下。
  6. [サーバーの役割]で[次へ]を押下(何も選択しない)。
  7. [機能]で[Windows Server バックアップ]を選択し、[次へ]を押下。

3. WindowsServerバックアップ機能の概要

今回実装するスクリプトではWindowsServerバックアップ機能を使用しますので、簡単に内容について復習しておきます。

(1) WindowsServerバックアップとは?
  • WindowsServer2008以降における標準バックアップツール(2003以前はNTBackup)
  • ボリュームシャドーコピーサービス(VSS)とブロックレベルのバックアップテクノロジにより、OS、ファイル、フォルダ、ボリュームのバックアップと回復を行う
  • 毎回完全バックアップを取得する以外に、初回のみ完全バックアップを取得し、後は増分バックアップを自動的に取得することも可能*1
  • バックアップ先として、内蔵・外部HDD、ネットワーク共有、光メディア(DVD等)、リムーバルメディア、WindowsAzureを指定可能(テープは不可)
  • バックアップ先ディスクはバックアップ専用として構成しても良いし、そうでなくとも良い*2
  • バックアップから特定の項目(ファイルやフォルダ)のみを復元することが可能
  • インストールメディア(DVD/ISO)を用いてバックアップからベアメタル回復が可能
(2) WindowsServer2012からサポートされた機能
  • バックアップファイルの形式がVHDからVHDXに変更
  • 2TBを超えるボリュームのバックアップをサポート
  • ファイルシステムとしてReFSをサポート(従来はNTFSのみ)
  • バックアップ先にWindows Azureを指定可能(その他に、内蔵・外部HDD、ネットワーク共有、光メディア(DVD等)、リムーバルメディアを指定可能)
  • Hyper-Vバックアップ機能を強化

4. 実現したいこと

今回実装するスクリプトでは、以下の要件を実現することとします。

  • 稼働中サーバのオンラインバックアップ(システム状態)を取得したい
  • 完全バックアップを1世代取得したい
  • バックアップ先はローカルディスクまたはネットワーク共有フォルダとしたい

5. バックアップ処理の流れ

今回実装するバックアップスクリプトの大まかな処理の流れは以下の通りです。

  1. バックアップポリシーの作成および設定
  2. バックアップの開始
  3. バックアップジョブの終了判定
  4. バックアップの結果判定
(1) バックアップポリシーの作成および設定

バックアップを開始する前に、まず「バックアップポリシー」を作成し、バックアップ対象や回復方法、バックアップ先などをポリシーとして指定する必要があります。今回は具体的に以下の手順でバックアップポリシーを作成および設定します。

  1. 空のバックアップポリシーを作成("New-WBPolicy")
  2. バックアップ対象として、「システム状態」を指定し、ポリシーに追加("Add-WBSystemState")
  3. 回復方法として、「ベアメタル回復」を指定し、ポリシーに追加("Add-WBBareMetalRecovery")
  4. バックアップ先として、「ローカルディスク」または「ネットワーク共有」を指定し、ポリシーに追加("New-WBBackupTarget", "Add-WBBackupTarget")
  5. VSSバックアップオプションとして「VSSコピー」を選択し、ポリシーに追加("Set-WBVssBackupOptions")

VSSでバックアップを取得する際の方法として、「VSSフルバックアップ」と「VSSコピーバックアップ」があります。これらの違いは、「バックアップ後にアプリケーションログを削除するかしないか」ということです。

ではアプリケーションログって何?って話ですが、具体的にはVSSに対応するアプリケーション(SQL ServerExchange Server)のトランザクションログ等を指しているとのことです。VSSフルバックアップを行うとバックアップ後にログは切り詰められ、VSSコピーバックアップではそのまま残る、という動作になります。

どう使い分けるのか?というと、もしサードパーティー製バックアップソフトとWindowsServerバックアップ機能を併用する場合、VSSフルバックアップを行うと、バックアップ後にログが削除されてしまうため、サードパーティー製バックアップソフトが差分または増分バックアップを取得するためにそれらのログに依存する場合、当然影響を受けてしまう、ということですね。

詳しくはTechNet Blogに記載があります。
http://blogs.technet.com/b/filecab/archive/2008/05/21/what-is-the-difference-between-vss-full-backup-and-vss-copy-backup-in-windows-server-2008.aspx

そもそもVSSって何?という方は、下記を参考にしてください。
https://msdn.microsoft.com/en-us/library/windows/desktop/bb968832%28v=vs.85%29.aspx

(2) バックアップの開始

上記(1)で作成したバックアップポリシーを使用して、バックアップを開始します。

今回はスクリプトを実行する度に1世代の完全バックアップを取得するため、バックアップ開始には"Start-WBBackup"コマンドレットを使用します。このコマンドレットは1回のみのバックアップ操作を行う際に用います。

コマンドレットの"-Policy"オプションの引数に設定済みのバックアップポリシーを指定します。また、今回は完全に非対話形式でバックアップを実行するため、確認プロンプトを表示しない"-Force"オプションと、バックアップ開始後即座に制御をPowershellに戻す"-Async"オプションも合わせて指定します。

また、バックアップジョブ終了判定のため、バックアップ開始直後に"Get-WBJob"コマンドレットを実行し、結果を取得しておきます。"Get-WBJob"コマンドレットはオプションなしで実行した場合、現在実行中のバックアップジョブの情報を取得できます。

(3) バックアップジョブの終了判定

"Start-WBBackup"で開始したバックアップはジョブとしてバックグラウンド処理されます。今回はバックアップ完了後に終了状態を判定するため、バックアップジョブの完了を待つ必要があります。

バックアップジョブの完了を判定するため、"Get-WBJob"コマンドレットを用いて、以下の条件を満たすかどうかを定期的に確認するようにします。

  • "Get-WBJob -Previous 1"(完了した前回のバックアップジョブ情報)の実行結果の"StartTime"と、上記(2)で取得した"Get-WBJob"の"StartTime"が一致する
(4) バックアップの結果判定

バックアップが完了したことを確認したら、バックアップが成功したか否かを判定します。

"Get-WBJob -Previous 1"(完了した前回のバックアップジョブ情報)の"HResult"が"0"であれば成功、それ以外であれば失敗となります。

6. スクリプト実装例

下記に実装例を示します。(エラー処理等は省略)

# バックアップイメージ格納先ボリューム
# バックアップイメージは"<DriveLetter>:\WindowsImageBackup\<hostname>"配下に格納される
$dst_path = "D:"

# バックアップポリシーの作成
$wb_policy = New-WBPolicy
# バックアップ元としてシステム状態をポリシーに設定
Add-WBSystemState -Policy $wb_policy
# 回復方法としてベアメタルバックアップをポリシーに設定
Add-WBBareMetalRecovery -Policy $wb_policy
# バックアップ先をポリシーに設定(ローカルディスクの場合)
Add-WBBackupTarget -Policy $wb_policy (New-WBBackupTarget -VolumePath $dst_path) -Force
# VSSバックアップオプションとしてVSSコピーバックアップを指定
Set-WBVssBackupOptions -Policy $wb_policy -VssCopyBackup

# バックアップ実行
Start-WBBackup -Policy $wb_policy -Force -Async
# バックアップジョブ開始時の状態を取得
$start_job_state = Get-WBJob

# 前回のバックアップジョブを取得
$last_job_state = Get-WBJob -Previous 1

# バックアップジョブが完了するまで待つ
while ($start_job_state.StartTime -ne $last_job_state.StartTime) {
    Start-Sleep -s 30
    $last_job_state = Get-WBJob -Previous 1
}

# バックアップ結果判定
if ($last_job_state.HResult -eq 0) {
    # バックアップジョブ正常終了
    exit 0
} else {
    # バックアップジョブ異常終了
    exit -1
}

参考(Get-WBJobの実行結果)

WindowsServerバックアップ中にGet-WBJobを実行すると、以下の様な結果が得られます。

PS > Get-WBJob


JobType          : Backup
StartTime        : 2015/03/22 18:26
EndTime          :
JobState         : Running
CurrentOperation : 2 個のうち 2 個目のボリューム (89%)。
HResult          : 0
DetailedHResult  : 0
ErrorDescription :
JobItems         : {VolumeList, SystemState, BareMetalRecovery}
VersionId        : 03/22/2015-09:26
SuccessLogPath   :
FailureLogPath   :

現在実行中のバックアップの進行状況が確認可能です。

また、バックアップ完了後に"Get-WBJob -Previous 1"を実行すると、以下の結果となります。

PS > Get-WBJob -Previous 1


JobType          : Backup
StartTime        : 2015/03/22 18:26
EndTime          : 2015/03/22 18:35
JobState         : Completed
CurrentOperation :
HResult          : 0
DetailedHResult  : 0
ErrorDescription :
JobItems         : {VolumeList, SystemState, BareMetalRecovery}
VersionId        : 03/22/2015-09:26
SuccessLogPath   : C:\Windows\Logs\WindowsServerBackup\Backup-22-03-2015_09-26-09.log
FailureLogPath   : C:\Windows\Logs\WindowsServerBackup\Backup_Error-22-03-2015_09-26-09.log

バックアップジョブ履歴が存在しない場合、上記結果は$nullとなり、何も表示されません。

*1:バックアップ先にネットワーク共有を指定した場合は世代管理不可

*2:2008ではバックアップ専用ディスクが必須だったが、2008R2から専用ディスクは不要