โดยปกติการ Backup VM บน VMware ก็สามารถทำได้หลายท่า แต่ส่วนใหญ่ที่นิยมทำกันก็คือการ Clone VM ด้วย PowerCLI Script แล้วตั้ง Schedule เอาไว้ หรือใช้ Software ซึ่งก็มีหลายเจ้าให้เลือกใช้ แต่ต้องเสียตังค์ เราจะมาพูดถึงการ Backup VM ด้วย Powershell Script บน Windows กัน
Backup Policy
ก่อนอื่นให้เรากำหนด Backup Policy กันก่อน โดยแบ่งความถี่ในการสำรองข้อมูล Backup Frequency เช่น รายวัน Daily, รายสัปดาห์ Weekly, รายเดือน Monthly จากนั้นก็กำหนด Data Retention ระยะเวลาของการเก็บไฟล์ เช่น Daily 7 วัน, Weekly 1 เดือน, Monthly 4 เดือน จะมีประโยชน์ตรงที่เวลาเราต้องการข้อมูลย้อนหลัง
Directory Structure
ต่อมาก็กำหนดโครงสร้างของ File และ Folder โดยจะประกอบไปด้วยโครงสร้างดังนี้
C:\powershell-script
├───Credential/
│ └───vcsa.lab.local.clixml
├───VM-List/
│ ├───Daily.txt
│ ├───Monthly.txt
│ └───Weekly.txt
├───VM-Log/
│ ├───Daily/
│ ├───Monthly/
│ └───Weekly/
└───VM-Script/
├───Backup-Daily.ps1
├───Backup-Monthly.ps1
├───Backup-Weekly.ps1
├───Configuration.ps1
├───Create-Credential.ps1
└───Delete.ps1
Clone VM vs Clone Template
การสำรองข้อมูลด้วยการ Clone VM เวลานำไปใช้งานเราสามารถ Rename VM แล้วสั่ง PowerOn ได้เลย แต่มันจะทำให้ Data Retention เราหายไป ซึ่งวิธีแก้คือการ Clone เป็น Template แทน แต่การ Clone เป็น Template จะติดปัญหาที่ไม่สามารถ Clone ไปเก็บข้าม Datacenter ได้ จึงต้องใช้วิธี Clone เป็น VM ก่อนแล้วค่อย Convert เป็น Template ทีหลัง ซึ่งก็มีข้อดีข้อเสียต่างกัน ใน Script ผมก็เขียนไว้ หากใครไม่ใช้ก็ Remark เอานะครับ แล้วไปแก้ไฟล์ Delete.ps1 ด้วย
Get Started
- ทำการสร้างไฟล์ Configuration.ps1
Import-Module VMware.VimAutomation.Core
# VMware Parameter
$Global:root = "C:\powershell-script\"
$Global:date = Get-Date -Format yyyyMMdd
$Global:server = 'vcsa.lab.local'
$Global:vmhost = '10.10.10.20'
$Global:datacenter = 'Datacenter'
$Global:cluster = 'Cluster'
$Global:resourcepool = 'Resourcepool'
$Global:datastore = 'Datastore'
$Global:folder_daily = 'Daily'
$Global:folder_weekly = 'Weekly'
$Global:folder_monthly = 'Monthly'
# Credential
$Global:logon = 'LAB\administrator'
$Global:credential = Import-clixml ($root + 'Credential\vcsa.lab.local.clixml')
$Global:path_credential = $root + 'Credential\vcsa.lab.local.clixml'
# VM-List
$Global:vm_daily = Get-Content ($root + 'VM-List\Daily.txt')
$Global:vm_weekly = Get-Content ($root + 'VM-List\Weekly.txt')
$Global:vm_monthly = Get-Content ($root + 'VM-List\Monthly.txt')
# VM-Log
$Global:path_log_daily = $root + 'VM-Log\Daily\Backup-Daily-' + $date + '.log'
$Global:path_log_weekly = $root + 'VM-Log\Weekly\Backup-Weekly-' + $date + '.log'
$Global:path_log_monthly = $root + 'VM-Log\Monthly\Backup-Monthly-' + $date + '.log'
# Data Retention
$Global:lastdate_daily = (Get-Date (Get-Date).AddDays(-7) -Format yyyyMMdd)
$Global:lastdate_weekly = (Get-Date (Get-Date).AddDays(-28) -Format yyyyMMdd)
$Global:lastdate_monthly = (Get-Date (Get-Date).AddMonths(-3) -Format yyyyMMdd)
- ทำการสร้างไฟล์ Create-Credential.ps1
. "$PSScriptRoot\Configuration.ps1"
Get-Credential –Credential $logon | Export-Clixml $path_credential
- ทำการสร้างไฟล์ Backup-Daily.ps1
. "$PSScriptRoot\Configuration.ps1"
Connect-VIServer -Server $server -Credential $credential
$vm = $vm_daily
$path = $path_log_daily
$folder = $folder_daily
$datastore = $datastore
foreach ($line in $vm) {
$name = 'Backup-Daily-' + $date + '-' + $line
$dsdc = Get-Datastore $datastore -Datacenter $datacenter
try {
$backup = New-VM -Name $name -VM $line -VMHost $vmhost -Datastore $dsdc -ResourcePool $resourcepool -Location $folder -ErrorAction Stop
$backup | Out-File $path -Append
Get-VM -Name $name | Set-VM -ToTemplate -Confirm:$false
$query = Get-VM -Name $line | select Name, VMHost, GuestId, NumCpu, MemoryMB -ErrorAction Stop
$query | Out-File $path -Append
} catch {
# $ErrorMessage = $_.Exception.Message
# $FailedItem = $_.Exception.ItemName
# $error += $line + "`r`n"
}
}
Disconnect-VIServer -Server $server -Confirm:$false
- ทำการสร้างไฟล์ Backup-Monthly.ps1
. "$PSScriptRoot\Configuration.ps1"
Connect-VIServer -Server $server -Credential $credential
$vm = $vm_monthly
$path = $path_log_monthly
$folder = $folder_monthly
$datastore = $datastore
foreach ($line in $vm) {
$name = 'Backup-Monthly-' + $date + '-' + $line
$dsdc = Get-Datastore $datastore -Datacenter $datacenter
try {
$backup = New-VM -Name $name -VM $line -VMHost $vmhost -Datastore $dsdc -ResourcePool $resourcepool -Location $folder -ErrorAction Stop
$backup | Out-File $path -Append
Get-VM -Name $name | Set-VM -ToTemplate -Confirm:$false
$query = Get-VM -Name $line | select Name, VMHost, GuestId, NumCpu, MemoryMB -ErrorAction Stop
$query | Out-File $path -Append
} catch {
# $ErrorMessage = $_.Exception.Message
# $FailedItem = $_.Exception.ItemName
# $error += $line + "`r`n"
}
}
Disconnect-VIServer -Server $server -Confirm:$false
- ทำการสร้างไฟล์ Backup-Weekly.ps1
. "$PSScriptRoot\Configuration.ps1"
Connect-VIServer -Server $server -Credential $credential
$vm = $vm_weekly
$path = $path_log_weekly
$folder = $folder_weekly
$datastore = $datastore
foreach ($line in $vm) {
$name = 'Backup-Weekly-' + $date + '-' + $line
$dsdc = Get-Datastore $datastore -Datacenter $datacenter
try {
$backup = New-VM -Name $name -VM $line -VMHost $vmhost -Datastore $dsdc -ResourcePool $resourcepool -Location $folder -ErrorAction Stop
$backup | Out-File $path -Append
Get-VM -Name $name | Set-VM -ToTemplate -Confirm:$false
$query = Get-VM -Name $line | select Name, VMHost, GuestId, NumCpu, MemoryMB -ErrorAction Stop
$query | Out-File $path -Append
} catch {
# $ErrorMessage = $_.Exception.Message
# $FailedItem = $_.Exception.ItemName
# $error += $line + "`r`n"
}
}
Disconnect-VIServer -Server $server -Confirm:$false
- ทำการสร้างไฟล์ Delete.ps1
. "$PSScriptRoot\Configuration.ps1"
Connect-VIServer -Server $server -Credential $credential
foreach ($line_d in $vm_daily) {
try {
$lastvm = 'Backup-Daily-' + $lastdate_daily + '-' + $line_d
#Remove-VM $lastvm -DeleteFromDisk -Confirm:$false -ErrorAction Stop
Remove-Template -Template $lastvm -DeleteFromDisk -Confirm:$false -ErrorAction Stop
} catch {
# $ErrorMessage = $_.Exception.Message
# $FailedItem = $_.Exception.ItemName
# $error += $line + "`r`n"
}
}
foreach ($line_w in $vm_weekly) {
try {
$lastvm = 'Backup-Weekly-' + $lastdate_weekly + '-' + $line_w
#Remove-VM $lastvm -DeleteFromDisk -Confirm:$false -ErrorAction Stop
Remove-Template -Template $lastvm -DeleteFromDisk -Confirm:$false -ErrorAction Stop
} catch {
# $ErrorMessage = $_.Exception.Message
# $FailedItem = $_.Exception.ItemName
# $error += $line + "`r`n"
}
}
foreach ($line_m in $vm_monthly) {
try {
$lastvm = 'Backup-Monthly-' + $lastdate_monthly + '-' + $line_m
#Remove-VM $lastvm -DeleteFromDisk -Confirm:$false -ErrorAction Stop
Remove-Template -Template $lastvm -DeleteFromDisk -Confirm:$false -ErrorAction Stop
} catch {
# $ErrorMessage = $_.Exception.Message
# $FailedItem = $_.Exception.ItemName
# $error += $line + "`r`n"
}
}
Disconnect-VIServer -Server $server -Confirm:$false
อ่านเพิ่มเติม : https://bit.ly/2TC5Isg
Leave a Reply