Tuesday, February 7, 2012

Grouping and averaging time to execute execute SCVMM 2012 Jobs with PowerShell

In my previous post I ended with a large array of System Center Job Objects.

I need to now determine how long each job took to execute.  And since these are many jobs over time, I want to see if the time to execute changes over time.

So, I need to sort.  I have my array from the previous post.  To sort I do this:

$vhdConvertJobs = $vhdConvertJobs | Sort StartTime

This will sort all Job objects in the Array ( $vhdConvertJobs )using the StartTime property of the Job object. 

Nice and conveniently each job has a StartTime and EndTime, so I just need to subtract those.  The subtraction part is easy:

Foreach ($job in $vhdConvertJobs) {
    ($job.EndTime - $job.StartTime).seconds
}

Now the interesting part.  I have a huge list of numbers.  Great.  I could graph them. No.

I had this great idea to group them into groups of ten and then average them.  So my averages are the first ten, then the second ten, and so on.  That is a bit easier to look at.

$i = $vhdConvertJobs.Count
$arrayTick = 0

While ($arrayTick -lt $i){
    $loopTick = 0
    While ($loopTick -ne 10){
        $timeToConvert = $timeToConvert + ($vhdConvertJobs[$arrayTick].EndTime - $vhdConvertJobs[$arrayTick].StartTime).seconds
        $loopTick++
        $arrayTick++
        if ($arrayTick -eq $i){break}
    }
    "Average of " + $loopTick + " jobs: " + ($timeToConvert / $loopTick) + " seconds"
    $TimeToConvert = 0
}

Put this all together and it looks like this:

<#
.SYNOPSIS
   This script is dump the time to convert VHDs form Dynamic to Fixed from SCVMM 2012
.DESCRIPTION
   It first finds the VMs using the name match pattern (or you can leave that commented to simply get all VMs)
   Then It finds the virtual disk and the latest job on the virtual disks.
   The jobs are sorted from first started to last started.
   The different from StartTime to EndTime is output.
   Then the Jobs are averaged as groups of 10 and groups of 100 from first started to last started.
.AUTHOR
    Brian Ehlert, MSFT VM MVP

.KNOWN ISSUES
   In SCVMM Jobs age and the last job on an object changes.  So there is a timeliness to running this script.  If you
   wait too long you will get an incorrect number of jobs back.
#>


Import-Module VirtualMachineManager

$vhdConvertJobs = @()

$scVMs = Get-SCVirtualMachine | where {$_.Name -match "Xd1K"}

Foreach ($scVM in $scVMs){
    $vhdConvertJobs += [Microsoft.SystemCenter.VirtualMachineManager.Task]( Get-SCVirtualDiskDrive -VM $scVM | where {$_.MostRecentTask -match "convert"} ).MostRecentTask
}

$vhdConvertJobs = $vhdConvertJobs | Sort StartTime

""
"Disk Conversion Jobs"
"Listed first are the jobs started earlier, listed last are the jobs started later"

Foreach ($job in $vhdConvertJobs) {
    ($job.EndTime - $job.StartTime).seconds
}

""
# Break the sorted list of jobs into groups of 10, Average the seconds to convert per group
"Disk Conversion Job Average per 10 conversions"
"Sorted by StartTime.  First are the first jobs started, last are the later jobs started"

$i = $vhdConvertJobs.Count
$arrayTick = 0

While ($arrayTick -lt $i){
    $loopTick = 0
    While ($loopTick -ne 10){
        $timeToConvert = $timeToConvert + ($vhdConvertJobs[$arrayTick].EndTime - $vhdConvertJobs[$arrayTick].StartTime).seconds
        $loopTick++
        $arrayTick++
        if ($arrayTick -eq $i){break}
    }
    "Average of " + $loopTick + " jobs: " + ($timeToConvert / $loopTick) + " seconds"
    $TimeToConvert = 0
}


""
# Break the sorted list of jobs into groups of 100, Average the seconds to convert per group
"Disk Conversion Job Average per 100 conversions"
"Sorted by StartTime.  First are the first jobs started, last are the later jobs started"

$i = $vhdConvertJobs.Count
$arrayTick = 0

While ($arrayTick -lt $i){
    $loopTick = 0
    While ($loopTick -ne 100){
        $timeToConvert = $timeToConvert + ($vhdConvertJobs[$arrayTick].EndTime - $vhdConvertJobs[$arrayTick].StartTime).seconds
        $loopTick++
        $arrayTick++
        if ($arrayTick -eq $i){break}
    }
    "Average of " + $loopTick + " jobs: " + ($timeToConvert / $loopTick) + " seconds"
    $TimeToConvert = 0
}