Powershell for Windows Server Backup 

# 背景

Windows Server Backup（以下、WSB）機能はWindows Server 2008から搭載されており、Windows Server 2003以前のNT Backupから発展したMicrosoft社の製品技術です。
Windows Serverライセンスの範囲内で追加費用無く利用できるため、全国に展開したWindows Server約150台のシステムバックアップとして利用してきました。

WSBを利用する方法は次のとおりですが、Powershellでの利用にあたり、今回色々障害に至った（苦労させられた）ので、備忘録も兼ねて本投稿に至った次第です。

## WSBの利用方法

* GUI（wbadmin.msc）
* WBADMINコマンド（wbadmin.exe）
* Powershell（WindowsServerBackupモジュール）

## WindowsServerBackupモジュール

Windows Server 2016のWindowsServerBackupモジュールのコマンドレットは以下のとおりです。

```Get-Command -Module WindowsServerBackup
CommandType     Name
ーーーーーー
Alias           Get-WBVssBackupOptions
Alias           Set-WBVssBackupOptions
Cmdlet          Add-WBBackupTarget
Cmdlet          Add-WBBareMetalRecovery
Cmdlet          Add-WBFileSpec
Cmdlet          Add-WBSystemState
Cmdlet          Add-WBVirtualMachine
Cmdlet          Add-WBVolume
Cmdlet          Get-WBBackupSet
Cmdlet          Get-WBBackupTarget
Cmdlet          Get-WBBackupVolumeBrowsePath
Cmdlet          Get-WBBareMetalRecovery
Cmdlet          Get-WBDisk
Cmdlet          Get-WBFileSpec
Cmdlet          Get-WBJob
Cmdlet          Get-WBPerformanceConfiguration
Cmdlet          Get-WBPolicy
Cmdlet          Get-WBSchedule
Cmdlet          Get-WBSummary
Cmdlet          Get-WBSystemState
Cmdlet          Get-WBVirtualMachine
Cmdlet          Get-WBVolume
Cmdlet          Get-WBVssBackupOption
Cmdlet          New-WBBackupTarget
Cmdlet          New-WBFileSpec
Cmdlet          New-WBPolicy
Cmdlet          Remove-WBBackupSet
Cmdlet          Remove-WBBackupTarget
Cmdlet          Remove-WBBareMetalRecovery
Cmdlet          Remove-WBCatalog
Cmdlet          Remove-WBFileSpec
Cmdlet          Remove-WBPolicy
Cmdlet          Remove-WBSystemState
Cmdlet          Remove-WBVirtualMachine
Cmdlet          Remove-WBVolume
Cmdlet          Restore-WBCatalog
Cmdlet          Resume-WBBackup
Cmdlet          Resume-WBVolumeRecovery
Cmdlet          Set-WBPerformanceConfiguration
Cmdlet          Set-WBPolicy
Cmdlet          Set-WBSchedule
Cmdlet          Set-WBVssBackupOption
Cmdlet          Start-WBApplicationRecovery
Cmdlet          Start-WBBackup
Cmdlet          Start-WBFileRecovery
Cmdlet          Start-WBHyperVRecovery
Cmdlet          Start-WBSystemStateRecovery
Cmdlet          Start-WBVolumeRecovery
Cmdlet          Stop-WBJob```

# 基本的な使い方

PowershellでWSBの使い方は、GUI操作手順の一つずつのように次のとおりですが、対象オブジェクトを作りポリシーに追加していくのでステップ数は多くなります。

## バックアップ

1. WBポリシーを作成（New-WBPolicy）
2. バックアップ先オブジェクトを作成（New-WBBackupTarget）
3. バックアップ先オブジェクトをWBポリシーに追加（Add-WBBackupTarget）
4. バックアップ対象オブジェクトを作成（Get-WBVolume）
5. バックアップ対象オブジェクトをWBポリシーに追加（Add-WBVolume）
6. バックアップ実行（Start-WBBackup）
7. 実行結果確認（Get-WBJob -Previous 1）

## リストア

