DanTourangeau
Contributor
Contributor

Move 2 VMs at the on 2 or more different Hosts

Jump to solution

I found this PowerCli script from LucD. It does work really well. 🙂

However I'm trying to find a way to run only 2 storage vMotions on 2 or more hosts reading a list of VMs for each host.
It does work but only 1 host at the time, no sure how to run to foreach at the same time or it will be an entire new way?

That is what I have so far, I've tried to add some if or else if but always ends up with the same results.
Any help or suggestion will be gladly appreciate. 🙂

Thanks,

$vmhost1 = "hostname1"
$vmhost2 = "hostname2"

$vmlist = Import-CSV c:\Temp\migration\VMs_List-123.csv
$vmlist1 = Import-CSV c:\Temp\migration\VMs_List-123.csv | where {$_.vmhost -eq $vmhost1}
$vmlist2 = Import-CSV c:\Temp\migration\VMs_List-123.csv | where {$_.vmhost -eq $vmhost2}

$maxParallel = 2


foreach ($VM1 in $VMlist1) {

write-host "Currently moving VM" $vm1.name "to the DatastoreCluster " $ds -ForegroundColor Green
Move-VM -VM (Get-VM -Name $vm1.name) -Datastore $ds -RunAsync
do {
sleep 5
}
while((Get-Task -Status Running | where{$_.Name -eq 'ApplyStorageDrsRecommendation_Task'}).Count -ge $maxParallel)

foreach ($VM2 in $VMlist2) {

write-host "Currently moving VM" $vm2.name "to the DatastoreCluster " $ds -ForegroundColor Green
Move-VM -VM (Get-VM -Name $vm2.name) -Datastore $ds -RunAsync
do {
sleep 5
}
while((Get-Task -Status Running | where{$_.Name -eq 'ApplyStorageDrsRecommendation_Task'}).Count -ge $maxParallel)
}

}
Disconnect-VIServer -Server * -Confirm:$false

0 Kudos
70 Replies
DanTourangeau
Contributor
Contributor

Hi Luc,

Not sure why the format changes when I post it.

To make sure I took snippet of the errors.

Thanks!

0 Kudos
LucD
Leadership
Leadership

I ran through the complete script, line by line, and for me, it works without an issue.
Are you by any chance connected to more than 1 VCSA?
How many entries in $global:defaultviservers?

We could check which IDs are actually in the array.
Add an extra Write-Verbose line

  Write-Verbose "EOF: $eof   I: $i   J:$j"
  Write-Verbose "TaskArr Count : $($TaskArr.Count)"
  Write-Verbose "IDs : $($TaskArr.Id -join '|')"      # <-- add line
  
  while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted | 





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

0 Kudos
DanTourangeau
Contributor
Contributor

How many entries in $global:defaultviservers?

It returns only 1 vCenter.

I added the line and snip the results, if I let it run it does shutdown the VMs and transfer it to the datacluster but they don't power on.

0 Kudos
LucD
Leadership
Leadership

I'm not sure what is happening, but it says "Move Task is empty", while the count shows 1.
That is all very strange.


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

0 Kudos
DanTourangeau
Contributor
Contributor

Anything else I can try?

 

0 Kudos
LucD
Leadership
Leadership

To be honest, I ran out of ideas for now.
I would need to debug the script in the environment to try and discover what the issue is.
In my lab it all works.


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

0 Kudos
DanTourangeau
Contributor
Contributor

Hi Luc,

So I redid the script by simplified it with hardcoded variables.
I also limit the number of VMs to test, also we are on a vSphere version 7.0 does that change anything?

This is what it gave me, always seems to have an issue with this line : while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
Also at the end when it tried to start the VM.

 

