Even if your ESX hosts can run a large number of VMs, they may not be able to power them all on simultaneously. Boot storming your virtual infrastructure can cause problems — among other things, if your VMs’ guest OS boots too slowly, errors can occur in the guest (e.g. Windows services can fail).

When creating linked clones, you can set cloneSpec.powerOn to true in order for linked clones to be powered on immediately upon creation, but if you issue too large a number of linked clone tasks at the same time using CloneVM_Task, you may experience such issues. You should therefore throttle the rapid creation of linked clones.

To limit the concurrency of linked clone creation, you can use CloneVM_Task to create a small batch of clones and then wait on those tasks to finish before continuing. You can use the wait-task cmdlet to wait until a set of tasks is complete. The following example creates 20 clones, 5 at a time, from the VM named “source_vm”. The linked clones are named “linked_clone_1” to “linked_clone_20”. You can write something similar if you are just interested in powering on existing VMs in batches.

 
$vm = Get-VM "source_vm" | Get-View
$clonePrefix = "linked_clone_"
$numClones = 20
$concurrentClones = 5

$cloneFolder = $vm.parent

$cloneSpec = new-object Vmware.Vim.VirtualMachineCloneSpec
$cloneSpec.Snapshot = $vm.Snapshot.CurrentSnapshot

$cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec
$cloneSpec.Location.DiskMoveType = [Vmware.Vim.VirtualMachineRelocateDiskMoveOptions]::createNewChildDiskBacking

#To power on each clone immediately after it is created:
#$cloneSpec.powerOn = $true

$i = 1
while ($i -le $numClones) {
   $taskViewArray = @()
   foreach ($j in 1..$concurrentClones) {
      $taskViewArray += $vm.CloneVM_Task( $cloneFolder, $clonePrefix+$i, $cloneSpec )
      $i++
   }
   $taskArray = $taskViewArray | Get-VIObjectByVIView
   Wait-Task $taskArray
}