Using PowerShell for vCenter Task Collection

Let me start with a disclaimer, I am not great with PowerShell or PowerCLI. I likely am inefficient and am a relative noob when it comes to both. I tend to lean on variables too much as they are my crutch. As a side note, I began my professional tech career in Linux Land and first learned to script in bash. With that all said, I did want to share something I learned when doing some recent testing.

What I was trying to do

What was the testing I was doing? I needed to run through a series of workflows, such as cloning VMs, powering on those VMs, taking some managed snapshots of those VMs, powering off the VMs and then deleting the VMs. For each one of these workflows I wanted to get an accurate measurement of Task Success Rate and Task Execution Time. Then take the numbers and figure out averages, mins and maxes. I could have just setup some fancy timers and math in the script, but found that getting task failure/success a bit more tricky. Where did I go from there?

At first I figured I should just use Get-Task, the problem with Get-Task is that it’s only the most recent tasks and pretty limited on details.

PS C:\> Get-Task

Name                           State      % Complete Start Time   Finish Time 
----                           -----      ---------- ----------   ----------- 
PowerOnVM_Task                 Running            33 11:20:29 AM              
PowerOnVM_Task                 Running            66 11:20:29 AM              
PowerOnVM_Task                 Running            66 11:20:29 AM              
PowerOnVM_Task                 Running            33 11:20:29 AM              

I didn’t know when the task was queued, what object the task was for and if the task took long enough the result that I wanted could be missing from that view. Then I looked at get-events and with that I just didn’t get the numbers I wanted either. After a lot of google searching and forum diving, I found a method that worked well for what I needed. It is a combination of creating a filter and task collector, gathering those tasks and then exporting them to excel. There were a lot of useful resources that I found. A lot of them came back to a few posts from LucD on event gathering (reference: 1, 2 and 3). Let us take a look at what I ended up with.

How did I collect the Tasks?

With the information I had gathered I came up with the process of creating a filter, creating the collector task manager for each vCenter, running the test , gathering all of the tasks starting when I kicked off the script and storing them to a variable.

First was getting the filter created. I wanted to create the filter based of the time I started the script. I would use Get-Date for that, then create the filter based off of the

## Creating Task Collector Managers for each vCenter ##

    ## First setting the task date and filters ##
        $DateStart = Get-Date
        $TaskNumber = 1000
        $tFilter = New-Object VMware.Vim.TaskFilterSpec
        $tFilter.Time = New-Object VMware.Vim.TaskFilterSpecByTime
        $tFilter.Time.beginTime = $DateStart
        $tFilter.Time.timeType = "startedTime"

    ## Setting up the Collector Task Managers ##
        $ac1TaskMgr = Get-view TaskManager -Server $ac1_vcsa
        $ac2TaskMgr = Get-view TaskManager -Server $ac2_vcsa

Then I ran through all the tests that I needed to run and then did the collecting. From my understanding, the RewindCollector option is needed to start the reading of the tasks from oldest to newest. What I did below was filter the tasks by the startedTime, then starting at the first task in that range start collecting the tasks 1000 at a time and storing them in a variable. If there were more than 1000 events, then after gabbing those events I would read the next 1000 after that, until there were no more remaining tasks.

## Collectiong the Tasks for the Test from the Tasks Manager Collector ##

Write-Host -ForegroundColor Green "Collecting all of the Tasks from each vCenter for the Script starting at $DateStart."

## AC-1 vCSA - Getting the collector, rewinding it and then gathering all of the tasks starting when this script started ##

$ac1tCollector = Get-View ($ac1TaskMgr.CreateCollectorForTasks($tFilter)) -Server $ac1_vcsa
$ac1tCollector.RewindCollector()
do  
  {
    $ac1Tasks = $ac1tCollector.ReadNextTasks($TaskNumber)
    $ac1Tasks.Count
    $ac1TasksList += $ac1Tasks
  }
until($ac1Tasks.Count -eq 0)

## AC-2 vCSA - Getting the collector, rewinding it and then gathering all of the tasks starting when this script started ##