VERBOSE: 2021-07-29 8:26:50 AM Stop-VMGuest Finished execution
VERBOSE: 2021-07-29 8:26:50 AM Get-VM Finished execution
VERBOSE: 2021-07-29 8:26:55 AM Get-VM Finished execution
VERBOSE: 2021-07-29 8:27:00 AM Get-VM Finished execution
VERBOSE: 2021-07-29 8:27:05 AM Get-VM Finished execution
VERBOSE: 2021-07-29 8:27:05 AM Get-VM Finished execution
VERBOSE: 2021-07-29 8:27:06 AM Move-VM Finished execution
VERBOSE: Move VM-Large-01 to datastore xxx
VERBOSE: Task created: Task-task-9186
VERBOSE: TaskArr Count : 2
VERBOSE: EOF: False I: 1 J:1
VERBOSE: TaskArr Count : 2
VERBOSE: IDs : Task-task-9183|Task-task-9186
Get-Task : 2021-07-29 8:27:06 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:06 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:11 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:11 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:16 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:16 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:21 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:21 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:26 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:26 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:31 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:31 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:36 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:36 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:41 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:42 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:47 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:47 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:52 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:52 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:27:57 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:27:57 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:02 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:02 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:07 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:07 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:12 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:12 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:17 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:17 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:22 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:22 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:27 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:28 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:33 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:33 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:38 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:38 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:43 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:43 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:48 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:48 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:53 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:53 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:28:58 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:28:58 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:29:03 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:29:03 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:29:08 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:29:08 AM Get-Task Finished execution
VERBOSE: Still background tasks running - going to sleep
Get-Task : 2021-07-29 8:29:13 AM Get-Task Object reference not set to an instance of an object.
At line:71 char:11
+ while ((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: 2021-07-29 8:29:14 AM Get-Task Finished execution
VERBOSE: Checking for VMs to start
VERBOSE: Task in hash table 2
Get-Task : 2021-07-29 8:29:14 AM Get-Task Object reference not set to an instance of an object.
At line:79 char:3
+ Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted | where{$_.S ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-Task], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.Common.Commands.Cmdlets.GetTask

VERBOSE: Start VM
Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:82 char:18
+ Get-VM -Name $tCompleted.ExtensionData.Info.EntityName | Start-VM ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-VM], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

VERBOSE: Start VM
Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:82 char:18
+ Get-VM -Name $tCompleted.ExtensionData.Info.EntityName | Start-VM ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-VM], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM

VERBOSE: 2021-07-29 8:29:14 AM Get-Task Finished execution
VERBOSE: Task in hash table 2
VERBOSE: EOF: False I: 1 J:1
VERBOSE: 2021-07-29 8:29:14 AM Get-VM Finished execution

 

Thanks!!

0 Kudos
DanTourangeau
Contributor
Contributor

Hello again,

I made a little changes to the script and seems to have less errors, just that the -PipelineVariable not adding.

