VMware Cloud Community
Cc3216
Contributor
Contributor

limit vMotion operations by Hosts?

same as limit vMotion operations? , but wanna to limit the operation by Host , not by Task.

Can i set each host can ran 4 vMotion simultaneously?

e.g.:

Source Dest

A             X    << vMotion Batch1

A             X    << vMotion Batch1

A             Y    << vMotion Batch1

A             Y    << vMotion Batch1

A             Y    << vMotion Batch2

B             X    << vMotion Batch1

B             X    << vMotion Batch1

C             X    << vMotion Batch1

expect to see 4 x A Server vMotion + 2 x B Server vMotion + 1 x C Server vMotion can run together,  and the last A Server will wait for any other A server completed in Batch1 first.

Reply
0 Kudos
27 Replies
Cc3216
Contributor
Contributor

same as before all count are zero and got below exception

ErrorRecord                 : Cannot index into a null array.

WasThrownFromThrowStatement : False

Message                     : Cannot index into a null array.

Data                        : {System.Management.Automation.Interpreter.InterpretedFrameInfo}

InnerException              :

TargetSite                  : Void CheckActionPreference(System.Management.Automation.Language.FunctionContext, System.Exception)

StackTrace                  :    at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)

                                 at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)

                                 at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

                                 at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

HelpLink                    :

Source                      : System.Management.Automation

HResult                     : -2146233087

Reply
0 Kudos
LucD
Leadership
Leadership

Some extra debug lines.

PS: you can attach the output as a file, no need to paste it in the thread.
Whatever is easiest for you

$max = 2

$fileName = '.\input.csv'

$jobs = @{}

$vMotions = @{}


Import-Csv -Path $fileName -UseCulture | %{

  $vMotions.Add("$($_.SourceESX)-$($_.DestinationESX)-$($_.ServerName)",0)

}


$vMotionTab = @{}

