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.
From where do the vMotions get triggered?
Is there an input file?
The reason for asking;
if the script would be waiting for source A to go below 4 before starting the next one,
the vMotions for source B and C should continue I assume.
I was thinking starting separate background jobs for each source VMhost.
Than you could just use the script you pointed to for each of the sources.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
thanks for yr quick reply
From where do the vMotions get triggered?
Is there an input file?
[Reply: Yup, from a CSV file to store all kind of info.]
if the script would be waiting for source A to go below 4 before starting the next one,
the vMotions for source B and C should continue I assume.
[Reply: yes, i assume the B & C should continue simultaneous with 4 x Server A]
I was thinking starting separate background jobs for each source VMhost.
Than you could just use the script you pointed to for each of the sources.
[Reply: how to get the host from Relocate_Task? and control it's maximum thread? i hv struggle for it for a long time ]
What is in that CSV? The VM's name I assume?
From the Get-VM we can get the VMHost on which the VM is running.
That should allow us to make groups based on the source (Source A,B,C...)
Each group could now be started as a background job (original script you pointed to) with Start-Job.
How is the destination for the vMotions determined?
Are all VMs going to the same targert VMHost?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
the csv will look like that, hope u understand
ServerName SourceESX & DestinationESX
A esxA esxC
B esxA esxC
C esxA esxC
D esxA esxC
E esxA esxC
F esxB esxC
G esxB esxC
H esxC esxD
Try something like this.
You need to connect to the vCenter before running this script
$script = {
param(
[int]$maxParallel,
[PSObject[]]$rows,
[string]$vcId
)
Connect-VIServer -Session $vcId
$rows | %{
Move-VM -VM $_.ServerName -Destination $_.DestinationESX -RunAsync
while((Get-Task -Status Running | where{$_.Name -eq 'RelocateVM_Task'}).Count -gt $maxParallel){
sleep 5
}
}
}
$max = 4
$fileName = '.\input.csv'
$jobs = @()
Import-Csv -Path $fileName -UseCulture | Group-Object -Property SourceEsx | %{
$jobs += (Start-Job -ScriptBlock $script -ArgumentList $max,$_.Group,$global:DefaultVIServer.SessionId)
}
Wait-Job -Job $jobs.Id
Receive-Job -Job $jobs.Id
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Awesome LucD, it's amazing.
but i observe a problem? if all CSV server are in Same host (eg. Host A)
and i set Parallel with 4 and Maxhost 2, then i assume all Host A vMotion should run 2 by 2, since MaxHost is 2.
however come up it ran 3 by 3 simultaneously, not by 2, any trick on it?
Not sure I'm following here :smileyconfused:
What is Parallel and MaxHost?
If all VMs are located on the same source ESXi, there will only be 1 background job.
And that job will allow $Max vMotions in parallel.
If the vSphere environment limits the parallel vMotions as well, then, if that number is lower than $Max, you will be limited by that imposed limit of course.
Is the system imposed maximum of parallel vMotions number what you are looking for?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
Sorry to make u confuse, but the result i got is like below
using ESXi 6.0 with default config
when [int]$maxpallael=8, $max=2
All SourceESX are same host
However the result is 3 vMotion Running simultaneously, instead of 2 , instead of 8, any idea why 3 ??
Where do you use
[int]$maxpallael=8, $max=2
Perhaps attach the complete script as you are running it?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
just like this LucD,
$script = {
param(
[int]$maxParallel=5,
[PSObject[]]$rows,
[string]$vcId
)
Connect-VIServer -Session $vcId
$rows | %{
Move-VM -VM $_.ServerName -Destination $_.DestinationESX -RunAsync
while((Get-Task -Status Running | where{$_.Name -eq 'RelocateVM_Task'}).Count -gt $maxParallel){
sleep 5
}
}
}
$max = 2
$fileName = '.\input.csv'
$jobs = @()
Import-Csv -Path $fileName -UseCulture | Group-Object -Property SourceEsx | %{
$jobs += (Start-Job -ScriptBlock $script -ArgumentList$max,$_.Group,$global:DefaultVIServer.SessionId)
}
Wait-Job -Job $jobs.Id
Receive-Job -Job $jobs.Id
Ok, I think I got it now.
Try swapping the Move-VM after the While-loop, and change the comparison operator to -ge
Like this
$script = {
param(
[int]$maxParallel,
[PSObject[]]$rows,
[string]$vcId
)
Connect-VIServer -Session $vcId
$rows | %{
while((Get-Task -Status Running | where{$_.Name -eq 'RelocateVM_Task'}).Count -ge $maxParallel){
sleep 5
}
Move-VM -VM $_.ServerName -Destination $_.DestinationESX -RunAsync
}
}
$max = 2
$fileName = '.\input.csv'
$jobs = @()
Import-Csv -Path $fileName -UseCulture | Group-Object -Property SourceEsx | %{
$jobs += (Start-Job -ScriptBlock $script -ArgumentList $max,$_.Group,$global:DefaultVIServer.SessionId)
}
Wait-Job -Job $jobs.Id
Receive-Job -Job $jobs.Id
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
is it possible set the limit not only on Source, but also the dest?
e.g.: take ServerC as example, and set each esx limit is 2
Since esxA have 2 Session running ( esxA>esxB & esxC>esxA), which reach the max limit
then ServerC will wait..... wait for either one session complete first.
ServerName | SourceESX | DestinationESX | Action | Count |
Server A | esxA | esxB | Proceed vMotion | esxA: 1, esxB: 1 |
Server B | esxC | esxA | Proceed vMotion | esxA: 2, esxB: 1, esxC:1 |
Server C | esxA | esxC | STOP & Wait since esxA Session > 2 | |
Server D | esxB | esxD | Proceed vMotion | esxA: 2, esxB: 2, esxC:1, esxD:1 |
Server E | esxB | esxC | STOP & Wait since esxB Session > 2 | |
Server F | esxB | esxD | STOP & Wait since esxB Session > 2 | |
Server G | esxD | esxA | STOP & Wait since esxA Session > 2 | |
Server H | esxE | esxC | Proceed vMotion | esxA: 2, esxB: 2, esxC:1, esxD:1, esxE:1 |
i tried to add DestESX in group object, but it doesn't match the result i want
Group-Object -Property SourceEsx DestEsx
Since you are counting the ESXi node for source and destination, that requires a different logic.
Try something like this
$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()){
$src,$dst,$vmName = $row.Name.Split('-')
if(-not $vMotionTab.ContainsKey($src)){
$vMotionTab.Add($src,0)
}
if(-not $vMotionTab.ContainsKey($dst)){
$vMotionTab.Add($dst,0)
}
if($vMotionTab[$src] -lt $max -and $vMotionTab[$dst] -lt $max){
Try{
$cst = Move-VM -VM $vmName -Destination $dst -RunAsync -ErrorAction Stop
$jobs.Add($cst.Result.Guest.VM.ExtensionData.RecentTask[-1],$row.Name)
$vMotionTab[$src] += 1
$vMotionTab[$dst] += 1
$remove += $row.Name
}
Catch{
Write-Output "vMotion failed for $vmName from $src to $dst"
$remove += $row.Name
}
}
if($jobs.Count -gt 0){
Get-Task -Id $jobs.Result.Guest.VM.ExtensionData.RecentTask[-1] |
where{$_.PercentComplete -eq 100} | %{
$src,$dst,$vmName = $jobs[$_.Id].Split('-')
$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
HI LucD
seems something were wrong? All failed immediately once trigger
\\ csv
ServerName | SourceESX | DestinationESX |
SerA | esxB | esxA |
SerB | esxC | esxA |
SerC | esxD | esxA |
SerD | esxA | esxD |
SerE | esxC | esxD |
\\
Result:
vMotion failed for SerA from esxB to esxA
vMotion failed for SerB from esxC to esxA
vMotion failed for SerC from esxD to esxA
vMotion failed for SerD from esxA to esxD
vMotion failed for SerE from esxC to esxD
Ok, we'll have to check what goes wrong.
Try removing the -ErrorAction Stop part on the MOve-VM cmdlet.
That should show more error messages
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
HI LucD,
tried to remove the -ErrorAction ,but it doesn't help, symptom same as before.
it will show fail immediately & but the vMotion are successfully triggered in vSphere (all vMotion together)
Result:
vMotion failed for SerA from esxB to esxA
vMotion failed for SerB from esxC to esxA
vMotion failed for SerC from esxD to esxA
vMotion failed for SerD from esxA to esxD
vMotion failed for SerE from esxC to esxD
I added a couple of Write-Host lines to help debugging the issue.
$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()){
$src,$dst,$vmName = $row.Name.Split('-')
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
$jobs.Add($cst.Result.Guest.VM.ExtensionData.RecentTask[-1],$row.Name)
$vMotionTab[$src] += 1
$vMotionTab[$dst] += 1
$remove += $row.Name
}
Catch{
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)"
$src,$dst,$vmName = $jobs[$_.Id].Split('-')
$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
HI LucD,
Result as below
Added esxD to vMotionTab
Added esxA to vMotionTab
Active for esxD = 0
Active for esxA = 0
Move SerC frm esxD to esxD
vMotion failed for SerC from esxD to esxA
Jobs count = 0
Added esxC to vMotionTab
Active for esxC = 0
Active for esxD = 0
Move SerE frm esxC to esxD
vMotion failed for SerE from esxC to esxD
Jobs count = 0
Active for esxC = 0
Active for esxA = 0
Move SerB frm esxC to esxA
vMotion failed for SerB from esxC to esxA
Jobs count = 0
Active for esxA = 0
Active for esxD = 0
Move SerD frm esxA to esxD
vMotion failed for SerD from esxA to esxD
Jobs count = 0
Added esxB to vMotionTab
Active for esxB = 0
Active for esxA = 0
Move SerA frm esxB to esxA
vMotion failed for SerA from esxB to esxA
Jobs count = 0
Can you change the Catch block to
Write-Output $_.Exception | Format-List -Force
Write-Output "vMotion failed for $vmName from $src to $dst"
$remove += $row.Name
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference