2019年3月31日 星期日

VMware PowerCLI:將 Storage 中所有的 .vmx file 註冊到 ESXi 主機

在計畫性停機、災難復原...等情況下,可能會有將多台 VM 移轉至備援資料中心的需求。除了選擇災難復原解決方案或是手動一台台復原之外,也可以透過 Script 的方式來做到。本文將說明如何透過 PowerCLI 將 Datastore 中所有 .vmx file 註冊到 ESXi 主機。

環境&情境說明

- 本文所使用的 PowerCLI 版本為 6.5 release 1 Build 4624819
- 模擬不影響正在運作的 VM 情況下,將 VM 註冊到另一個 Cluster 中的 ESXi。流程步驟為:首先透過 snapshot 建立一個新的 Volume,並掛載給 ESXi 主機,接著用 PowerCLI 指令 將 VM 都註冊到 ESXi 主機。同時,也將 VM 的網卡設定更換至封閉的 vSwitch 上的 Port Group。

PowerCLI 指令

以下針對所用到的指令說明,整體的邏輯是參考 【LucD Notes - VMX Raiders Revisited】,並依照自己的環境做些調整。
  •  用 Connect-VIServer 連線至 vCenter,接著輸入帳號密碼
  • 使用 Get-Cluster、Get-Datastore 取得 snapshot 建立出來的 Datastore 名稱 (也可以把相關的變數設定固定的值)
  • 使用 New-PSDrive 新增磁碟機 (路徑為Datastore完整路徑)

  • 搜尋 Datastore 路徑底下所有 .vmx file
  • 使用 New-VM 將 VM 註冊到 ESXi 主機上,並搭配 Set-VM 修改 VM 名稱;在本例為了想要讓 VM 隨機註冊到 Cluster 中的任一主機,所以並沒有把 $ESXi 變數寫死
  • VM 開機之前,先將 VM 的網卡設定改到封閉 vSwitch 上的 Port Group (如果是災難切換,就可以跳過此步驟)
  • 修改完後,就可以用 Start-VM 將 VM 都開機了。可能會跳出需要回答問題的錯誤,這是正常的
  • 這時候可以使用 Get-VMQuestion 來取得答案選項的參數
  • 因為我是複製過來的,所以參數值為 "button.uuid.copiedTheVM"

完整的 Script

#設定變數
$Cluster = "Secondary"
$DS = Get-Cluster -Name $Cluster | Get-Datastore | where{$_.Name -like "snap-*"}
$RootPath = ("vmstore:\Datacenter") + $DS.Name

#掛載磁碟機 路徑為RootPath
New-PSDrive -Name TgtDS -PSProvider VimDatastore -Root $RootPath | Out-Null

#搜尋磁碟機 .vmx file
$Unregistered = @( Get-ChildItem -Path TgtDS: -Recurse | where {$_.FolderPath -notmatch ".snapshot" -and $_.Name -like "*.vmx"} )

#卸載磁碟機
Remove-PSDrive -Name TgtDS

#將vm註冊至ESXi,同時修改VM名稱
foreach($VMXFile in $Unregistered){
$ESXi = Get-Cluster -Name $Cluster | Get-VMHost | Get-Random
New-VM -VMFilePath $VMXFile.DatastoreFullPath -VMHost $ESXi | %{Set-VM -VM $_ -Confirm:$False -Name ("DR-"+$_.Name)}
}

#修改VM網卡
$VMList = Get-VM -Datastore $DS.Name
foreach($vm in $VMList){
$adapterList = $vm | Get-NetworkAdapter
foreach($adapter in $adapterList){
if($Adapter.NetworkName -eq "255"){
Get-VM $vm.Name | Get-NetworkAdapter -Name $Adapter.Name | Set-NetworkAdapter -NetworkName "Test_255" -Confirm:$False
}elseif($Adapter.NetworkName -eq "28"){
Get-VM $vm.Name | Get-NetworkAdapter -Name $Adapter.Name | Set-NetworkAdapter -NetworkName "Test_28" -Confirm:$False
elseif($Adapter.NetworkName -eq "84"){
Get-VM $vm.Name | Get-NetworkAdapter -Name $Adapter.Name | Set-NetworkAdapter -NetworkName "Test_84" -Confirm:$False
}elseif($Adapter.NetworkName -eq "85"){
Get-VM $vm.Name | Get-NetworkAdapter -Name $Adapter.Name | Set-NetworkAdapter -NetworkName "Test_85" -Confirm:$False
}elseif($Adapter.NetworkName -eq "86"){
Get-VM $vm.Name | Get-NetworkAdapter -Name $Adapter.Name | Set-NetworkAdapter -NetworkName "Test_86" -Confirm:$False
}else{
Write-Host "NetworkAdapter not found"
}
}

#vm開機,回答VMQuestion
Get-VM -Datastore $ds | Start-VM | Get-VMQuestion | Set-VMQuestion -Options "button.uuid.copiedTheVM"

沒有留言:

張貼留言