Vmware-Vsphere

將 VM 快照複製到新的 VM 環境

  • March 4, 2022

我們有 2 個獨立的 VMWare 環境,一個是主環境,它在許多站點上擁有數百台虛擬機。另一種是安裝在一台伺服器上的小得多的,僅用於歸檔舊系統。

我想做的是對我們的一個實時 VM 的目前狀態進行快照,並使用它複製到另一個 VMWare 環境並在那裡創建一台新機器,將其用作該系統的存檔。

這可能/容易嗎?

Dang,如果您一直在使用 vSphere 6,則可以進行 vCenter 間複製並完成它。

無論如何,如果您使用 PowerCLI,這個任務在 5.5 中也不是特別難。

步驟如下:

  1. 拍攝 VM 的快照(使用 PowerCLI 或任何一個 GUI,都沒有關係)
  2. 使用這個方便的 PowerCLI將快照複製到新 VM:

New-VM -Name $CloneName -VM $SourceVM -Location $CloneFolder -Datastore $Datastore -ResourcePool $ResourcePool -VMHost $VMHost -LinkedClone -ReferenceSnapshot $Snapshot

您可以查看“New-VM”文件以了解所有選項的含義以及如何填充它們。

它們的關鍵是“-ReferenceSnapshot”選項。 3. 將閃亮的新 VM 導出到 OVF/OVA,或將文件夾從 DS 複製到網路上的某個位置 4. 將其導入其他 vCenter

我已經讓我的 IT 安全團隊請求一個正在執行的虛擬機的“取證”副本,包括記憶體快照,以便他們可以在存在病毒或某種違規的情況下進行一些調查。為了讓我的生活更輕鬆,我編寫了一個 PS 函式來完成所有繁重的工作。它只需要一個源 VM(按名稱或對象)和磁碟上的一個文件夾。它完成了其餘的工作。

Function ExportVM {
   Param(
   [parameter(Mandatory=$true)]
   [ValidateNotNullOrEmpty()]
   [PSObject]$SourceVM,

   [parameter(Mandatory=$true)]
   [ValidateNotNullOrEmpty()]
   [String]$DestinationPath
   )

   #Check if the destination path exists, bail out if it doesn't
   if ( -not (Test-path $DestinationPath -IsValid) ) {
       Write-Warning "Please provide a valid path for the exported VM"
       return
   }
   
   #Get the SourceVM, bail out if it fails
   if ($SourceVM.GetType().Name -eq "string"){
       try {
           $SourceVM = Get-VM $SourceVM -ErrorAction Stop
       }
       catch [Exception]{
           Write-Warning "VM $SourceVM does not exist"
           return
       }
   }
   elseif ($SourceVM -isnot [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl]){
       Write-Warning "You did not pass a string or a VM object for 'SourceVM'"
       Return
   }

   try {
       $DestinationPath = $DestinationPath + "\" + $SourceVM.Name

       #Setup the required compoments to compute an MD5 hash
       $algo = [System.Security.Cryptography.HashAlgorithm]::Create("MD5")
       $md5StringBuilder = New-Object System.Text.StringBuilder 50
       $ue = New-Object System.Text.UTF8Encoding

       #Define the snapshot name
       $SnapshotName = "IT-Security Export - " + (Get-Date -UFormat "%b-%d-%Y, %R")
       #Create the snapshot
       $Snapshot = New-Snapshot -VM $SourceVM -Name $SnapshotName -Description "Snapshot for IT-Security Forensic export" -Memory -Quiesce -Confirm:$false

       $Snapshot

       #Define variables needed to create the clone
       $CloneFolder = $SourceVM.Folder
       $Datastore = Get-Datastore -RelatedObject $SourceVM
       $ResourcePool = Get-ResourcePool -VM $SourceVM
       $VMHost = Get-VMHost -VM $SourceVM

       #Build a unique name for the cloned machine based on the snapshot name
       $algo.ComputeHash($ue.GetBytes($SnapshotName)) | % { [void] $md5StringBuilder.Append($_.ToString("x2")) }
       $CloneName = $SourceVM.Name +"_ITSecExport_" + $md5StringBuilder.ToString().SubString(0,15)

       #Clone the VM
       $CloneVM = New-VM -Name $CloneName -VM $SourceVM -Location $CloneFolder -Datastore $Datastore -ResourcePool $ResourcePool -VMHost $VMHost -LinkedClone -ReferenceSnapshot $Snapshot

       #Define the name of the PSDrive, based on the Datastore name
       $DSName = "ITSecExport_" + ($Datastore.name -replace "[^a-zA-Z0-9]","")
       #Check to see if it already exists, remove if it does
       if (Get-PSDrive | Where {$_.Name -like $DSName}) {
           Remove-PSDrive $DSName
       }
       #Add the new drive
       $PSDrive = New-PSDrive -Location $Datastore -Name $DSName -Scope Script -PSProvider VimDatastore -Root "\"

       #Define variables needed to copy the SourceVM's VMX and the snapshot's VMSN
       $SnapshotID = (Get-VM $SourceVM |Get-Snapshot | where {$_.Name -like $SnapshotName}).ExtensionData.ID
       $SourceVM_VMXPath = (Get-View $SourceVM).Config.Files.VmPathName.Split(" ")[1].replace("/","\")
       $SourceVM_VMSNPath = $SourceVM_VMXPath.Replace(".vmx", "-Snapshot" + $SnapshotID + ".vmsn")
       #$CloneVM_VMPath = (Get-View $CloneVM).Config.Files.VmPathName.Split(" ")[1].Split("/")[0]

       #Copy the VMSN and VMX
       Copy-DatastoreItem -Item ${DSName}:\$SourceVM_VMXPath -Destination $DestinationPath -Force
       Copy-DatastoreItem -Item ${DSName}:\$SourceVM_VMSNPath -Destination $DestinationPath -Force

       #Copy-DatastoreItem -Item ${DSName}:\$CloneVM_Path\* $DestinationPath"$CloneName" -Force -Recurse

       #Export the VM
       $CloneVM | Export-VApp -Destination $DestinationPath -Force

       #Clean up
       Remove-VM -DeletePermanently $CloneVM -Confirm:$false
       Remove-Snapshot -Snapshot $Snapshot -Confirm:$false
       Remove-PSDrive -Name $DSName
   }
   catch [Exception]{
       $ErrorMessage = $_.Exception.Message
       $FailedItem = $_.Exception.ItemName
       Write-Warning "Looks like we ran in to an error"
       Write-Warning "  $ErrorMessage"
       return
   }
}

引用自:https://serverfault.com/questions/704581