VMware Cloud Community
TheVMinator
Expert
Expert
Jump to solution

Automate selection of svMotion Target Datastore based on existing tasks

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}

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

View solution in original post

0 Kudos
2 Replies
LucD
Leadership
Leadership
Jump to solution

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

0 Kudos
TheVMinator
Expert
Expert
Jump to solution

Truly amazing  -thanks again

0 Kudos