1. バックアップ元オブジェクトを作成（New-WBBackupTarget）
2. バックアップ元からバックアップセットを見つける（Get-WBBackupSet）
3. リストア実行（Start-WBxxxxxRecovery）注1
4. 実行結果確認（Get-WBJob -Previous 1）

<details><summary>  注1  xxxx: File / Volume / HyperV / SystemState</summary></details>

## 実行結果（WSBジョブ履歴）の確認

直前のWSBジョブ履歴（Get-WBJob -Previous 1）の開始日時を退避しておき、実行したWSBジョブ完了後、実行結果の確認のために使用します。

WSBジョブ履歴（実行結果）の確認すべき項目は次のとおりです。他のサイトではHRESULTだけの確認を説明されてますが、経験的にそれだけでは不十分でしたので、念には念を入れます。

1. StartTime（直前のジョブ以降である事）
2. JobType（[Backup | ApplicationRecovery | VolumeRecovery | FileRecovery]のいずれかである事）
3. JobState（Completedである事）
4. HRESULT（0である事）

ジョブ履歴の開始日時は「yyyy/mm/dd h:mm」形式の文字列であり。日付時刻型ではありません。
**また、日付はゼロ補完されますが、時刻はゼロ補完されないため、「2020/03/15 9:00」のように日付と時刻の間は空白が1個となります。もし、直前のWSBジョブ履歴が同日午前9時であり、午後2時に実行したバックアップの結果は「2020/03/15 14:00」となるので、単純に大小比較すると後の方が小さい（＝古い）ことになります。よって、［日付時刻］型への変換が必要です。**

**また、バックアップ等のコマンドレットが終了しても直ぐにWSBジョブ履歴が作られないので、10秒位してから結果を取るようにした方が良いです。**
また、経験的に、WSBの実行主体であるWBENGINE.exeが実行途中で異常終了した場合等、WSBジョブ履歴が記録されないこともあるので、必ず開始日付時刻等の確認が必要です。

# 具体的なスクリプト例

## システムのベアメタル・バックアップ

Windowsホストサーバのシステム状態とCドライブ、Fドライブをバックアップする。

```wbadmin start backup -backupTarget:W: -allCritical -include:F: -systemState``` 

![BMR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606736/46b7acc9-a918-f16d-4e17-747db71f014b.png)

+ WBバックアップポリシー作成

``` $wbpolicy = New-WBPolicy```

+ バックアップ先をWドライブに設定

```$target = New-WBBackupTarget -VolumePath W:```
```Add-WBBackupTarget -Policy $wbpolicy -Target $target```

+ ベアメタル回復のWBバックアップポリシーへの追加

``` Add-WBBareMetalRecovery -Policy $wbpolicy```

+ システム状態のWBバックアップポリシーへの追加

```Add-WBSystemState -Policy $wbpolicy```

+ FドライブのWBバックアップポリシーへの追加

```$volume = Get-WBVolume -VolumePath F:```
```Add-WBVolume -Policy $wbpolicy -Volume $volume```

ここまでで、WBバックアップポリシーは完成です。
続いて、バックアップ実行結果確認のために直前のWSBジョブ履歴の開始日時を退避します。

+ 直前のWSBジョブ履歴開始日時の退避

```$previous_starttime = (Get-WBJob -Previous 1).StartTime```

+ バックアップの実行

```Start-WBBackup -Policy $wbpolicy -Force```

+ 実行結果（WSBジョブ履歴）の取得

```Start-Sleep -Seconds 10```
```$wbstatus = Get-WBJob -previous 1```

+ WSBジョブ履歴（実行結果）の確認

WSBジョブ履歴の確認すべき項目は次のとおりです。

1. StartTime（**直近のジョブ以降**である事）
2. JobType（**Backup**である事）
3. JobState（**Completed**である事）
4. HRESULT（**0**である事）

