Home > Windows にまつわる e.t.c.

謎のスナップショット


Windows Server 2012 R2 で Windows Server Backup を仕込んでいると、なんかのはずみで Hyper-V VM に謎のスナップショットができます。

 

このスナップショットのおかげで、VM が使用する VHD サイズはどんどん肥大化します。(スナップショット後の VHD が差分ディスクになるので WU で上書きになったモジュール領域がリサイクルされない)

厄介なことに、僕が試した限りこのスナップショットはどうやっても削除できません。

仕方ないので、スナップショットをとって、そのスナップショットからエクスポートしてリカバリーすることにしました。(スナップショットからエクスポートすると、スナップショット時のエクスポートとなり、他のスナップショットは無視される)

GUI で処理してもいいのですが、1台あたりの処理時間が長いので、複数台処理は GUI でやってられません。
サクッと PowerShell で処理しちゃいましょう。

RecoveryVM.PS1

# リカバリーする VM 名
$VMNames = @"
MV01
MV02
MV03
MV04
MV05
"@

# ヒア文字列を文字列配列に変換
$VMNames = $VMNames.Replace("`r","")
$VMNames = $VMNames.Split("`n")

# ワークフォルダー(Export フォルダーと同じドライブに作ると move の高速処理ができる)
$WorkDir = "E:\Hyper-V\Work"

# Export フォルダー
$ExportDir = "E:\Hyper-V\Running"

if( Test-Path $WorkDir ){
    echo "$WorkDir があったので削除"
    rd $WorkDir -Recurse -Force
}

echo "$WorkDir 作成"
md $WorkDir

foreach($VMName in $VMNames){
    $VM = $null
    $VM = Get-VM $VMName
    if( $VM -eq $null ){
        echo "$VMName が存在しないので skip"
        continue
    }

    # 動いていたら止める
    $State = "Off"
    if( $VM.State -ne "Off" ){
        $State = "Running"
        echo "$VMName VM 停止"
        $VM | Stop-VM
    }

    echo "$VMName チェックポイント作成"
    $VM | Checkpoint-VM -SnapshotName $VMName

    echo "$VMName Export"
    $VM | Export-VMSnapshot -Name $VMName -Path $WorkDir

    echo "$VMName VM 削除"
    $VM | Remove-VM -Force

    # 古い Export フォルダーがあったら削除
    $OldDir = Join-Path E:\Hyper-V\Running $VMName
    if( Test-Path $OldDir ){
        echo "$VMName $OldDir 削除"
        rd $OldDir -Recurse -Force
    }

    echo "$VMName スナップショット移動"
    $SourceDir = Join-Path $WorkDir $VMName
    move $SourceDir $ExportDir

    echo "$VMName Import"
    $DestinationDir = Join-Path $ExportDir $VMName
    $DestinationDir = Join-Path $DestinationDir "Virtual Machines"
    $XML = Join-Path $DestinationDir "*.xml"
    $VMXML = dir $XML
    $VMXMLFullPath = $VMXML.FullName
    Import-VM -Path $VMXMLFullPath

    # 動いていたら起動
    if( $State -eq "Running"){
        echo "$VMName VM 起動"
        $VM = Get-VM $VMName
        $VM | Start-VM
    }
}

echo "$WorkDir 削除"
rd $WorkDir -Recurse -Force

 

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.