您可以自訂和使用下列範例指令碼,以複製任意數量的虛擬機器 (VM)。

若要複製和貼上不含分頁符號的指令碼內容,請使用本主題的 HTML 版本,您可以從 Horizon7 說明文件頁面取得,網址為 https://docs.vmware.com/tw/VMware-Horizon-7/index.html

指令碼輸入

此指令碼會讀取一個輸入檔,描述於用於部署 Linux 桌面平台的範例 PowerCLI 指令碼輸入檔。此指令碼也會互動地要求下列資訊:

  • vCenter Server 的 IP 位址
  • vCenter Server 的管理員登入名稱
  • vCenter Server 的管理員密碼
  • 複製類型,必須是「完整」
  • 是否停用 vSphere 虛擬機器主控台

指令碼內容

<#
Create Clones from a Master VM

The Tool supports creation of Full clone from Master VM.
#>
#------------------------- Functions -------------------------
function GetInput
{
    Param($prompt, $IsPassword = $false)
    $prompt = $prompt + ": "
    Write-Host $prompt -NoNewLine
    [Console]::ForegroundColor = "Blue"
    if ($IsPassword)
    {
        $input = Read-Host -AsSecureString
        $input = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($input))
    }
    else
    {
        $input = Read-Host
    }
    
    [Console]::ResetColor()
    return $input
}

function IsVMExists ()
{
    Param($VMExists)
	Write-Host "Checking if the VM $VMExists already Exists"
	[bool]$Exists = $false

	#Get all VMS and check if the VMs is already present in VC
	$listvm = Get-vm
	foreach ($lvm in $listvm)
	{
		if($VMExists -eq $lvm.Name )
		{
			$Exists = $true
		}
	}
	return $Exists
}
function Disable_VM_Console()
{
    Param($VMToDisableConsole)
    $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $extra = New-Object VMware.Vim.optionvalue
    $extra.Key="RemoteDisplay.maxConnections"
    $extra.Value="0"
    $vmConfigSpec.extraconfig += $extra
    $vm = Get-VM $VMToDisableConsole | Get-View
    $vm.ReconfigVM($vmConfigSpec)
}


function Delete_VM()
{
    Param($VMToDelete)
	Write-Host "Deleting VM $VMToDelete"
	Get-VM $VMToDelete | where { $_.PowerState –eq "PoweredOn" } | Stop-VM –confirm:$false
	Get-VM $VMToDelete | Remove-VM –DeleteFromDisk –confirm:$false
}

#------------------------- Main Script -------------------------

$vcAddress = GetInput -prompt "Your vCenter address" -IsPassword $false
$vcAdmin = GetInput -prompt "Your vCenter admin user name" -IsPassword $false
$vcPassword = GetInput -prompt "Your vCenter admin user password" -IsPassword $true
$cloneType = GetInput -prompt 'Clone Type ("full")' -IsPassword $false
$disableVMConsole = GetInput -prompt 'Disable vSphere VM Console ("yes" or "no", recommend "yes")' -IsPassword $false
"-----------------------------------------------------"
$csvFile = '.\CloneVMs.csv'

# Check that user passed only full clone
if (($CloneType.length >0) -and ($CloneType -ne "full"))
{
	write-host  -ForeGroundColor Red "Clone type supports only 'full' (case sensitive)"
	exit
}
if (($disableVMConsole.length >0) -and ($disableVMConsole -ne "yes" -or $disableVMConsole -ne "no"))
{
	write-host  -ForeGroundColor Red "Disable vSphere VM Console supports only 'yes' or 'no' (case sensitive)"
	exit
}

#check if file exists
if (!(Test-Path $csvFile))
{
	write-host  -ForeGroundColor Red "CSV File $CSVFile not found"
	exit
}

# Connect to the VC (Parameterize VC)
#Connect to vCenter
$VC_Conn_State = Connect-VIServer $vcAddress -user $vcAdmin -password $vcPassword
if([string]::IsNullOrEmpty($VC_Conn_State))
{
   Write-Host 'Exit since failed to login vCenter'
   exit
}
else
{
  Write-Host 'vCenter is connected'
}

#Read input CSV file
$csvData = Import-CSV $csvFile 
#$csvData = Import-CSV $csvFile -header("VMName","Parentvm","CustomSpec","Datastore","Host","FromSnapshot","DeleteIfPresent")
foreach ($line in $csvData)
{
    "`n-----------------------------------------------------"
    $VMName = $line.VMName
    write-host -ForeGroundColor Yellow "VM: $VMName`n"

    $destVMName=$line.VMName
    $srcVM = $line.Parentvm
	$cSpec = $line.CustomSpec
	$targetDSName = $line.Datastore
    $destHost = $line.Host
	$srcSnapshot = $line.FromSnapshot
	$deleteExisting = $line.DeleteIfPresent
	if (IsVMExists ($destVMName))
	{
		Write-Host "VM $destVMName Already Exists in VC $vcAddress"
		if($deleteExisting -eq "TRUE")
		{
			Delete_VM ($destVMName)
		}
		else
		{
			Write-Host "Skip clone for $destVMName"
            continue
		}
	}    
    $vm = get-vm $srcvm -ErrorAction Stop | get-view -ErrorAction Stop
	$cloneSpec = new-object VMware.VIM.VirtualMachineCloneSpec
	$cloneSpec.Location = new-object VMware.VIM.VirtualMachineRelocateSpec
	Write-Host "Using Datastore $targetDSName"
	$newDS = Get-Datastore $targetDSName | Get-View
	$CloneSpec.Location.Datastore =  $newDS.summary.Datastore
    Set-VM -vm $srcVM -snapshot (Get-Snapshot -vm $srcVM -Name $srcSnapshot) -confirm:$false
    $cloneSpec.Snapshot = $vm.Snapshot.CurrentSnapshot
	$cloneSpec.Location.Host = (get-vmhost -Name $destHost).Extensiondata.MoRef
	$CloneSpec.Location.Pool = (Get-ResourcePool -Name Resources -Location (Get-VMHost -Name $destHost)).Extensiondata.MoRef
    # Start the Clone task using the above parameters
	$task = $vm.CloneVM_Task($vm.parent, $destVMName, $cloneSpec)
    # Get the task object
	$task = Get-Task | where { $_.id -eq $task }
    #Wait for the taks to Complete
    Wait-Task -Task $task
    
    $newvm = Get-vm $destVMName
    $customSpec = Get-OSCustomizationSpec $cSpec
    Set-vm -OSCustomizationSpec $cSpec -vm $newvm -confirm:$false 
	if ($disableVMConsole -eq "yes")
	{
		Disable_VM_Console($destVMName)
	} 
    # Start the VM
	Start-VM $newvm
}
Disconnect-VIServer $vcAddress -Confirm:$false
exit

指令碼執行

下列訊息是來自指令碼的執行:

PowerCLI C:\scripts> .\CloneVMs.ps1
Your vCenter address: 10.117.44.17
Your vCenter admin user name: administrator
Your vCenter admin user password: *******
Clone Type<"Full"> : Full
Disable vSphere VM Console ("yes" or "no", recommend "yes") : yes

複製程序耗費的時間視桌面平台機器的數量而定,範圍從數分鐘到數小時不等。若要確認程序已完成,請從 vSphere Client,確定已將最新的桌面平台虛擬機器開機、具有自己的唯一主機名稱,而且 VMware Tools 正在執行。