while($vMotions.Count -gt 0){

  $remove = @()

  foreach($row in $vMotions.GetEnumerator()){

   Write-Host "Name: $($_.Name)"

   $src,$dst,$vmName = $row.Name.Split('-')

   Write-Host "Extracted - VM: $vmName  Src: $src  Dest: $dest"

   if(-not $vMotionTab.ContainsKey($src)){

   $vMotionTab.Add($src,0)

   Write-Host "Added $src to vMotionTab"

   }

   if(-not $vMotionTab.ContainsKey($dst)){

   $vMotionTab.Add($dst,0)

   Write-Host "Added $dst to vMotionTab"

   }

   Write-Host "Active for $src = $($vMotionTab[$src])"

   Write-Host "Active for $dst = $($vMotionTab[$dst])"

   if($vMotionTab[$src] -lt $max -and $vMotionTab[$dst] -lt $max){

   Try{

   Write-Host "Move $vmName frm $src to $dst"

   $cst = Move-VM -VM $vmName -Destination $dst -RunAsync -ErrorAction Stop

   Write-Host "Task: $($cst.Result.Guest.VM.ExtensionData.RecentTask[-1])"

   $jobs.Add($cst.Result.Guest.VM.ExtensionData.RecentTask[-1],$row.Name)

   $vMotionTab[$src] += 1

   $vMotionTab[$dst] += 1

   Write-Host "Active for $src = $($vMotionTab[$src])"

   Write-Host "Active for $dst = $($vMotionTab[$dst])"

   $remove += $row.Name

   }

   Catch{

   Write-Output $_.Exception | Format-List -Force

   Write-Output "vMotion failed for $vmName from $src to $dst"

   $remove += $row.Name

   }

   }

   Write-Host "Jobs count = $($jobs.Count)"

   if($jobs.Count -gt 0){

   Get-Task -Id $jobs.Result.Guest.VM.ExtensionData.RecentTask[-1] |

   where{$_.PercentComplete -eq 100} | %{

   Write-Host "Task: $($_.Name)  State: $($_.State)  Job: $($_.Id)"

   $src,$dst,$vmName = ($jobs[$_.Id]).Split('-')

   Write-Host "VM: $vmName  Src: $src  Dest: $dest "

   $vMotionTab[$src] -= 1

   $vMotionTab[$dst] -= 1

   $jobs.Remove($_.Id)

   }

   }

  }

  if($remove.Count -gt 0){

   $remove | %{

   $vMotions.Remove($_)

  }

  }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Cc3216
Contributor
Contributor

LucD,

FYI, result attached

Reply
0 Kudos
LucD
Leadership
Leadership

I have the impression the issue is related to the RecentTask property.

Can you have another run with this version (it has a few more debug lines in there)?

$max = 2

$fileName = '.\input.csv'

$jobs = @{}

$vMotions = @{}


Import-Csv -Path $fileName -UseCulture | %{

  $vMotions.Add("$($_.SourceESX)-$($_.DestinationESX)-$($_.ServerName)",0)

}


$vMotionTab = @{}

while($vMotions.Count -gt 0){

  $remove = @()

  foreach($row in $vMotions.GetEnumerator()){

   Write-Host "Name: $($_.Name)"

   $src,$dst,$vmName = $row.Name.Split('-')

   Write-Host "Extracted - VM: $vmName  Src: $src  Dest: $dst"

   if(-not $vMotionTab.ContainsKey($src)){

   $vMotionTab.Add($src,0)

   Write-Host "Added $src to vMotionTab"

   }

   if(-not $vMotionTab.ContainsKey($dst)){

   $vMotionTab.Add($dst,0)

   Write-Host "Added $dst to vMotionTab"

   }

   Write-Host "Active for $src = $($vMotionTab[$src])"

   Write-Host "Active for $dst = $($vMotionTab[$dst])"

   if($vMotionTab[$src] -lt $max -and $vMotionTab[$dst] -lt $max){

   Try{

   Write-Host "Move $vmName frm $src to $dst"

   $cst = Move-VM -VM $vmName -Destination $dst -RunAsync -ErrorAction Stop

   Write-Output $cst | Format-List -Force

   Write-Output $cst.Result.Guest.VM.ExtensionData.RecentTask | Format-List -Force

   Write-Host "Task: $($cst.Result.Guest.VM.ExtensionData.RecentTask[-1])"

   $jobs.Add($cst.Result.Guest.VM.ExtensionData.RecentTask[-1],$row.Name)

   $vMotionTab[$src] += 1

   $vMotionTab[$dst] += 1

   Write-Host "Active for $src = $($vMotionTab[$src])"

   Write-Host "Active for $dst = $($vMotionTab[$dst])"

   $remove += $row.Name

   }

   Catch{

   Write-Output $_.Exception | Format-List -Force

   Write-Output "vMotion failed for $vmName from $src to $dst"

   $remove += $row.Name

   }

   }

   Write-Host "Jobs count = $($jobs.Count)"

   if($jobs.Count -gt 0){

   Get-Task -Id $jobs.Result.Guest.VM.ExtensionData.RecentTask[-1] |

   where{$_.PercentComplete -eq 100} | %{

   Write-Host "Task: $($_.Name)  State: $($_.State)  Job: $($_.Id)"

   $src,$dst,$vmName = ($jobs[$_.Id]).Split('-')

   Write-Host "VM: $vmName  Src: $src  Dest: $dest "

   $vMotionTab[$src] -= 1

   $vMotionTab[$dst] -= 1

   $jobs.Remove($_.Id)

   }

   }

  }

  if($remove.Count -gt 0){

   $remove | %{

   $vMotions.Remove($_)

  }

  }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Cc3216
Contributor
Contributor

LucD, FYI

Reply
0 Kudos
LucD
Leadership
Leadership

Ok, now I know why the script doesn't work.

The Move-VM is handled by a so-called Client-Side Task, and the Task MoRef I'm using is only filled in when the vMotion has completed.

The script could wait, but that would result in only doing one vMotion at the time.

I'll have to rethink the logic.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Cc3216
Contributor
Contributor

Hi LucD,

is it possible no need to wait all first batch completed then trigger next batch? since the VM size are various, and the transaction time also

example: IF Server E (first batch) require 30mins for vMotion, all Second Batch Job need to wait it's completed first, can made it didn't wait?

what i can see the result right now:

ServerNameSourceESXDestinationESXAction
Server AesxAesxDFirst Batch Trigger
Server BesxAesxDneed to wait all First Batch Job Completed first.
Server CesxAesxDneed to wait all Second Batch Job Completed first. ( which mean need to wait other 8 Servers vMotion completed, then trigger Server C vMotion.
Server DesxBesxCFirst Batch Trigger
Server EesxBesxCneed to wait all First Batch Job Completed first.
Server FesxCesxBFirst Batch Trigger
Server GesxCesxBneed to wait all First Batch Job Completed first.
Server HesxDesxAFirst Batch Trigger
Server IesxDesxAneed to wait all First Batch Job Completed first.

btw :smileysilly: any idea for the Second query? lol  any idea to counting the ESXi node for source and destination

Reply
0 Kudos
LucD
Leadership
Leadership

I don't really see a solution at this time, due to the CST concept.
It could work if there are no other vMotions being triggered by other users or DRS, but that is not something I could easily accomplish in a script.

One could disable DRS temporarily and inform other users from starting vMotions, but that goes rather far I think.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos