VMware Cloud Community
birdylarry
Enthusiast
Enthusiast
Jump to solution

Tracking the progress of task in the pipeline

Hi,

Just wondering if there's a way to track the progress (% completed) of each task in the pipeline for a bunch of objects, and also run concurrent command in the pipeline. Don't think write-progress can be used for this purpose.


I have a script that serially migrate a list of VMs every night to a different datastore (storage vMotion). Each VM is quite huge (provisioned size around 1TB) and takes about 3 hours to migrate each. What I want for each VM in the pipeline that is being migrated, is to track how much of the migration is completed (for each VM, not for the VMs in the array as a whole) so I can send out an email notification of the progress for each VM every hour that has passed.


1. Pass each vm in the array to foreach and execute move-vm in concurrence with a bunch of other commands (in pseudo code below)

2. WHen the stopwatch instance hits 1 hour (meaning the storage vmotion for the vm in the pipeline has been going on for an hour), call an email notification function passing the %completed of the current VM being migrated

$vmarray | foreach { #need all command here to run concurrently

move-vm $_ -datastore (get-targetdatastore)

$ElapsedTime = [System.Diagnostics.Stopwatch]::StartNew()

$percentcompleted = get-progress (imaginary function) #this is what I what I need help with

$triggerdue = $elapsedtime.minutes -eq 60

While ($true) {

if ($triggerdue) {$elapsedtime.reset; send-notifmail

$percentcompleted}

}

}


Looking at [runspacefactory]::CreateRunspacePool to run these commands in concurrence but is there a "PS native / more powershell-ish" way to do this?

Thank you very much.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

There are a couple of other possibilities.

You can use Start-Job and parallel tasks in Workflow.

You could launch the Move-VM with the RunAsync switch, that way the script will not wait wait for the completion of the svMotion.

But you will probably hit some vSphere limitations on the max number of svMotions permitted.

Just looking at the status of the powershell jobs (whichever method you chose to use), will not be very conclusive (due to the vSphere maximum).

You could query the Tasks in vSphere and query the percentage completed from there (if available).

That same Task object should also tell you the Status (running ro waiting)


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

View solution in original post

0 Kudos
3 Replies
LucD
Leadership
Leadership
Jump to solution

There are a couple of other possibilities.

You can use Start-Job and parallel tasks in Workflow.

You could launch the Move-VM with the RunAsync switch, that way the script will not wait wait for the completion of the svMotion.

But you will probably hit some vSphere limitations on the max number of svMotions permitted.

Just looking at the status of the powershell jobs (whichever method you chose to use), will not be very conclusive (due to the vSphere maximum).

You could query the Tasks in vSphere and query the percentage completed from there (if available).

That same Task object should also tell you the Status (running ro waiting)


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

0 Kudos
birdylarry
Enthusiast
Enthusiast
Jump to solution

Luc, thanks a lot! I don't want to migrate concurrently as management doesn't approve of it, so have to do it 1 VM at a time. Just wanted to track svmotion progress for each VM.

Turns out RunAsync also returns a task object for the calling cmdlet so I ended up writing it like this:

$ElapsedTime = [System.Diagnostics.Stopwatch]::StartNew()

    $triggerdue = 60

  $vms | % {

  $codeprefix = ($_.name).substring(0, 5) + "*"

  $codesuffix = $SET_B_SUFFIX

  if ($codeprefix -in $SET_A_CODE)

  {

  $codesuffix = $SET_A_SUFFIX

  }

  $targetds = get-targetds $codeprefix $codesuffix

  $svmoStatus = $_ | move-vm -datastore $targetds -RunAsync        

                While ($true)

                    {

                        if ($ElapsedTime.minutes -eq $triggerdue)

                        {

                            $percentComplete = $svmoStatus.percentcomplete

                            send-notifmail $percentComplete

                            $ElapsedTime.Reset

                        }

                        if ($svmoStatus.state -eq "success")

                        {

                            Break;

                        }

                    }

  }

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Note that you will have to refresh the Task object that was given.

Or do a new Get-Task with the Id of the task, that way you are sure you have the current Status


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

0 Kudos