以PowerShell指令碼進行VM的Clone備份

以PowerShell指令碼進行VM的Clone備份

一、緣起

1、專業的VM線上備份軟體每套都不便宜,不是以CPU計價,就是以台數計價。若以公司全部ESX主機來算,挺貴的。

2、在與主管討論後,採取折衷方案,將目前虛擬機分為兩大類。

A類備份週期比較短的,每天備份一次,服務為線上交易類為主,有類似SQL高度交易的程序。

B類備份週期較長。一周甚至一個月備份一次都可以。如Printer Server、Terminal Server之類的。

3、然後將A類虛擬機,集中於兩台伺服器上,共四顆CPU。因此備份軟體先以備份此兩台,四顆CPU為主。

4、其餘伺服器上的虛擬機,先以Clone的方式複製一份出來,由於Clone出來的虛擬機為關機狀態,因此透過網路的方式,下載到網路分享的路徑。以達到備份目的。週期以一周為主。

5、Clone雖然可以透過vCenter排程的方式進行,但是下載不行。如果可以將一連串動作,以指令排程的方式進行,就可以減輕管理員的負擔。

二、程式碼

這是PowerShell程式。


#--------- Function - dumpvm() - Clone VM ------------
Function dumpvm( $vm , $cloneName ){
	$cloneFolder = $vm.Parent
	$cloneSpec = New-Object VMWare.Vim.VirtualMachineCloneSpec
	$cloneSpec.Location = New-Object VMWare.Vim.VirtualMachineRelocateSpec
	$cloneSpec.Location.Datastore = ( Get-Datastore -VM $vm.Name | Get-View ).MoRef
	$clonevm = Get-VM -Name $cloneName #嘗試取得舊的clone
	if( $clonevm -eq $null ){
		Write-Host $clonevm " 不存在"
	}else{
		# 如果有舊的clone就殺掉
		Write-Host  "有舊的 " $clonevm " 存在,嘗試刪除"
		Remove-VM -DeleteFromDisk:$true -VM $clonevm -Confirm:$false
	}
	$cloneSpec.Snapshot = $vm.Snapshot.CurrentSnapshot	
	$cloneSpec.Location.Transform = [VMware.Vim.VirtualMachineRelocateTransformation]::sparse 
	#Clone VM 給備分用
	$vm.CloneVM( $cloneFolder , $cloneName , $cloneSpec  )
}
#--------- Function - backupvm() - Copy VM to CIFS Location ------------
Function backupvm( $vm , $cloneName , $destRootPathStr ){
	#拷貝 Clone 的備分到網路路徑
	$ds = Get-Datastore -VM $vm.Name -Name "Storage1"
	New-PSDrive -Name myds -PSProvider vimdatastore -Root "\" -location $ds	
	#確認備份路徑是否存在
	$destDir = New-Object System.IO.DirectoryInfo( $destRootPathStr+"\"+$cloneName )
	if ( !$destDir.Exists ) {
		#不存在就建立
		$rootPath = New-Object System.IO.DirectoryInfo( $destRootPathStr )
		#建子目錄
		$rootPath.CreateSubdirectory( $cloneName )
	}
	$destFullPath = $destRootPathStr+"\"+$cloneName
	New-PSDrive -Name dest -PSProvider Filesystem -Root $destFullPath
	#拷貝 Clone 的 VM 過去
	Copy-DatastoreItem myds:\$cloneName\* -Destination "dest:\"
	#拷貝完畢 刪除clone
	#嘗試重新取得clone
	$clonevm = Get-VM -Name $cloneName 
	if( $clonevm -eq $null ){
		Write-Host $clonevm " 不存在"
	}else{
		# 如果有clone就殺掉
		Write-Host "拷貝完畢刪除 " $clonevm
		Remove-VM -DeleteFromDisk:$true -VM $clonevm -Confirm:$false
	}
}
Add-PSSnapin VMWare.VimAutomation.Core
#讀入清單
$backuplists = Import-Csv "backuplists.csv"
Write-Host $backuplists.Count
#接上VC
Connect-VIServer -Server "192.168.1.66" -User "Domain\User" -Password "password
for ($backuploop = 0; $backuploop -lt $backuplists.count ; $backuploop++) {
	#要被備份的VM
	$vm = Get-VM -Name $backuplists[$backuploop].VMName | Get-View
	#準備要Clone到VM的名稱
	$cloneName = "clone-"+$vm.Name
	#備份主路徑
	$destRootPathStr = $backuplists[$backuploop].backupPath
	dumpvm $vm $cloneName
	backupvm $vm $cloneName $destRootPathStr	
}
#中斷VC連接
Disconnect-VIServer -Confirm:$false

 

 

 

 

三、程式碼流程說明

前提有架設vCenter,因此程式碼會連入vCenter(以下簡稱VC)進行操作,故有些指令是VC獨有的。如果是ESX就應該使用New-VM的方式做,而不是用CloneVM。

1、準備一個CSV檔,程式會由CSV檔,讀入要備份的VM名稱,及要備份到的主路徑(網路共享路徑也可以)。

2、連入VC

3、根據VM名稱,取得VM。

4、定義Clone的VM名稱。( 這裡一概以 『 clone-VM原來名稱 』作為Clone產生VM的名稱 )

5、Clone VM ( 由 dumpvm函式負責 )

6、拷貝Clone完的 VM 到網路上。(由 backupvm 函式負責)

7、關閉VC連接。

dumpvm函式

1、CloneVM必須具備3個參數。

$vm.CloneVM_Task( $cloneFolder, $cloneName, $cloneSpec )

cloneName

就是Clone完的VM名稱。這裡一概以 『 clone-VM原來名稱 』作為Clone產生VM的名稱。

cloneFolder

必須指定Clone到哪個目的資料夾,如果我們希望放在與目前的VM相同位置底下,只要設定給這個變數為目前VM的『parent』值即可。

cloneSpec

這是一個有趣的參數,其他雜七雜八的參數都在這。其引用的物件命名空間來自於『 Vmware.Vim.VirtualMachineCloneSpec 』。因此必須使用New-Object引用。另外還必須建立來自『 VMWare.Vim.VirtualMachineRelocateSpec 』的物件,這是為了指定 『 $cloneSpec.Location 』下面相關屬性。比如:Target host、datastore、cluster、resource pool之類。但不是全部都要設,視情況而定。在這裡我們只針對下列幾個項目設定

Datastore

指定與來源VM相同的儲存裝置。

Transform

VMware.Vim.VirtualMachineRelocateTransformation 只有兩個值。『 sparse 』或『 flat 』。『 sparse 』表示Thin provisioned,屬於thin disk。『 flat 』相反,建立的是thick disk。至於Thin或Thick的定義及區別,另參照VMWare相關技術文章,在此不贅述。

2、$cloneSpec.Snapshot

一般而言,我們Clone時,大部分希望是以VM目前的狀態為主。當然也可以透過CloneVM 的API控制,使Clone的對象是之前的Snapshop。如果這地方不特別指定,就以 current state 為主。如果要更精確的話,應該在CloneVM動作之前,先進行一次Snapshop動作,然後指定該Snapshop為Clone的版本。

3、中間有一段判別式,如果有相同名稱的Clone存在的話,則刪除之,再進行Clone。

以PowerGUI觀察cloneSpec的相關屬性

$cloneSpec.Location

image

 

backupvm函式

1、兩個重點,從哪裡來,拷貝到哪裡去。

2、New-PSDrive會建立與資料存放區中任一位置 (例如網路磁碟機、本機電腦上的目錄或登錄機碼) 對應或關聯的 Windows PowerShell 磁碟機。vimdatastore 代表磁碟類型為VMWare Datastore。Filesystem本機目錄或網路磁碟機都是用這個。

3、以Copy-DatastoreItem方法,將VM資料夾拷貝到網路上備份。

四、排程執行

使用排程工具,執行內容指令如下

powershell [指令檔完整路徑]

例如:

powershell C:\Scripts\

五、後記

1、程式碼中間有一段為嘗試抓取以Clone-XXXXX為名的VM,以便偵知是否已有同名的VM存在,決定是否直接Clone或先刪除舊的Clone VM。若無抓到同名的Clone VM,會有錯誤訊息,不過測試結果並不影響後續作業,個人因此不特別處理。可以用偵錯或乾脆拿掉這段,以避免礙眼。

2、Clone + Copy的方式極為耗時,且因為拷貝出來的VM檔案,脫離VMFS格式,檔案會與原先設定硬碟大小相同,不再支持Thin格式。因次備份空間應以VM的硬碟加總大小,在多加一些迴轉空間,以避免失敗。同時因為備分時間不算短,如過公司VM挺多的時候,最好還是要分批處理,個人實作時,以一周為周期,星期五晚上開始做,每周做5-6個VM,下周換另一批。

3、這種方式並不能取代較為專業的備份軟體,因為這些軟體大多針對備份最佳化,支持壓縮、去除重複數據,且速度也較快。同時高交易服務性質的VM,仍應當交給專業備份軟體處理。這種方式可以做為另一種保險方式。