VMware Cloud Community
Pilu1978
Enthusiast
Enthusiast
Jump to solution

Cluster Utilisation Report

Hi,

I have been tasked to create utilisation report of all the esxi clusters based on cpu ready, cpu usage and memory usage. So I am using the following script to create the utilisation report for each cluster.

Could anyone please advise if I have made any mistake in calculation while measuring the utilisation based on cpu ready, cpu usage and memory usage or kindly advise if there is any better way to do this

 

Import-Module VMware.VimAutomation.Core

$cwdpath = Split-Path -Parent $MyInvocation.MyCommand.Path
$List = $cwdpath + "\VCList.txt"
$VCList = @(Get-Content $List)
$file = "c:\temp\Cluster-CPU-Mem-Utlisation-" + (Get-Date -Format "dd-MM-yyyy") + ".csv"
$report = @()

foreach($VC in $VCList){

Connect-VIServer $VC -user xxxxxxxx -password 'xxxxxxxxxxxxx' -WarningAction SilentlyContinue

$fol = get-folder | where {$_.Name -eq "PROD" -or $_.Name -eq "DEV"}

$clusters = $fol | Get-Cluster

foreach($cluster in $clusters){

$esxhosts = $cluster | Get-VMHost | where {$_.ConnectionState -eq "connected"}
$vms = $cluster | Get-VM | where {$_.PowerState -eq "PoweredOn"}

if($vms){

[double]$cpuAverage = 0
[double]$memAverage = 0
[double]$cpuReady = 0

foreach ($esx in $esxhosts) {
$stats = Get-Stat -Entity $esx -Stat cpu.ready.summation -Start (Get-Date).Adddays(-1) -Finish (Get-Date)
$readyAvg = $stats | Measure-Object -Property Value -Average | Select -ExpandProperty Average
$readyPerc = ($readyAvg / ($stats[0].IntervalSecs * 1000))*100
$cpuReady = $cpuReady + $readyPerc

[double]$esxiCPUavg = [double]($esx | Select-Object @{N = 'cpuAvg'; E = {[double]([math]::Round(($_.CpuUsageMhz) / ($_.CpuTotalMhz) * 100, 2))}} | Select-Object -ExpandProperty cpuAvg)
$cpuAverage = $cpuAverage + $esxiCPUavg

[double]$esxiMEMavg = [double]($esx | Select-Object @{N = 'memAvg'; E = {[double]([math]::Round(($_.MemoryUsageMB) / ($_.MemoryTotalMB) * 100, 2))}} | select-object -ExpandProperty memAvg)
$memAverage = $memAverage + $esxiMEMavg
}
$cpuAverage = [math]::Round(($cpuAverage / ($esxhosts.count) ), 1)
$memAverage = [math]::Round(($memAverage / ($esxhosts.count) ), 1)
$cpuReady = [math]::Round(($cpuReady / ($esxhosts.count) ), 1)


$row = "" | Select Cluster, "CPURdy(%)", CPUAvg, MEMAvg
$row.Cluster = $Cluster.Name
$row."CPURdy(%)" = $cpuReady
$row.CPUAvg = $cpuAverage
$row.MEMAvg = $memAverage
$report += $row
}
}
Disconnect-VIServer -Confirm:$false
}

$report | Export-Csv $file -NoTypeInformation -UseCulture

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Yes, that looks better now, you are using values from the same interval.


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

View solution in original post

0 Kudos
4 Replies
LucD
Leadership
Leadership
Jump to solution

There is a basic flaw in your script in that you are using the Ready value over 24 hours, while the CpuUsageMHz and MemoryUsageMB values are over a recent short internal interval.
I would suggest using the average of the metrics cpu.usagemhz.average and mem.usage.average, also over 24 hours, instead.


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

0 Kudos
Pilu1978
Enthusiast
Enthusiast
Jump to solution

Thanks LucD for pointing me to correct direction as always. I have made the necessary amendments to the script as per your suggestion as shown below. Please let me know if it is correct now.

 

Import-Module VMware.VimAutomation.Core

$cwdpath = Split-Path -Parent $MyInvocation.MyCommand.Path
$List = $cwdpath + "\VCList.txt"
$VCList = @(Get-Content $List)
$file = "c:\temp\Cluster-CPU-Mem-Utlisation-" + (Get-Date -Format "dd-MM-yyyy") + ".csv"
$metrics = 'cpu.ready.summation','cpu.usagemhz.average','mem.usage.average'
$report = @()

foreach($VC in $VCList){

Connect-VIServer $VC -user xxxxxxxxx -password 'xxxxxxxxxx' -WarningAction SilentlyContinue

$fol = get-folder | where {$_.Name -eq "PROD" -or $_.Name -eq "DEV"}

$clusters = $fol | Get-Cluster

foreach($cluster in $clusters){

$esxhosts = $cluster | Get-VMHost | where {$_.ConnectionState -eq "connected"}
$vms = $cluster | Get-VM | where {$_.PowerState -eq "PoweredOn"}

if($vms){

[double]$cpuAverage = 0
[double]$memAverage = 0
[double]$cpuReady = 0

foreach ($esx in $esxhosts) {
$stats = Get-Stat -Entity $esx -Stat $metrics -Start (Get-Date).Adddays(-1) -Finish (Get-Date)

$readyAvg = $stats | where {$_.MetricId -eq 'cpu.ready.summation'} | Measure-Object -Property Value -Average | Select -ExpandProperty Average
$readyPerc = ($readyAvg / ($stats[0].IntervalSecs * 1000))*100
$cpuReady = $cpuReady + $readyPerc

$esxiCPUavg = $stats | where {$_.MetricId -eq 'cpu.usagemhz.average'} | Measure-Object -Property Value -Average | Select -ExpandProperty Average
$cpuAverage = $cpuAverage + $esxiCPUavg

$esxiMEMavg = $stats | where {$_.MetricId -eq 'mem.usage.average'} | Measure-Object -Property Value -Average | Select -ExpandProperty Average
$memAverage = $memAverage + $esxiMEMavg
}

$cpuAverage = [math]::Round(($cpuAverage / ($esxhosts.count) ), 1)
$memAverage = [math]::Round(($memAverage / ($esxhosts.count) ), 1)
$cpuReady = [math]::Round(($cpuReady / ($esxhosts.count) ), 1)


$row = "" | Select Cluster, "CPURdy(%)", CPUAvg, MEMAvg
$row.Cluster = $Cluster.Name
$row."CPURdy(%)" = $cpuReady
$row.CPUAvg = $cpuAverage
$row.MEMAvg = $memAverage
$report += $row
}
}
Disconnect-VIServer -Confirm:$false
}

$report | Export-Csv $file -NoTypeInformation -UseCulture

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yes, that looks better now, you are using values from the same interval.


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

0 Kudos
Pilu1978
Enthusiast
Enthusiast
Jump to solution

Thanks a lot.

0 Kudos