VMware Cloud Community
jcouch
Enthusiast
Enthusiast

Powershell Jobs not finishing when using Move-VM

This is a script block from a larger script I am using to feed it parameters. The background job never finishes if I leave off the -runasync flag. The task completes fine in VC, but I don't see any of the write-hosts in the job output after the Move-Vm line.  I have tried this in both powershell v2 and v3 with powercli 5.0 and 5.1 . Any ideas?

$vCenter = "VCenterName"

$DestinationDatastore = "DestinationDatastoreName"
$VMName = "VMName"
$Account = "Username"
$VIPass = "Password"
# Define Job Parameters
$jobcmd =
{
     $in = $input.'<>4__this'.read();
     Add-PSSnapin VMware.VimAutomation.Core
     Connect-VIServer $in[1] -User $in[2] -Password $in[3]
     Write-Host "Getting VM Object"
     $JobVMObject = get-vm -Name $in[4]
     Write-Host "Getting Datastore Object"
     $JobDatastoreObject = Get-Datastore -name $in[5]
     Write-Host "Moving VM"
     Move-VM -VM $JobVMObject -Datastore $JobDatastoreObject -Verbose:$true
     Write-Host "Im Done Moving"
     Write-Host "Disconnecting from VCenter"
     Disconnect-VIServer * -Confirm:$false -Force:$true
     Write-Host "Disconnected"
$jobSpec = @()
$jobSpec += $jobcmd
$jobSpec += $vCenter
$jobSpec += $acount
$jobSpec += $vipass
$jobSpec += $VMName
$jobSpec += $DestinationDatastore
Start-Job -InputObject $jobSpec -ScriptBlock $jobSpec[0]

Wait until the task in VC completes, then run this command, and you should see that the job doesnt progress past the move-vm command.

Get-Job | Receive-Job -Keep

Tags (2)
Reply
0 Kudos
13 Replies
RvdNieuwendijk
Leadership
Leadership

Have you run 'Wait-Job' to be sure that the job is finished, before you run 'Get-Job | Receive-Job -Keep'?

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
Reply
0 Kudos
jcouch
Enthusiast
Enthusiast

Yes, that is at the core of why this is a problem for me. The job itself never comes out of the status "running", and if you look at the output of one of the jobs, you see that the move started and finished, but it doesnt continue after that

Here is the output from the job after the task has been finished in VC for 1 hour:                 

Getting VM Object
Getting Datastore Object
Moving VM
VERBOSE: 2/19/2013 4:14:43 PM     Move-VM     Started execution
VERBOSE: Performing operation "Move-VM" on Target "Moving VM 'exampleVM'".
VERBOSE: 2/19/2013 4:14:45 PM     Move-VM     Finished execution

Here is an example of the job execution with the "-runasync" flag on the move-VM command:

Getting VM Object

Getting Datastore Object

Moving VM

VERBOSE: 2/19/2013 4:12:47 PM Move-VM Started execution

VERBOSE: Performing operation "Move-VM" on Target "Moving VM 'exampleVM'".

RunspaceId      : 544746c4-91c2-4a41-b628-b3cd5ddb135d

ServerId        : /VIServer=user@vcenter.domain.com:443/

State           : Running

IsCancelable    : False

PercentComplete : 0

StartTime       : 2/19/2013 4:12:49 PM

FinishTime      :

ObjectId        : VirtualMachine-vm-3211

Result          :

Description     : Relocate virtual machine

ExtensionData   : VMware.Vim.Task

Id              : Task-task-65476

Name            : RelocateVM_Task

Uid             : /VIServer=user@vcenter.domain.com:443/Task=Task-task-65476/

VERBOSE: 2/19/2013 4:12:50 PM Move-VM Finished execution

Im Done Moving

Disconnecting from VCenter

Disconnected

I am not concerned with the receive-job output, rather the job completeting so the next job in the queue can start.

Reply
0 Kudos
LucD
Leadership
Leadership

Try adding the -Confirm:$false parameter on the Move-VM cmdlet.


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

Reply
0 Kudos
jcouch
Enthusiast
Enthusiast

Thanks Luc. Tried that just now, I get the same results. Here is the output from the job:

VCenterName.Domain.COM             443   AccountName                    
Getting VM Object
Getting Datastore Object
Moving VM
VERBOSE: 2/20/2013 11:16:21 AM     Move-VM     Started execution
VERBOSE: Performing operation "Move-VM" on Target "Moving VM 'VMName".
VERBOSE: 2/20/2013 11:16:22 AM     Move-VM     Finished execution
Reply
0 Kudos
LucD
Leadership
Leadership

Are you running the script from the 32- or 64-bit PowerCLI ?


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

Reply
0 Kudos
jcouch
Enthusiast
Enthusiast

I have tried both. Same results. I was thinking there might be a way to run it async, but track the task and wait until the task was completed or error. Do you know if there is a good way to track the task created off of a powercli command like Move-VM?

Reply
0 Kudos
RvdNieuwendijk
Leadership
Leadership

You can run the task async and then wait for the task to complete with:

$task = Move-VM -VM $JobVMObject -Datastore $JobDatastoreObject -Verbose:$true -Confirm:$false -RunAsync
Wait-Task -Task $task

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
Reply
0 Kudos
jcouch
Enthusiast
Enthusiast

That didnt seem to work either. I did figure out a workaround though, here is the interjob code. Its not perfect, but it should get me by. I am curious as to why the powershell jobs hang on some tasks like move-vm though.

$jobcmd =
{
$in = $input.'<>4__this'.read();
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer $in[1] -User $in[2] -Password $in[3]
Write-Host "Getting VM Object"
$JobVMObject = get-vm -Id $in[4]
Write-Host "Getting Datastore Object"
$JobDatastoreObject = Get-Datastore -Id $in[5]
Write-Host "Moving VM"
$task = Move-VM -VM $JobVMObject -Datastore $JobDatastoreObject -RunAsync
$RunTask = $True
Write-Host "Waiting On Job To Finish"
sleep 5
while ($RunTask){
$Tasks = Get-Task | where {($_.Name -eq "RelocateVM_Task") -and ($_.ObjectId -eq $JobVMObject.ID)}
If ($Tasks -ne $null){
     foreach ($Task in $Tasks){
         if (($task.state -eq "Success") -or ($task.state -eq "Error")){
              $RunTask = $False
              Break
                  }
                 else {
                              $Time = Get-Date
                              Write-Host "Still Waiting On Job To Finish - $Time"
                          }
                     }
               }
               Else {
                    Write-Host "Cannot find task with VM ID and a name of RelocateVM_Task"
                        break
                }
           start-Sleep 5
       }

     Write-Host "Im Done Moving"

     Write-Host "Disconnecting from VCenter"

     Disconnect-VIServer * -Confirm:$false -Force:$true

     Write-Host "Disconnected"

Reply
0 Kudos
johndavidd
Enthusiast
Enthusiast

I'm having the same issue... did you ever find a solid solution or still using the work around?

Reply
0 Kudos
jcouch
Enthusiast
Enthusiast

I did not. The code above worked great for what we have needed it to do.

Reply
0 Kudos
johndavidd
Enthusiast
Enthusiast

Thanks, I'm writing up something to monitor the task as well... sad that it won't work with just the move-vm command.

Thanks for your quick reply.

Reply
0 Kudos
Czernobog
Expert
Expert

Just wanted to bump this, since I had against the same problem myself recently and the workaround provided by jcouch was the only one that worked for me as well.

In my case it is a script that has to reboot a VM, but is iteself started via a remote powershell session. The script hung everytime during the execution of the PowerCLI cmdlet (any cmdlet really, tried executing one that needs no confirm, like get-vm or get-vmhost). I've tried following the advice posted here: http://communities.vmware.com/thread/449501, but the script stopped regardless of which credentials were used.

Here's the code, maybe someone will find it useful:

$pssession = New-PSSession -ComputerName vCenterServer

$creds = Get-Credential TESTDOMAIN\vmbooter

$sb = {

param($creds)

Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer vCenterServer -Credential $creds

$task = Restart-VM VMtobebooted -Confirm:$false -RunAsync

$taskrunning = $true

sleep 5

while ($RunTask)

{

$Tasks = Get-Task

    If ($Tasks -ne $null)

    {

        foreach ($Task in $Tasks)

            {

            if (($task.state -eq "Success") -or ($task.state -eq "Error"))

                {

                          $RunTask = $False

                Break

                }

            else

                {

                Write-Host "Waiting for task to finish..."

                }

            }

    }

    Else

    {

    break

    }

    start-Sleep 5

} # while END

Disconnect-viserver vCenterServer -Force -Confirm:$false

} # $sb scriptblock object END

Invoke-Command -Session $pssession -ScriptBlock $sb -ArgumentList $creds

Remove-PSSession $pssession

Reply
0 Kudos
EKardinal
Enthusiast
Enthusiast

I've done nearly the same in my script and it's working like a charm.

https://communities.vmware.com/message/2280500#2280500

The only difference I can see is the way of passing arguments into the Job.

Regards

Emanuel

Reply
0 Kudos