PowerCLI

 View Only
  • 1.  Tracking the progress of task in the pipeline

    Posted May 25, 2016 08:52 AM

    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.



  • 2.  RE: Tracking the progress of task in the pipeline
    Best Answer

    Posted May 25, 2016 10:11 AM

    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)



  • 3.  RE: Tracking the progress of task in the pipeline

    Posted May 25, 2016 02:29 PM

    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;

                            }

                        }

      }



  • 4.  RE: Tracking the progress of task in the pipeline

    Posted May 25, 2016 04:10 PM

    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