$ac2tCollector = Get-View ($ac2TaskMgr.CreateCollectorForTasks($tFilter)) -Server $ac2_vcsa
$ac2tCollector.RewindCollector()
do  
  {
    $ac2Tasks = $ac2tCollector.ReadNextTasks($TaskNumber)
    $ac2Tasks.Count
    $ac2TasksList += $ac2Tasks
  }
until($ac2Tasks.Count -eq 0)

Alright, alright, alright. I have all of these tasks, now what? This is where my lack of PowerShell skill comes into play. I should be able to just filter by the task I want to see and then grab the numbers all in PowerShell. I am not at that level (yet). So I used Import-Excel module to export my filtered results to a .xlxs file. Each filtered result had a sheet in that workbook created for it as well.

Using Export-Excel to use the Data

I want to make some use of the data now that I have all of the tasks for the test I ran. What I ended using is Where-Object to filter by the DescriptionID. I could have used the Name as well to filter. As I was spending a lot of time looking at these tasks, I had already gathered the DescriptionID’s. The task names could be found by looking through the Managed Objects as well.

Here is the workflow that I put together:

## Now that we have all of the tasks, time to output them to an Excel file and filter out each event type. ##

## Gathering all of the tasks and outputing them to their own workbook sheets ##
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.clone'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-CloneVM-Task' -ClearSheet -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOn'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-PowerOnVM-Task' -ClearSheet -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.createSnapshot'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-Snapshot-Task' -ClearSheet -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOff'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-PowerOff-Task' -ClearSheet -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.destroy'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-DeleteVM-Task' -ClearSheet -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.clone'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-CloneVM-Task' -Append -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOn'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-PowerOnVM-Task' -Append -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.createSnapshot'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-Snapshot-Task' -Append -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOff'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-PowerOff-Task' -Append -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.destroy'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'all-DeleteVM-Task' -Append -FreezeTopRow

## Gathering all of the AC-VCSA-1 tasks and outputing them to their own workbook sheets ##
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.clone'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac1-CloneVM-Task' -ClearSheet -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOn'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac1-PowerOnVM-Task' -ClearSheet  -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.createSnapshot'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac1-Snapshot-Task' -ClearSheet  -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOff'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac1-PowerOff-Task' -ClearSheet  -FreezeTopRow
$ac1TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.destroy'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac1-DeleteVM-Task' -ClearSheet  -FreezeTopRow

## Gathering all of the AC-VCSA-2 tasks and outputing them to their own workbook sheets ##
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.clone'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac2-CloneVM-Task' -ClearSheet  -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOn'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac2-PowerOnVM-Task' -ClearSheet  -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.createSnapshot'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac2-Snapshot-Task' -ClearSheet  -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.powerOff'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac2-PowerOff-Task' -ClearSheet  -FreezeTopRow
$ac2TasksList |Where-Object {$_.DescriptionId -eq 'VirtualMachine.destroy'} | Export-Excel -Path $Excel_FilePath  -WorksheetName 'ac2-DeleteVM-Task' -ClearSheet  -FreezeTopRow

Here is a look at what the results looked like in Excel Online:

This was the first time I had ever used Export-Excel. There are several things I could have done better here. I could have filtered the task results even further. Such as only showing the queued time, start time, finish time, Name and result. I imagine that I’ll get some more ideas down the road of what I could improve on as well. At the end of the script I destroyed the collector that was created.

## Destroying the collectors and disconnecting from the vCSA ##
$ac1tCollector.DestroyCollector()
$ac2tCollector.DestroyCollector()

What’s next?

The next part of the journey will be using python to run through this process instead. I’ve been telling myself that I need to learn python for a few years now. However I never found any projects that would really force me to learn python. When I was trying to figure out some of these processes I worked with one of my coworkers (jhop). He was able to get the task collector working with python and pyvmomi. I also want to convert a lot of these tests I’ve been doing into python scripts (QA Teams love python).

There is a long road ahead there on some stuff to learn and figure out. In the short term though I want to go ahead and clean up the output I was collecting and figure out a better way to automate the calculation/formulas I want to use to analyze the data. This may lead to some interesting posts in the future.

Posted in PowerCLI, PowerShell, VMware and tagged , .

Leave a Reply