DevAdmin Blog

Blog di Ermanno Goletto (Microsoft MVP Directory Services - MCSE - MCSA - MCITP - MCTS)
posts - 1026, comments - 598, trackbacks - 8

My Links

News

Il blog si è trasferito al seguente link:

www.devadmin.it

Avatar

Visualizza il profilo di Ermanno Goletto su LinkedIn

Follow ermannog on Twitter


Il contenuto di questo blog e di ciascun post viene fornito “così come é”, senza garanzie, e non conferisce alcun diritto. Questo blog riporta il mio personale pensiero che non riflette necessariamente il pensiero del mio datore di lavoro.

Logo Creative Commons Deed


Logo SysAdmin.it SysAdmin.it Staff


Logo TechNet Forum TechNet Italia @ForumTechNetIt Follow TechNet Forum on Twitter


Logo MVP

Article Categories

Archives

Post Categories

Blogs

Friends

Knowledge Base

MVP Sites

Resources

Hyper-V backup di macchine virtuali

Per eseguire il backup di macchine virtuali in Hyper-V su Windows server 2008 R2 senza ricorrere a soluzioni a pagamento quali come ad esempio Microsoft System Center Data Protection Manager è possibile utilizzare due approcci.

Approccio 1: Utilizzo di Windows Backup

E’ possibile utilizzare Windows backup dalla parent partition per eseguire il backup delle VM in Hyper-V. Perchè Windows Backup possa eseguire il backup delle VM è necessario registrare il writer VSS HYPER-V Microsoft con Windows Server Backup impostando una chiave di registry come indicato in KB 958662: How to back up Hyper-V virtual machines from the parent partition on a Windows Server 2008-based computer by using Windows Server Backup.