while ((Get-Task | where{$TaskArr.id} -PipelineVariable $tCompleted |
where{$_.State -eq 'Running' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' }).Count -ge $maxParallel) {
Write-Verbose "Still background tasks running - going to sleep"
Start-Sleep 5
}

Write-Verbose "Checking for VMs to start"
Write-Verbose "Task in hash table $($TaskArr.Count)"
Get-Task | where{$TaskArr.id} -PipelineVariable $tCompleted | where{$_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $_.State -eq 'Success'} |
ForEach-Object -Process {
Write-Verbose "Start VM $($tCompleted.ExtensionData.Info.EntityName)"
Get-VM -Name $tCompleted.ExtensionData.Info.EntityName | Start-VM -Confirm:$false
$TaskArr.Remove($tCompleted)

 

 

0 Kudos
LucD
Leadership
Leadership

I'm not sure what this is supposed to do?

Get-Task | where{$TaskArr.id} -PipelineVariable $tCompleted | where{$_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $_.State -eq 'Success'}


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

0 Kudos
DanTourangeau
Contributor
Contributor

When you run this command what is suppose to return? Me doesn't work at all...

((Get-Task -Id $TaskArr.Id -PipelineVariable $tCompleted |

I was hopping to replace this line with something similar that "may" work for me...

0 Kudos
LucD
Leadership
Leadership

This supposed to get the Task object for all the task that are stored in $TaskArr.
The PipelineVariable makes it easier to refer to the returned objects later on.
But the problem seems to be that $TaskArr.Id contains a $null value, which is something I can't seem to reproduce.


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

0 Kudos
DanTourangeau
Contributor
Contributor

When I run 

PS Q:\> Get-Task -PipelineVariable $tCompleted | where{$TaskArr.id} | where{$_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $_.State -eq 'Success'}

Name State % Complete Start Time Finish Time
---- ----- ---------- ---------- -----------
ApplyStorageDrsRecommendati... Success 100 12:44:39 PM 12:49:15 PM
ApplyStorageDrsRecommendati... Success 100 12:42:49 PM 12:44:14 PM
ApplyStorageDrsRecommendati... Success 100 12:43:26 PM 12:44:45 PM
ApplyStorageDrsRecommendati... Success 100 12:43:47 PM 12:44:45 PM
VERBOSE: 2021-07-29 12:49:50 PM Get-Task Finished execution

When I run 

$TaskArr.id


Task-task-9363
Task-task-9366
Task-task-9369
Task-task-9372
Task-task-9375
Task-task-9378

 

Im trying but not sure if I'm heading to the right direction?

0 Kudos
LucD
Leadership
Leadership

Give this variation, where it does not use the Id parameter on the Get-Task cmdlet, a try.

$vmhost1 = "hostname1"
$vmhost2 = "hostname2"
$maxParallel = 2

[System.Collections.ArrayList]$TaskArr = @()

$groups = Import-Csv -Path 'c:\Temp\migration\VMs_List-123.csv' -UseCulture |
Group-Object -Property vmhost

$i = $j = 0

$eof = $false
while (-not $eof) {
    Write-Verbose "EOF: $eof   I: $i   J:$j"
    if ($i -lt $groups[0].Group.Count) {
    $vm = Get-VM -Name $groups[0].Group[$i].name
    Shutdown-VMGuest -VM $vm -Confirm:$false
    while((Get-VM -Name $vm).PowerState -ne 'PoweredOff'){
      sleep 5
    }
    $t = Move-VM -VM $vm -Datastore $ds -RunAsync
    Write-Verbose "Move $($vm.Name) to datastore $($ds.Name) "
    if($t){
        Write-Verbose "Task created: $($t.Id)"
        $TaskArr.Add($t) | Out-Null
        Write-Verbose "TaskArr Count : $($TaskArr.Count)"
    }
    else{
        Write-Verbose "Move Task is empty"
    }
    $i++
  }
  if ($j -lt $groups[1].Group.Count) {
    $vm = Get-VM -Name $groups[1].Group[$j].name
    Shutdown-VMGuest -VM $vm -Confirm:$false
    while ((Get-VM -Name $vm).PowerState -ne 'PoweredOff') {
      Start-Sleep 5
      }
    $t = Move-VM -VM $vm -Datastore $ds -RunAsync
    Write-Verbose "Move $($vm.Name) to datastore $($ds.Name) "
    if($t){
      Write-Verbose "Task created: $($t.Id)"
      $TaskArr.Add($t) | Out-Null
      Write-Verbose "TaskArr Count : $($TaskArr.Count)"
     }
     else{
        Write-Verbose "Move Task is empty"
    }
    $j++
  }
  Write-Verbose "EOF: $eof   I: $i   J:$j"
  Write-Verbose "TaskArr Count : $($TaskArr.Count)"
  Write-Verbose "IDs : $($TaskArr.Id -join '|')"
  
  while ((Get-Task -PipelineVariable $tCompleted | 
  where{$_.State -eq 'Running' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id}).Count -ge $maxParallel) {
    Write-Verbose "Still background tasks running - going to sleep"
    Start-Sleep 5
  }

  Write-Verbose "Checking for VMs to start"
  Write-Verbose "Task in hash table $($TaskArr.Count)"
  Get-Task -PipelineVariable $tCompleted | 
  where{$_.State -eq 'Success' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id} |
  ForEach-Object -Process {
    Write-Verbose "Start VM $($tCompleted.ExtensionData.Info.EntityName)"
    Get-VM -Name $tCompleted.ExtensionData.Info.EntityName | Start-VM -Confirm:$false
    $TaskArr.Remove($tCompleted)
  }
  Write-Verbose "Task in hash table $($TaskArr.Count)"

  if ($i -eq $groups[0].Group.Count -and $j -lt $groups[1].Group.Count) {
    Write-Verbose "Reached the end of both VM lists"
    $eof = $true
  }
}

Write-Verbose "Wait till remaining Tasks are finished"
while($TaskArr.Count -gt 0){
    Get-Task-PipelineVariable $tCompleted |
    where{$_.State -eq 'Success' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id} |
    ForEach-Object -Process {
        Write-Verbose "Start VM $($tCompleted.ExtensionData.Info.EntityName)"
        Get-VM -Name $tCompleted.ExtensionData.Info.EntityName | Start-VM -Confirm:$false
      $TaskArr.Remove($tCompleted)
    }
    $erroredOut = @()
    Get-Task -PipelineVariable $tCompleted | 
    where{$_.State -eq 'Error' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id} |
    ForEach-Object -Process {
      Write-Verbose "Error for VM $($tCompleted.ExtensionData.Info.EntityName)"
      $erroredOut += $tCompleted.ExtensionData.Info.EntityName
      $TaskArr.Remove($tCompleted)
    }
}
if($erroredOut.Count -gt 0){
  Write-Error "vMotion failed for VMs $($erroredOut -join ',')"
}


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

0 Kudos
DanTourangeau
Contributor
Contributor

Less errors with this one but still one :

VERBOSE: Task created: Task-task-9372
VERBOSE: TaskArr Count : 4
VERBOSE: EOF: False   I: 2   J:2
VERBOSE: TaskArr Count : 4
VERBOSE: IDs : Task-task-9363|Task-task-9366|Task-task-9369|Task-task-9372
VERBOSE: 2021-07-29 12:43:47 PM	Get-Task	Finished execution
VERBOSE: Still background tasks running - going to sleep
VERBOSE: 2021-07-29 12:43:52 PM	Get-Task	Finished execution
VERBOSE: Still background tasks running - going to sleep
VERBOSE: 2021-07-29 12:43:57 PM	Get-Task	Finished execution
VERBOSE: Still background tasks running - going to sleep
VERBOSE: 2021-07-29 12:44:02 PM	Get-Task	Finished execution
VERBOSE: Still background tasks running - going to sleep
VERBOSE: 2021-07-29 12:44:08 PM	Get-Task	Finished execution
VERBOSE: Still background tasks running - going to sleep
VERBOSE: 2021-07-29 12:44:13 PM	Get-Task	Finished execution
VERBOSE: Still background tasks running - going to sleep
VERBOSE: 2021-07-29 12:44:18 PM	Get-Task	Finished execution
VERBOSE: Checking for VMs to start
VERBOSE: Task in hash table 4
VERBOSE: Start VM 
Get-VM : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At K:\DIMTPS 9\DIMTPS 9-2\Infrastructure\Software\Scripts\Migration\Work In Progress\Move_VMs_To_Cluster_PowerOn_PowerOff_Ver2.ps1:160 char:18
+     Get-VM -Name $tCompleted.ExtensionData.Info.EntityName | Start-VM ...
+                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-VM], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVM
0 Kudos
LucD
Leadership
Leadership

At least the script is getting further.

Seems it now has an issue with the VM's name in the Task object.
The name of the VM is missing in

VERBOSE: Start VM


Let's first eliminate the PipelineVariable and see if that changes anything.

$vmhost1 = "hostname1"
$vmhost2 = "hostname2"
$maxParallel = 2

[System.Collections.ArrayList]$TaskArr = @()

$groups = Import-Csv -Path 'c:\Temp\migration\VMs_List-123.csv' -UseCulture |
Group-Object -Property vmhost

$i = $j = 0

$eof = $false
while (-not $eof) {
    Write-Verbose "EOF: $eof   I: $i   J:$j"
    if ($i -lt $groups[0].Group.Count) {
    $vm = Get-VM -Name $groups[0].Group[$i].name
    Shutdown-VMGuest -VM $vm -Confirm:$false
    while((Get-VM -Name $vm).PowerState -ne 'PoweredOff'){
      sleep 5
    }
    $t = Move-VM -VM $vm -Datastore $ds -RunAsync
    Write-Verbose "Move $($vm.Name) to datastore $($ds.Name) "
    if($t){
        Write-Verbose "Task created: $($t.Id)"
        $TaskArr.Add($t) | Out-Null
        Write-Verbose "TaskArr Count : $($TaskArr.Count)"
    }
    else{
        Write-Verbose "Move Task is empty"
    }
    $i++
  }
  if ($j -lt $groups[1].Group.Count) {
    $vm = Get-VM -Name $groups[1].Group[$j].name
    Shutdown-VMGuest -VM $vm -Confirm:$false
    while ((Get-VM -Name $vm).PowerState -ne 'PoweredOff') {
      Start-Sleep 5
      }
    $t = Move-VM -VM $vm -Datastore $ds -RunAsync
    Write-Verbose "Move $($vm.Name) to datastore $($ds.Name) "
    if($t){
      Write-Verbose "Task created: $($t.Id)"
      $TaskArr.Add($t) | Out-Null
      Write-Verbose "TaskArr Count : $($TaskArr.Count)"
     }
     else{
        Write-Verbose "Move Task is empty"
    }
    $j++
  }
  Write-Verbose "EOF: $eof   I: $i   J:$j"
  Write-Verbose "TaskArr Count : $($TaskArr.Count)"
  Write-Verbose "IDs : $($TaskArr.Id -join '|')"
  
  while ((Get-Task -PipelineVariable $tCompleted | 
  where{$_.State -eq 'Running' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id}).Count -ge $maxParallel) {
    Write-Verbose "Still background tasks running - going to sleep"
    Start-Sleep 5
  }

  Write-Verbose "Checking for VMs to start"
  Write-Verbose "Task in hash table $($TaskArr.Count)"
  Get-Task | 
  where{$_.State -eq 'Success' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id} |
  ForEach-Object -Process {
    Write-Verbose "Start VM $($_.ExtensionData.Info.EntityName)"
    Get-VM -Name $_.ExtensionData.Info.EntityName | Start-VM -Confirm:$false
    $TaskArr.Remove($_)
  }
  Write-Verbose "Task in hash table $($TaskArr.Count)"

  if ($i -eq $groups[0].Group.Count -and $j -lt $groups[1].Group.Count) {
    Write-Verbose "Reached the end of both VM lists"
    $eof = $true
  }
}

Write-Verbose "Wait till remaining Tasks are finished"
while($TaskArr.Count -gt 0){
    Get-Task |
    where{$_.State -eq 'Success' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id} |
    ForEach-Object -Process {
        Write-Verbose "Start VM $($_.ExtensionData.Info.EntityName)"
        Get-VM -Name $_.ExtensionData.Info.EntityName | Start-VM -Confirm:$false
      $TaskArr.Remove($_)
    }
    $erroredOut = @()
    Get-Task | 
    where{$_.State -eq 'Error' -and $_.Name -eq 'ApplyStorageDrsRecommendation_Task' -and $TaskArr.Id -contains $_.Id} |
    ForEach-Object -Process {
      Write-Verbose "Error for VM $($_.ExtensionData.Info.EntityName)"
      $erroredOut += $_.ExtensionData.Info.EntityName
      $TaskArr.Remove($_)
    }
}
if($erroredOut.Count -gt 0){
  Write-Error "vMotion failed for VMs $($erroredOut -join ',')"
}

 


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

0 Kudos
DanTourangeau
Contributor
Contributor

Hello,

This line return the datastorecluster name instead of the vm name :

Get-VM -Name $_.ExtensionData.Info.EntityName

 

0 Kudos
LucD
Leadership
Leadership

I did several tests, and the $_.ExtensionData.Info.EntityName always contains the VM's name.
What is the name of that Task?
Check what is in $_.Name


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

0 Kudos
DanTourangeau
Contributor
Contributor

Good day Luc,

Sorry for the delay, I changed my environment to see if things are different but $_.ExtensionData.Info.EntityName is still returning the Datastores Cluster name.

No sure about what you are asking, but $_.Name return nothing.

As soon as the script tried to start a VM it doesn't give any errors but don't continue to migrate the other VMs on list, just empty the tasks and looks for VM to start.

Thank you!

 

0 Kudos
LucD
Leadership
Leadership

So the objects returned by Get-Task do not have a Name property?


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

0 Kudos
DanTourangeau
Contributor
Contributor

Sorry I'm not sure how to test that?

0 Kudos