I need to storage vmotion a large number of VMs. They all need to go to one of 2 destination datastores. The maximum concurrent sVmotion operations to a single datastore is 8.
(This is an all flash array and can handle the load of lots of concurren svMotions)
I want my script to be able to select which datastore to move to based on which one has fewer svMotions already in progress.
This way I keep my concurrent jobs per datastore under 8 and lessen the load on each one.
how could I modify this script to find which destination datastore has the fewest existing vCenter svMotion tasks running on it and then select that one as the destination?
Also - since the maximum concurrent svmotions per ESXi host is 2, is there a way to detect if the host the VM is on is already running 2 vmotions, and if so, skip to the next VM?
get-vm | foreach {move-vm -vm $vm -Datastore $destinationDatastore -ErrorAction Stop -RunAsync}
Try something like this.
You will have to change the name of the datastorecluster and adapt the Get-VM to fit your own VM seletion criteria.
Also note that this only tries each VM once, when a VM is skipped, it will not be retried.
$maxEsx = 2
$tgtDatastoreCluster = 'DSC'
$dsNames = Get-DatastoreCluster -Name $tgtDatastoreCluster | Get-Datastore | select -ExpandProperty Name
foreach($vm in Get-VM){
$tasks = Get-Task -Status Running | where{$_.Name -eq 'RelocateVM_Task'}
$svMotions = foreach($task in $tasks){
$vInfo = Get-VIEvent -Start $task.StartTime | where{$_.ChainId -eq $task.ExtensionData.Info.EventChainId} |
where{$_ -is [VMware.Vim.VmBeingHotMigratedEvent]}
New-Object PSObject -Property @{
SrcDs = $vInfo.DS.Name
TgtDS = $vInfo.DestDatastore.Name
SrcEsx = $vInfo.Host.Name
DstEsx = $vInfo.DestHost.Name
}
}
$dsCount = foreach($dsName in $dsNames){
New-Object PSObject -Property @{
Name = $dsName
svMotionCount = ($svMotions | where{$_.TgtDS -eq $dsName}).Count
}
}
$leastBusyDS = $dsCount | Sort-Object -Property svMotionCount -Descending | select -First 1 -ExpandProperty Name
$skipVM = ($svMotions | where{$_.SrcEsx -eq $vm.VMHost.Name}).Count -ge $maxEsx
if(!$skipVM){
Move-VM -VM $vm -Datastore $leastBusyDS -RunAsync
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Try something like this.
You will have to change the name of the datastorecluster and adapt the Get-VM to fit your own VM seletion criteria.
Also note that this only tries each VM once, when a VM is skipped, it will not be retried.
$maxEsx = 2
$tgtDatastoreCluster = 'DSC'
$dsNames = Get-DatastoreCluster -Name $tgtDatastoreCluster | Get-Datastore | select -ExpandProperty Name
foreach($vm in Get-VM){
$tasks = Get-Task -Status Running | where{$_.Name -eq 'RelocateVM_Task'}
$svMotions = foreach($task in $tasks){
$vInfo = Get-VIEvent -Start $task.StartTime | where{$_.ChainId -eq $task.ExtensionData.Info.EventChainId} |
where{$_ -is [VMware.Vim.VmBeingHotMigratedEvent]}
New-Object PSObject -Property @{
SrcDs = $vInfo.DS.Name
TgtDS = $vInfo.DestDatastore.Name
SrcEsx = $vInfo.Host.Name
DstEsx = $vInfo.DestHost.Name
}
}
$dsCount = foreach($dsName in $dsNames){
New-Object PSObject -Property @{
Name = $dsName
svMotionCount = ($svMotions | where{$_.TgtDS -eq $dsName}).Count
}
}
$leastBusyDS = $dsCount | Sort-Object -Property svMotionCount -Descending | select -First 1 -ExpandProperty Name
$skipVM = ($svMotions | where{$_.SrcEsx -eq $vm.VMHost.Name}).Count -ge $maxEsx
if(!$skipVM){
Move-VM -VM $vm -Datastore $leastBusyDS -RunAsync
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Truly amazing -thanks again