Sie können das im Folgenden aufgeführte Beispielskript für das Klonen einer beliebigen Anzahl virtueller Maschinen (VMs) anpassen und anwenden.

Für das Kopieren und Einfügen des Skriptinhalts ohne Seitenumbrüche verwenden Sie die HTML-Version dieses Themas, die auf der Dokumentationsseite von Horizon 7 unter https://www.vmware.com/support/pubs/view_pubs.html verfügbar ist.

Skripteingabe

Dieses Skript liest eine Eingabedatei, die im Kapitel Eingabedatei für die PowerCLI-Beispielskripts zur Bereitstellung von Linux-Desktops beschrieben ist. Es gibt verschiedene Eingabeaufforderungen für die folgenden Informationen aus:

  • IP-Adresse von vCenter Server

  • Anmeldename des Administrators für vCenter Server

  • Kennwort des Administrators für vCenter Server

  • Klontyp (verknüpft oder vollständig)

  • Deaktivierung der vSphere-VM-Konsole

Skriptinhalt

<#
Create Clones from a Master VM

The Tool supports creation of Full clone and linked clone from Master VM.
The parent VM is required for the linked-clone to work and the parent VMs file cannot be renamed or moved.
#>
#------------------------- 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 ("linked" or "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 linked or full clone
if (($CloneType.length >0) -and ($CloneType -ne "linked" -or $CloneType -ne "full"))
{
	write-host  -ForeGroundColor Red "Clone type supports only 'linked' or '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
	if ($CloneType -eq "linked")
	{
		$cloneSpec.Location.DiskMoveType = [VMware.VIM.VirtualMachineRelocateDiskMoveOptions]::createNewChildDiskBacking
	}    
	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

Skriptausführung

Die folgenden Meldungen resultieren aus einer Ausführung des Skripts:

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<"linked" or "Full"> : linked
Disable vSphere VM Console ("yes" or "no", recommend "yes") : yes

Der für den Klonvorgang notwendige Zeitraum ist abhängig von der Anzahl der Desktop-Maschinen und kann von mehreren Minuten bis zu Stunden reichen. Um sicherzustellen, dass der Vorgang abgeschlossen ist, vergewissern Sie sich im vSphere Client, dass die letzte virtuelle Desktop-Maschine eingeschaltet ist und über ihren eigenen eindeutigen Hostnamen verfügt und dass VMware Tools ausgeführt wird.