ccastell
Contributor
Contributor

Game of Nines VMuptime script

Trying to run this report against a vc with about 1000 vms.  we recieve this error after about 15 minutes of running it.  anyone ever see this?  attached a screenshot.  It does produce results from about 200 vms before it stops.

Here is the scrip we are running:

function Get-VMUptime {

<# 

.SYNOPSIS  Calculate the VM uptime percentage 

.DESCRIPTION The function will calculate the uptime

    percentage for a VM for a given period of time 

.NOTES  Author:  Luc Dekens 

.PARAMETER VM

    One or more virtual machines. This parameter accepts

    pipeline input. 

.PARAMETER Start

    Start of the interval over which the uptime percentage

    shall be calculated. THe default is 7 days ago. 

.PARAMETER Finish

    End of the interval. The default is 'now'. 

.EXAMPLE

    PS> Get-VMUptime -VM

.EXAMPLE

   PS> Get-VM VM | Get-VMUptime -Start $start

#>

  param(

    [CmdletBinding()]

    [Parameter(

      Position=0,

      Mandatory=$true,

      ValueFromPipeline=$true,

      ValueFromPipelineByPropertyName=$true

    )]

    [PSObject[]]$VM,

    [Datetime]$Start = ((Get-Date).AddDays(-30)),

    [Datetime]$Finish = (Get-Date)

  )

  process {

    $extraStart = $Start.AddDays(-1)

    Get-Stat -Entity $VM -Stat "sys.uptime.latest" -Start $extraStart -Finish $Finish -ErrorAction SilentlyContinue |

    Group-Object -Property {$_.Entity.Name} | %{

      if($_.Group){

        $totalUptime = 0

        $intervalDuration = $_.Group[0].IntervalSecs

        $numberOfSamples = $_.Count - (86400 / $intervalDuration)

        $startInterval = $_.Group[$numberOfSamples - 1].Timestamp - (New-TimeSpan -Seconds $intervalDuration)

        $uptime = New-TimeSpan -Seconds $_.Group[0].Value

        if(($_.Group[0].Timestamp - $uptime) -le $startInterval){

          $totalUptime = $numberOfSamples * $intervalDuration

        }

        else{

          $i = [math]::Floor($_.Group[0].Value/$intervalDuration)

          $totalUptime = $_.Group[0].Value

          $i++

          while($i -lt $numberOfSamples){

            if(0,1 -notcontains $_.Group[$i].Value){

              $j = $i + [math]::Floor($_.Group[$i].Value/$intervalDuration) + 1

              if($j -le $numberOfSamples){

                $totalUptime += $_.Group[$i].Value

                $i = $j++

              }

              else{

                $partialIntervalValue = $_.Group[$i].Value - $_.Group[$i + 1].Value

                $completeIntervals = $numberOfSamples - $i - 1

                $fullIntervalsValue = $completeIntervals * $intervalDuration

                $totalUptime += ($fullIntervalsValue + $partialIntervalValue)

                $i = $j

              }

            }

          }

        }

        New-Object PSObject -Property @{

          VM = $_.Name

          Uptime = [math]::Round(($totalUptime / ($numberOfSamples * $intervalDuration) * 100),2)

          Unit = "percent"

          Start = $startInterval

          Finish = $_.Group[0].Timestamp

        }

      }

      else{

        New-Object PSObject -Property @{

          VM = $_.Name

          Uptime = "no data"

          Unit = ""

          Start = $Start

          Finish = $Finish

        }

      }

    }

  }

}

$yearStart = Get-Date -Day 1 -Month 8 -Year 2013 -Hour 0 -Minute 0 -Second 0

$months = 2

$vms = Get-VM  ITSS*

 

&{0..($months-1) | %{

  $start = $yearStart.AddMonths($_)

  $finish = $start.AddMonths(1).AddSeconds(-1)

   Get-VMUptime -VM $vms -Start $start -Finish $finish

}} |

Export-Csv C:\uptime.csv -NoTypeInformation -UseCulture

0 Kudos
5 Replies
LucD
Leadership
Leadership

From the error it looks as if there was a metric returned with a $null timestamp.

Would you be able to pinpoint the VM that gives this error ?

And check if you can see data under the Performance tab for the VM ?


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

0 Kudos
ccastell
Contributor
Contributor

i don't know how i would be able to pinpoint this vm.  the script finishes but with a few vm's missing.  this is a 5.1 vcenter.  we also have a 4.1 vcenter with about 1100vm's in it.  i am running the script using powercli 64bit on a machine that has 8gb of memory.  the 5.1 finishes fine in about 2 hours against 900+ guests.  The 4.1 has been running for 8 hours and has just consumed all the memory from the host i am running the script from.  it still running, just trying to figure out if i should stop the query or just wait and let it complete or error out...  any help would be appreciated.

0 Kudos
LucD
Leadership
Leadership

One suggestion, you could run the script against smaller numbers of VM, in parallel.

Use the Start-Job cmdlet for that.

That should make the total runtime shorter (I hope), and would allow you to pinpoint which VMs are causing this.

It could also be caused by the PowerShell engine running out of resources due to the greater number of VM.

Did you check the resource consumption of the PS engine ?


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

0 Kudos
ccastell
Contributor
Contributor

Luc thanks for the responses.  So I continued doing some additional testing.  I specified 1 vm name in the script and tried to run it against out 4.1 vcenter, it is just clocking away.  this shouldn't take more than 5 minutes i would think, i am going on 30 minutes for 1 machine.  Does this script work against 4.1?

0 Kudos
LucD
Leadership
Leadership

To be honest, I don't know.

And I'm afraid I don't have a 4.1 available to do some debugging.


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

0 Kudos