```if ( `
([datetime]$wbstatus.StartTime -gt [datetime]$previous_starttime) `
-and ($wbstatus.JobType -eq "Backup") `
-and ($wbstatus.JobState -eq "Completed") `
-and ($wbstatus.HRESULT -eq 0) ) `
{echo "Backup Completed" } else {echo "Backup Failed"}```

## Hyper-V仮想マシンのバックアップ

Hyper-V上の仮想マシン（Win2016A）をWドライブにバックアップする。

```wbadmin start backup -backupTarget:W: -HyperV:Win2016A```

![HyperV.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606736/c8692700-1c9e-78c3-be84-ff3e94a11f3e.png)

+ WBバックアップポリシー作成

``` $wbpolicy = New-WBPolicy```

+ バックアップ先をWドライブに設定

```$target = New-WBBackupTarget -VolumePath W:```
```Add-WBBackupTarget -Policy $wbpolicy -Target $target```

+ 仮想マシン（Win2016A）のWBバックアップポリシーへの追加

```$vm = Get-WBVirtualMachine | ? VMName -Match "Win2016A"```
```Add-WBVirtualMachine -Policy $wbpolicy -VirtualMachine $VM```

**ここで注意すべきことは、Get-VMで仮想マシンを確認できても、WSBの Get-WBVirtualMachineで確認できるとは限らないことです。**
**経験的にチェックポイント（スナップショット）が作成されている仮想マシンを、Get-WBVirtualMachineで取得できませんでした。事前にチェックポイントを削除しておいてください。**

ここまでで、WBバックアップポリシーは完成です。
続いて、バックアップ実行結果確認のために直前のWSBジョブ履歴の開始日時を退避します。

+ 直前のWSBジョブ履歴の開始日時の退避

```$previous_starttime = (Get-WBJob -Previous 1).StartTime```

+ バックアップの実行

```Start-WBBackup -Policy $wbpolicy -Force```

+ 実行結果（WSBジョブ履歴）の取得

```Start-Sleep -Seconds 10```
```$wbstatus = Get-WBJob -previous 1```

+ WSBジョブ履歴（実行結果）の確認

WSBジョブ履歴の確認すべき項目は次のとおりです。

1. StartTime（**直近のジョブ以降**である事）
2. JobType（**Backup**である事）
3. JobState（**Completed**である事）
4. HRESULT（**0**である事）

```if ( `
([datetime]$wbstatus.StartTime -gt [datetime]$previous_starttime) `
-and ($wbstatus.JobType -eq "Backup") `
-and ($wbstatus.JobState -eq "Completed") `
-and ($wbstatus.HRESULT -eq 0) ) `
{echo "Backup Completed" } else {echo "Backup Failed"}```

## ボリュームのバックアップ

特定のボリューム（Fドライブ）をWドライブにバックアップする。

```wbadmin start backup -backupTarget:W: -include:F: ```

![Volume.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606736/727b1f7c-4412-f219-45df-703ee7b7b208.png)

+ WBバックアップポリシー作成

``` $wbpolicy = New-WBPolicy```

+ バックアップ先をWドライブに設定

```$target = New-WBBackupTarget -VolumePath W:```
```Add-WBBackupTarget -Policy $wbpolicy -Target $target```

+ FドライブのWBバックアップポリシーへの追加

```$volume = Get-WBVolume -VolumePath F:```
```Add-WBVolume -Policy $wbpolicy -Volume $volume```

ここまでで、WBバックアップポリシーは完成です。

+ 直前のWSBジョブ履歴の開始日時の退避

```$previous_starttime = (Get-WBJob -Previous 1).StartTime```

+ バックアップの実行

```Start-WBBackup -Policy $wbpolicy -Force```

+ 実行結果（WSBジョブ履歴）の取得

```Start-Sleep -Seconds 10```
```$wbstatus = Get-WBJob -previous 1```

+ WSBジョブ履歴（実行結果）の確認