L’utilizzo di questa metodologia di backup comporta le seguenti:

  • Le macchine virtuali che non hanno gli Integration Services installati rimarranno in stato salvato mentre viene creato lo snapshot VSS.
  • Le macchine virtuali che eseguono sistemi operativi che non supportano VSS, ad esempio Microsoft Windows 2000 o Windows XP, rimarranno in stato mentre viene creato lo snapshot VSS.
  • Le macchine virtuali che contengono i dischi dinamici devono essere sottoposti a backup in modalità non in linea.
  • Windows Server Backup non supporta il backup di macchine virtuali HYPER-V su volumi di cluster condiviso (volumi CSV).
  • Non è possibile ripristinare la singola VM con Windows Backup ma solo.
  • Le VM con due o più snapshot non verranno ripristinate (esiste comunque un workaround descritto nella KB 958662.

Approccio 2: Utilizzo di script Powershell

E’ possibile utilizzare la PowerShell management Library for Hyper-V gli script sviluppati da James O'Neill per realizzare uno script Powershell che arresti la VM, compatti i VHD, esporti la VM e avvii nuovamente la VM.

Di seguito riporto uno script che fa esattamente quanto descritto con la possibilità di mantenere un certo numero di backup e di gestire i log.

Per poter eseguire gli script PowerShell locali occorre impostare l’execution policy ad esempio su RemoteSigned con il seguente comando:

Set-ExecutionPolicy RemoteSigned

Di seguito lo script, nella sezione iniziale è possibile impostare le seguenti configurazioni:

  • Nome macchina virtuale
    ($vmName = "VMTest")
  • Path backup
    ($bkpPath = "F:\HyperV-Export")
  • Numero di backup da mantenere
    ($bkpCopiesRetained = 2)
  • Compressione VHD della VM prima dell’esportazione
    ($compressVHDs = $TRUE)
  • Timeout shutdown in secondi (vedi [Update 01])
    $timeoutShutdownVM = 300
  • Avvio della VM al termine del backup
    ($startVM = $TRUE)
  • Esecuzione dell’esportazione della VM
    ($exportVM = $TRUE)
  • Path dei file log
    ($logFilePath = $bkpPath)
  • Suffisso del nome dei file log
    ($logFileNameSuffix = "LogBackup")
  • Numero di file di log da mantenere
    ($logFilesRetained = 3)
  • Path del modulo powershell di Hyper-V della PowerShell management Library for Hyper-V
    ($pathPSModuleHyperv = "C:\Scripts\PSHyperv\HyperV" )

Per avviare lo script è possibile utilizzare il comando:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe C:\Scripts\BackupVMTest.ps1

Sorgente script BackupVMTest.ps1:

 

# *** Impostazioni ***
$vmName = "VMTest"
$bkpPath = "F:\HyperV-Export"
$bkpCopiesRetained = 2
$compressVHDs = $TRUE
$timeoutShutdownVM = 300
$startVM = $FALSE
$exportVM = $TRUE
$logFilePath = $bkpPath
$logFileNameSuffix = "LogBackup"
$logFilesRetained = 3
$pathPSModuleHyperv = "C:\Scripts\PSHyperv\HyperV"
# ************************


# *** Import modulo Hyper-V
Import-Module $pathPSModuleHyperv


# *** Inizializzazioni ***
$now = Get-Date
$expPathVM = $bkpPath + "\" + $vmName
$bkpPathVM = $expPathVM + "-" + $now.ToString("yyyy-MM-dd-HH-mm-ss")
$logFileNameBase = $logFilePath + "\" + $logFileNameSuffix + "-" + $vmName
$logFile = $logFileNameBase + "-" + $now.ToString("yyyy-MM-dd-HH-mm-ss") + ".txt"
# ************************


# *** Creazione Backup Path
if (!(Test-Path $bkpPath)){
    New-Item $bkpPath -type directory
}


# *** Creazione Log Path
if (!(Test-Path $logFilePath)){
    New-Item $logFilePath -type directory
}


# *** Avvio backup
(Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " Avvio Backup" | Out-File $logFile


# **** Shutdown virtual machines
if ((Test-VmHeartbeat $vmName -HeartBeatTimeOut 5).Status -eq "OK"){
    (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " Arresto VM " + $vmName | Out-File $logFile -append
    Invoke-VMShutdown $vmName -force wait | Out-File $logFile -append
}
else{
    (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " VM " + $vmName + " non attiva"| Out-File $logFile -append
}


# *** Compattamento VHD
if ($compressVHDs){
    Get-VMDisk $vmName | foreach {
        if ($_.DiskPath -ne $NULL) {
            if ($_.DiskPath.EndsWith(".iso") -eq $FALSE){
                (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " Compressione VHD " + $_.DiskPath | Out-File $logFile -append
                Compress-VHD $_.DiskPath -wait | Out-File $logFile -append
            }
        }
    }
}


# *** Export virtual machines
if ($exportVM){
    (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") +  " Esportazione VM " + $vmName | Out-File $logFile -append
    Export-vm $vmName $bkpPath -Wait –copystate | Out-File $logFile -append
}


# *** Avvio VM
if ($startVM){
    (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") +  " Avvio VM " + $vmName | Out-File $logFile -append
    Start-Vm $vmName -wait -HeartBeatTimeOut 300 | Out-File $logFile -append
}


# *** Rename directory esportazione
if (Test-Path ($expPathVM)){
    (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") +  " Rename directory esportazione" | Out-File $logFile -append
    Move-Item $expPathVM $bkpPathVM | Out-File $logFile -append
}


# *** Eliminazione backup obsoleti
$bkpFolders = Get-ChildItem $bkpPath | Where {$_.psIsContainer -eq $true -and $_.FullName -like ($expPathVM + "*")} | Sort $_.FullName

if ($bkpFolders.Count -gt $bkpCopiesRetained){
    for ($i = 1; $i -le $bkpFolders.Count - $bkpCopiesRetained; $i++) {
            (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " Eliminazione backup directory " + $bkpFolders[$i-1].FullName | Out-File $logFile -append
            Remove-Item $bkpFolders[$i-1].FullName -recurse | Out-File $logFile -append
        }
}


# *** Eliminazione log file obsoleti
$logFiles = Get-ChildItem $logFilePath | Where {$_.psIsContainer -eq $false -and $_.FullName -like ($logFileNameBase + "*")} | Sort $_.FullName

if ($logFiles.Count -gt $logFilesRetained){
    for ($i = 1; $i -le $logFiles.Count - $logFilesRetained; $i++) {
            (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " Eliminazione log file " + $logFiles[$i-1].FullName | Out-File $logFile -append
            Remove-Item $logFiles[$i-1].FullName | Out-File $logFile -append
        }
}


# *** Termine backup
(Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + " Backup terminato" | Out-File $logFile -append

[Update 01]

Con la versione R2 SP1 della PowerShell management Library for Hyper-V il wait dello shutdown sembra non funzionare (si veda l’issue  Invoke-VMShutdown issue in R2 SP1 version) quindi è necessario modificare la seguente riga:

Invoke-VMShutdown $vmName -force -wait | Out-File $logFile –append

come segue:

Invoke-VMShutdown $vmName -Force -ShutdownTimeOut $timeoutShutdownVM | Out-File $logFile –append

Print | posted on Thursday, June 17, 2010 3:17 PM |

Powered by:
Powered By Subtext Powered By ASP.NET