salasos3
Enthusiast
Enthusiast

VM stats at 95% percentile

Hi there,

I have the below code to get some VM stats averages but I need to get the below ones in MB and at 95%:

CPU Util (95%)
Mem Util (MB) (95%)
Net Util-Out (MB/s) (95%)
Net Util-In (MB/s) (95%)

How can I achieve this?

$out= "H:\Desktop\report1.csv"
$vm = Get-Content H:\Desktop\machines.txt

Get-VM -Name $vm |

Select Name, MemoryGB,
@{N="Memory Usage (Average), %" ; E={[Math]::Round((($_ | Get-Stat -Stat mem.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 | Measure-Object Value -Average).Average),2)}} , `
@{N="CPU Usage (Average), Mhz" ; E={[Math]::Round((($_ | Get-Stat -Stat cpu.usagemhz.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 | Measure-Object Value -Average).Average),2)}}, `
@{N="Network Usage (Average), KBps" ; E={[Math]::Round((($_ | Get-Stat -Stat net.usage.average -Start (Get-Date).AddDays(-30) -IntervalMins 5 | Measure-Object Value -Average).Average),2)}} |

Export-Csv -Path $out -NoTypeInformation -UseCulture
Tags (3)
0 Kudos
9 Replies
LucD
Leadership
Leadership

Provided your vCenter is configured to have Historical Interval 4 with a Statistics Level of at least 2 (otherwise the net metrics aren't kept that long), you could do the following.

Note that I used the Get-Percentile function from jbirley.

function Get-Percentile {

  <#

.SYNOPSIS

    Returns the specified percentile value for a given set of numbers.


.DESCRIPTION

    This function expects a set of numbers passed as an array to the 'Sequence' parameter.  For a given percentile, passed as the 'Percentile' argument,

    it returns the calculated percentile value for the set of numbers.


.PARAMETER Sequence

    A array of integer and/or decimal values the function uses as the data set.

.PARAMETER Percentile

    The target percentile to be used by the function's algorithm.


.EXAMPLE

    $values = 98.2,96.5,92.0,97.8,100,95.6,93.3

    Get-Percentile -Sequence $values -Percentile 0.95


.NOTES

    Author:  Jim Birley

#>


  [CmdletBinding()]

  param (

    [Parameter(Mandatory)]

    [Double[]]$Sequence

    ,

    [Parameter(Mandatory)]

    [Double]$Percentile

  )


  $Sequence = $Sequence | Sort-Object

[int]$N = $Sequence.Length

Write-Verbose "N is $N"

[Double]$Num = ($N - 1) * $Percentile + 1

Write-Verbose "Num is $Num"

if ($num -eq 1) {

  return $Sequence[0]

} elseif ($num -eq $N) {

  return $Sequence[$N - 1]

} else {

  $k = [Math]::Floor($Num)

  Write-Verbose "k is $k"

  [Double]$d = $num - $k

  Write-Verbose "d is $d"

  return $Sequence[$k - 1] + $d * ($Sequence[$k] - $Sequence[$k - 1])

}

}


$out = "H:\Desktop\report1.csv"


$metrics = 'cpu.usage.average', 'mem.usage.average', 'net.received.average', 'net.transmitted.average'

$start = (Get-Date).AddDays(-1)


$vmNames = Get-Content H:\Desktop\machines.txt

$vms = Get-VM -Name $vmNames


$sStat = @{

  Entity = $vms

  Start = $start

  Stat = $metrics

  MaxSamples = ([int]::MaxValue)

  Instance = ''

  ErrorAction = 'SilentlyContinue'

}

Get-Stat @sStat |

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

  ForEach-Object -Process {

    New-Object -TypeName PSObject -Property ([ordered]@{

        VM = $group.Name

        MemoryGB = $group.Group[0].Entity.MemoryGB

        CPU95 = "{0:f1}" -f (Get-Percentile -Sequence ($group.Group.Where( { $_.MetricId -eq 'cpu.usage.average' })).Value -Percentile 0.95)

        Mem95 = "{0:f1}" -f (Get-Percentile -Sequence ($group.Group.Where( { $_.MetricId -eq 'mem.usage.average' })).Value -Percentile 0.95)

        NetIn95 = "{0:f1}" -f (Get-Percentile -Sequence ($group.Group.Where( { $_.MetricId -eq 'net.received.average' })).Value -Percentile 0.95)

        NetOut95 = "{0:f1}" -f (Get-Percentile -Sequence ($group.Group.Where( { $_.MetricId -eq 'net.transmitted.average' })).Value -Percentile 0.95)

      })

  } |

  Export-Csv -Path $out -NoTypeInformation -UseCulture


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

0 Kudos
salasos3
Enthusiast
Enthusiast

I just ran it but I'm getting a bunch of these:

Get-Percentile : Cannot bind argument to parameter 'Sequence' because it is null.
At H:\Desktop\vmdata.ps1:127 char:57
+ ... e -Sequence ($group.Group.Where( { $_.MetricId -eq 'net.received.aver ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Percentile], ParameterBindingValidationExcepti
   on
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-Percentile
0 Kudos
LucD
Leadership
Leadership

That indicates most probably that you don't capture those net metrics.


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

0 Kudos
salasos3
Enthusiast
Enthusiast

With my code this is the output Im getting:

They are being captured.

MemoryGB Memory Usage (Average), % CPU Usage (Average), Mhz Network Usage (Average), KBps

12 12.18 2963.24 45.71

12 11.61 696.15 63.65

8 10.7 279.59 41.18

16 6.61 312.4 47.95

12 21.3 1070.35 74.69

8 11.26 312.46 45.47

12 12.66 738.34 66.47

12 11.51 750.15 46.62

0 Kudos
LucD
Leadership
Leadership

And what is the question?
Without seeing the code you are using, I can't deduce anything from that.

Btw, it looks as if you are using the metric net.usage.average, which is available with Statistics Level 1.

But your original question asked for net usage In and Out, which requires metrics net.received.average and net.transmitted.average, which both require Statistics Level 2.
So no, what you posted is most probably not proof that you are capturing Statistics Level 2 for Historical Interval 4.


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

0 Kudos
salasos3
Enthusiast
Enthusiast

Hi LucD

where can I see whether net.received.average and net.transmitted.average are enabled to be collected or not?

0 Kudos
LucD
Leadership
Leadership

You can't see that for individual metrics, you will have to look at settings for the Historical Intervals in the vCenter settings.

Start by reading my PowerCLI & VSphere Statistics – Part 1 – The Basics post.


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

0 Kudos
salasos3
Enthusiast
Enthusiast

Thanks for the link good info!

I ran this and got this output:

PS H:\> Get-StatType -Entity (Get-VM vmname)
cpu.usage.average
cpu.usagemhz.average
cpu.ready.summation
mem.usage.average
mem.swapinRate.average
mem.swapoutRate.average
mem.vmmemctl.average
mem.consumed.average
mem.overhead.average
disk.usage.average
disk.maxTotalLatency.latest
net.usage.average
sys.uptime.latest
disk.used.latest
disk.provisioned.latest
disk.unshared.latest

So I guess if the metric is not in the list it's not being collected.

0 Kudos
LucD
Leadership
Leadership

You should take into account the Historical Interval (the Interval parameter or the Realtime switch).

Since each Historical Interval has a Statistics Level, not all metrics are available for all Historical Intervals.

To see the link between a metric and the Statistics Level, you can consult the PerformanceManager pages.

Or use my Stats Toolbox

Both show the minimum Statistics Level you need to capture that metric.


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

0 Kudos