```if ( `
([datetime]$wbstatus.StartTime -gt [datetime]$previous_starttime) `
-and ($wbstatus.JobType -eq "Backup") `
-and ($wbstatus.JobState -eq "Completed") `
-and ($wbstatus.HRESULT -eq 0) ) `
{echo "Backup Completed" } else {echo "Backup Failed"}```

## BMR（Bare Metal Recovery）リストア

通常、Windowsホストサーバのシステムリストアは、インストールメディアからの回復しかできないので説明は割愛します。

## Hyper-V仮想マシンのリストア

WドライブにバックアップしたHyper-V仮想マシン（Win2016A）を元の場所（F:\Hyper-V）にリストアします。

```wbadmin start recovery -backupTarget:W: -version:03/15/2020-01:23 -itemtype:Hyperv -items:Win2016A -recoveryTarget:F:\Hyper-V```

![VMrestore.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606736/0b738bfd-8245-aef2-8283-54185c62f2d4.png)

+ バックアップ元をWドライブに設定

```$target = New-WBBackupTarget -VolumePath W:```

+ バックアップ元からバックアップセットを検索

```$backupset = Get-WBBackupSet -BackupTarget $target -MachineName $env:ComputerName | ? Application -Match "Win2016A"```

+ 最新のバックアップセットを確認

複数バックアップ世代が作られていたら、直近のものを採用します。

```$bs = $backupset.count - 1```
```$ap = $backupset[$bs].Application | ? Identifier -match "HyperV"```
```$cp = $ap.Component | ? VMName -match "Win2016A"```

+ 直前のWSBジョブ履歴の開始日時の退避

```$previous_starttime = (Get-WBJob -Previous 1).StartTime```

+ リストアの実行

```Start-WBHyperVRecovery -BackupSet $backupset[$bs] -VMInBackup $cp -TargetPath F:\Hyper-V -Force```

+ 実行結果（WSBジョブ履歴）の取得

```Start-Sleep -Seconds 10```
```$wbstatus = Get-WBJob -previous 1```

+ WSBジョブ履歴（実行結果）の確認

1. StartTime（直前のジョブ以降である事）
2. JobType（**ApplicationRecovery**である事）
3. JobState（Completedである事）
4. HRESULT（0である事）

```if ( `
([datetime]$wbstatus.StartTime -gt [datetime]$previous_starttime) `
-and ($wbstatus.JobType -eq "ApplicationRecovery") `
-and ($wbstatus.JobState -eq "Completed") `
-and ($wbstatus.HRESULT -eq 0) ) `
{echo "Backup Completed" } else {echo "Backup Failed"}```

## ボリュームリストア

Wドライブにバックアップしたボリューム（Fドライブ）を元の場所にリストアします。

```wbadmin start recovery -version:03/15/2020-01:23 -backupTarget:W: -itemtype:Volume -items:F:```

![restorevol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606736/90cbc93a-1c14-f8c9-f58a-4fe93656d58d.png)

+ バックアップ元をWドライブに設定

```$target = New-WBBackupTarget -VolumePath W:```

+ バックアップ元からバックアップセットを検索

```$backupset = Get-WBBackupSet -BackupTarget $target -MachineName $env:ComputerName | ? Volume -Match "F:"```

+ 最新のバックアップセットを確認

複数バックアップ世代が作られていたら、直近のものを採用します。

```$bs = $backupset.count - 1```
```$vl = $backupset[$bs].Volume | ? {$_.MountPath -match "F:"}```

+ 直前のWSBジョブ履歴の開始日時の退避

```$previous_starttime = (Get-WBJob -Previous 1).StartTime```

+ リストアの実行

```Start-WBVolumeRecovery -BackupSet $backupset[$bs] -VolumeInBackup $vl -Force```

+ 実行結果（WSBジョブ履歴）の取得

```Start-Sleep -Seconds 10```
```$wbstatus = Get-WBJob -previous 1```

+ WSBジョブ履歴（実行結果）の確認

1. StartTime（直前のジョブ以降である事）
2. JobType（**VolumeRecovery**である事）
3. JobState（Completedである事）
4. HRESULT（0である事）

```if ( `
([datetime]$wbstatus.StartTime -gt [datetime]$previous_starttime) `
-and ($wbstatus.JobType -eq "VolumeRecovery") `
-and ($wbstatus.JobState -eq "Completed") `
-and ($wbstatus.HRESULT -eq 0) ) `
{echo "Backup Completed" } else {echo "Backup Failed"}```

# 最後に

何かのお役に立てば幸いです。

以上