carias593
Contributor
Contributor

PowerCLI Script to capture Cluster Utilization with Performance Averages (v2)

Jump to solution

Hi,

Id like to take the script used for quickly analyzing and exporting cluster utilization data to include historical average as well using Get-Stat as recommended by LucD.  I've modified the final script version from the previous thread located https://communities.vmware.com/thread/596563 to the following:

$hosts = "192.168.0.1"

$a = "<style>"

$a = $a + "BODY{background-color:white;}"

$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"

$a = $a + "TH{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"

$a = $a + "TD{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:white}"

$a = $a + "</style>"

if($global:defaultviservers){

    Disconnect-VIServer -Server $global:defaultviservers -Force -Confirm:$false

}

$output = foreach($vc in $hosts){

    Write-Host "Getting Cluster Information from $vc"

    Connect-VIServer -Server $vc | Out-Null

    Get-Cluster -Server $vc | where{$_.ExtensionData.Host.Count -ne 0} | ForEach-Object -Process {

        Write-Host "Looking at cluster $($_.Name)"

        #$ds = Get-Datastore -RelatedObject $_ | where{$_.ExtensionData.Summary.MultipleHostAccess}

        $esx = Get-VMHost -Location $_

        $vm = Get-VM -Location $_ | where{$_.PowerState -eq "PoweredOn"}

        $cpuTot = ($esx | Measure-Object -Property CpuTotalMhz -Sum).Sum

        $cpuUse = ($esx | Measure-Object -Property CpuUsageMhz -Sum).Sum

        $memTot = ($esx | Measure-Object -Property MemoryTotalGB -Sum).Sum

        $memUse = ($esx | Measure-Object -Property MemoryUsageGB -Sum).Sum

        $obj = [ordered]@{

            #vCenter = $global:defaultviserver.Name

            Cluster = $_.Name

            'Total CPU Ghz' = [math]::Round($cpuTot/1000,0)

            'CPU Usage' = "{0:P0}" -f ($cpuUse/$cpuTot)

            'CPU Free' = "{0:P0}" -f (($cpuTot - $cpuUse)/$cpuTot)

            'Total RAM GB' = [math]::Round($memTot,0)

            'RAM Usage' = "{0:P0}" -f ($memUse/$memTot)

            'RAM Free GB' = "{0:P0}" -f (($memTot - $memUse)/$memTot)

            #'Total Capacity GB' = [math]::Round(($ds.CapacityGB | Measure-Object -Sum).Sum,0)

            #'Used Capacity GB' = [math]::Round(($ds | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum).Sum,0)

            #'Free Capacity GB' = [math]::Round(($ds.FreeSpaceGB | Measure-Object -Sum).Sum,0)

            'N° Hosts' = $_.ExtensionData.Host.Count

            'N°VMs' = &{

                $esxVM = Get-View -Id $_.ExtensionData.Host -Property VM

                $vm = @()

                if($esxVM.VM){

                    $vm = Get-View -Id $esxVM.VM -Property Summary.Config.Template |

                    where{-not $_.Summary.Config.Template}

                }

                $vm.Count

                }

            'vCPU' = ($vm.NumCpu | Measure-Object -Sum).Sum

            'pCPU' = ($esx.NumCpu | Measure-Object -Sum).Sum

            'vCPU/pCPU' = "{0:P0}" -f (($vm.NumCpu | Measure-Object -Sum).Sum / ($esx.NumCpu | Measure-Object -Sum).Sum)

            'vMem' = [math]::Round(($vm.MemoryGB | Measure-Object -Sum).Sum)

            'pMem' = [math]::Round(($esx.MemoryTotalGB | Measure-Object -Sum).Sum)

            'vMem/pMem' = "{0:P0}" -f (($vm.MemoryGB | Measure-Object -Sum).Sum / ($esx.MemoryTotalGB | Measure-Object -Sum).Sum)

        }

        New-Object PSObject -Property $obj

   }

   Disconnect-VIServer $vc -confirm:$false

}

$output | ConvertTo-Html -Head $a | Out-File C:\ClusterReport.htm -width 400

I've commented out various storage related items, and added columns for the vCPU, pCPU, vMem, and pMem components, as well as changed the original script to only count poweredOn VMs where relevant.  Is it possible to change CPU usage and RAM usage to display the clusters overall average usage for 7 days or even a month? Can anyone think of a way to subtract the largest host from the values calculated for pCPU?

Thanks in advance,

carias593

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

The cluster avg CPU & mem usage can be done as follows.
I trust you can incorporate that in your script

$clusterName = 'cluster'

$sStat = @{

   Entity = Get-Cluster -Name $clusterName

   Stat = 'cpu.usage.average', 'mem.usage.average'

   Start = (Get-Date).AddDays(-7)

   # Start = (Get-Date).AddHours(-1)

   Instance = '*'

   ErrorAction = 'SilentlyContinue'

}


$stat = Get-Stat @sStat


New-Object -TypeName PSObject -Property @{

   Cluster = $clusterName

   ClusterAvgCpu = (($stat | where { $_.MetricId -eq 'cpu.usage.average' }).Value | Measure-Object -Average).Average

   ClusterAvgMem = (($stat | where { $_.MetricId -eq 'mem.usage.average' }).Value | Measure-Object -Average).Average

}

To skip the host with the most pCPU, you could do

'pCPU' = ($esx.NumCpu | Sort-Object -Descending | Select -Skip 1 | Measure-Object -Sum).Sum

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


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

View solution in original post

0 Kudos
11 Replies
LucD
Leadership
Leadership

I'm not sure how the line you added

$vm = Get-VM -Location $_ | where{$_.PowerState -eq "PoweredOn"}

has any impact on the script?

Or am I missing something?


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

0 Kudos
carias593
Contributor
Contributor

Its purpose was to only count the powered on VMs when calculating provisioned memory/cpu (vCPU/vMem).  In our environment, we only count powered on VMs for capacity planning.

carias593

0 Kudos
LucD
Leadership
Leadership

The cluster avg CPU & mem usage can be done as follows.
I trust you can incorporate that in your script

$clusterName = 'cluster'

$sStat = @{

   Entity = Get-Cluster -Name $clusterName

   Stat = 'cpu.usage.average', 'mem.usage.average'

   Start = (Get-Date).AddDays(-7)

   # Start = (Get-Date).AddHours(-1)

   Instance = '*'

   ErrorAction = 'SilentlyContinue'

}


$stat = Get-Stat @sStat


New-Object -TypeName PSObject -Property @{

   Cluster = $clusterName

   ClusterAvgCpu = (($stat | where { $_.MetricId -eq 'cpu.usage.average' }).Value | Measure-Object -Average).Average

   ClusterAvgMem = (($stat | where { $_.MetricId -eq 'mem.usage.average' }).Value | Measure-Object -Average).Average

}

To skip the host with the most pCPU, you could do

'pCPU' = ($esx.NumCpu | Sort-Object -Descending | Select -Skip 1 | Measure-Object -Sum).Sum

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


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

View solution in original post

0 Kudos
carias593
Contributor
Contributor

Here's my final:

$hosts = "192.168.0.1"

$a = "<style>"

$a = $a + "BODY{background-color:white;}"

$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"

$a = $a + "TH{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"

$a = $a + "TD{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:white}"

$a = $a + "</style>"

if($global:defaultviservers){

    Disconnect-VIServer -Server $global:defaultviservers -Force -Confirm:$false

}

$output = foreach($vc in $hosts){

    Write-Host "Getting Cluster Information from $vc"

    Connect-VIServer -Server $vc | Out-Null

    Get-Cluster -Server $vc | where{$_.ExtensionData.Host.Count -ne 0} | ForEach-Object -Process {

        Write-Host "Looking at cluster $($_.Name)"

        #$ds = Get-Datastore -RelatedObject $_ | where{$_.ExtensionData.Summary.MultipleHostAccess}

        $sStat = @{

            Entity = Get-Cluster -Name $_.Name

            Stat = 'cpu.usage.average', 'mem.usage.average'

            Start = (Get-Date).AddDays(-7)

            # Start = (Get-Date).AddHours(-1)

            Instance = '*'

            ErrorAction = 'SilentlyContinue'

            }

        $stat = Get-Stat @sStat

        $esx = Get-VMHost -Location $_

        #$hostthreads = ($esx.extensiondata.hardware.cpuinfo.numcputhreads | Measure-Object -Sum).Sum

        $vm = Get-VM -Location $_ | where{$_.PowerState -eq "PoweredOn"}

        $cpuTot = ($esx | Measure-Object -Property CpuTotalMhz -Sum).Sum

        $cpuUse = ($esx | Measure-Object -Property CpuUsageMhz -Sum).Sum

        $memTot = ($esx | Measure-Object -Property MemoryTotalGB -Sum).Sum

        $memUse = ($esx | Measure-Object -Property MemoryUsageGB -Sum).Sum

        $obj = [ordered]@{

            #vCenter = $global:defaultviserver.Name

            Cluster = $_.Name

            'Total CPU Ghz' = [math]::Round($cpuTot/1000,0)

            'CPU Usage' = "{0:P0}" -f ($cpuUse/$cpuTot)

            'CPU 7-day' = "{0:P2}" -f (((($stat | where { $_.MetricId -eq 'cpu.usage.average' }).Value | Measure-Object -Average).Average)/100)

            'CPU Free' = "{0:P0}" -f (($cpuTot - $cpuUse)/$cpuTot)

            'Total RAM GB' = [math]::Round($memTot,0)

            'RAM Usage' = "{0:P0}" -f ($memUse/$memTot)

            'RAM 7-day' = "{0:P2}" -f (((($stat | where { $_.MetricId -eq 'mem.usage.average' }).Value | Measure-Object -Average).Average)/100)

            'RAM Free GB' = "{0:P0}" -f (($memTot - $memUse)/$memTot)

            #'Total Capacity GB' = [math]::Round(($ds.CapacityGB | Measure-Object -Sum).Sum,0)

            #'Used Capacity GB' = [math]::Round(($ds | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum).Sum,0)

            #'Free Capacity GB' = [math]::Round(($ds.FreeSpaceGB | Measure-Object -Sum).Sum,0)

            'N° Hosts' = $_.ExtensionData.Host.Count

            'N°VMs' = &{

                $esxVM = Get-View -Id $_.ExtensionData.Host -Property VM

                $vm = @()

                if($esxVM.VM){

                    $vm = Get-View -Id $esxVM.VM -Property Summary.Config.Template |

                    where{-not $_.Summary.Config.Template}

                }

                $vm.Count

                }

            'vCPU' = ($vm.NumCpu | Measure-Object -Sum).Sum

            'pCPU' = ($esx.NumCpu | Sort-Object -Descending | Select -Skip 1 | Measure-Object -Sum).Sum

            'vCPU/pCPU' = "{0:P0}" -f (($vm.NumCpu | Measure-Object -Sum).Sum / ($esx.NumCpu | Measure-Object -Sum).Sum)

            'vMem' = [math]::Round(($vm.MemoryGB | Measure-Object -Sum).Sum)

            'pMem' = [math]::Round(($esx.MemoryTotalGB | Measure-Object -Sum).Sum)

            'vMem/pMem' = "{0:P0}" -f (($vm.MemoryGB | Measure-Object -Sum).Sum / ($esx.MemoryTotalGB | Measure-Object -Sum).Sum)

        }

        New-Object PSObject -Property $obj

   }

   Disconnect-VIServer $vc -confirm:$false

}

$output | ConvertTo-Html -Head $a | Out-File C:\ClusterReport.htm -width 400

Here's its output:

Output.jpg

I'm probably going to remove the pMem column since the data is duplicated from Total RAM GB, but all the rest of the data looks great at this point!

Thanks for your help LucD!

carias593

0 Kudos
lucknowdinesh
Contributor
Contributor

I am looking for similar data by script out but when i use it is not working.

I just copy paste this script and only change the name of my VC server at  $hosts = "192.168.0.1" but nothing work.

Can you please help me how to use it in the environment.

0 Kudos
LucD
Leadership
Leadership

I suspect the connection is not working.

Can you change

Connect-VIServer -Server $vc | Out-Null

to

Connect-VIServer -Server $vc

and check if there is an error message?


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

0 Kudos
lucknowdinesh
Contributor
Contributor

Thanks.

After changes script is working but output is not as expected.

$hosts = "10.10.10.xx"

$a = "<style>"

$a = $a + "BODY{background-color:white;}"

$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"

$a = $a + "TH{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"

$a = $a + "TD{border-width: 1px;padding: 1px;border-style: solid;border-color: black;background-color:white}"

$a = $a + "</style>"

if($global:defaultviservers){

    Disconnect-VIServer -Server $global:defaultviservers -Force -Confirm:$false

}

$output = foreach($vc in $hosts){

    Write-Host "Getting Cluster Information from $vc"

    Connect-VIServer -Server $vc

    Get-Cluster -Server $vc | where{$_.ExtensionData.Host.Count -ne 0} | ForEach-Object -Process {

        Write-Host "Looking at cluster $($_.Name)"

        #$ds = Get-Datastore -RelatedObject $_ | where{$_.ExtensionData.Summary.MultipleHostAccess}

        $sStat = @{

            Entity = Get-Cluster -Name $_.Name

            Stat = 'cpu.usage.average', 'mem.usage.average'

            Start = (Get-Date).AddDays(-7)

            # Start = (Get-Date).AddHours(-1)

            Instance = '*'

            ErrorAction = 'SilentlyContinue'

            }

        $stat = Get-Stat @sStat

        $esx = Get-VMHost -Location $_

        #$hostthreads = ($esx.extensiondata.hardware.cpuinfo.numcputhreads | Measure-Object -Sum).Sum

        $vm = Get-VM -Location $_ | where{$_.PowerState -eq "PoweredOn"}

        $cpuTot = ($esx | Measure-Object -Property CpuTotalMhz -Sum).Sum

        $cpuUse = ($esx | Measure-Object -Property CpuUsageMhz -Sum).Sum

        $memTot = ($esx | Measure-Object -Property MemoryTotalGB -Sum).Sum

        $memUse = ($esx | Measure-Object -Property MemoryUsageGB -Sum).Sum

        $obj = [ordered]@{

            #vCenter = $global:defaultviserver.Name

            Cluster = $_.Name

            'Total CPU Ghz' = [math]::Round($cpuTot/1000,0)

            'CPU Usage' = "{0:P0}" -f ($cpuUse/$cpuTot)

            'CPU 7-day' = "{0:P2}" -f (((($stat | where { $_.MetricId -eq 'cpu.usage.average' }).Value | Measure-Object -Average).Average)/100)

            'CPU Free' = "{0:P0}" -f (($cpuTot - $cpuUse)/$cpuTot)

            'Total RAM GB' = [math]::Round($memTot,0)

            'RAM Usage' = "{0:P0}" -f ($memUse/$memTot)

            'RAM 7-day' = "{0:P2}" -f (((($stat | where { $_.MetricId -eq 'mem.usage.average' }).Value | Measure-Object -Average).Average)/100)

            'RAM Free GB' = "{0:P0}" -f (($memTot - $memUse)/$memTot)

            #'Total Capacity GB' = [math]::Round(($ds.CapacityGB | Measure-Object -Sum).Sum,0)

            #'Used Capacity GB' = [math]::Round(($ds | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum).Sum,0)

            #'Free Capacity GB' = [math]::Round(($ds.FreeSpaceGB | Measure-Object -Sum).Sum,0)

            'N° Hosts' = $_.ExtensionData.Host.Count

            'N°VMs' = &{

                $esxVM = Get-View -Id $_.ExtensionData.Host -Property VM

                $vm = @()

                if($esxVM.VM){

                    $vm = Get-View -Id $esxVM.VM -Property Summary.Config.Template |

                    where{-not $_.Summary.Config.Template}

                }

                $vm.Count

                }

            'vCPU' = ($vm.NumCpu | Measure-Object -Sum).Sum

            'pCPU' = ($esx.NumCpu | Sort-Object -Descending | Select -Skip 1 | Measure-Object -Sum).Sum

            'vCPU/pCPU' = "{0:P0}" -f (($vm.NumCpu | Measure-Object -Sum).Sum / ($esx.NumCpu | Measure-Object -Sum).Sum)

            'vMem' = [math]::Round(($vm.MemoryGB | Measure-Object -Sum).Sum)

            'pMem' = [math]::Round(($esx.MemoryTotalGB | Measure-Object -Sum).Sum)

            'vMem/pMem' = "{0:P0}" -f (($vm.MemoryGB | Measure-Object -Sum).Sum / ($esx.MemoryTotalGB | Measure-Object -Sum).Sum)

        }

        New-Object PSObject -Property $obj

   }

   Disconnect-VIServer $vc -confirm:$false

}

$output | ConvertTo-Html -Head $a | Out-File C:\ClusterReport.htm -width 400

My script out is not like this.

Output.jpg

IsConnectedIdServiceUriSessionSecretNamePortSessionIdUserUidVersionBuildProductLineInstanceUuidRefCountExtensionData
0 Kudos
LucD
Leadership
Leadership

That is why the Out-Null was there.
Place it back, since it looks as if the Connect-VIServer is working.

You are sure Get-Cluster is returning anything?


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

0 Kudos
lucknowdinesh
Contributor
Contributor

Excellent!!

It is working now and output is also perfect.

Thanks once again..

0 Kudos
vmk2014
Expert
Expert

LucD,

If i want to pull report for all the cluster in vCenter instead of specific cluster i.e. $clusterName = 'cluster'  will be replaced by $Cluster = Get-Cluster $ClusterName ?

$Cluster = Get-Cluster $ClusterName

$sStat = @{

   Entity = Get-Cluster -Name $clusterName

   Stat = 'cpu.usage.average', 'mem.usage.average'

   Start = (Get-Date).AddDays(-7)

   # Start = (Get-Date).AddHours(-1)

   Instance = '*'

   ErrorAction = 'SilentlyContinue'

}

$stat = Get-Stat @sStat

New-Object -TypeName PSObject -Property @{

   Cluster = $clusterName

   ClusterAvgCpu = (($stat | where { $_.MetricId -eq 'cpu.usage.average' }).Value | Measure-Object -Average).Average

   ClusterAvgMem = (($stat | where { $_.MetricId -eq 'mem.usage.average' }).Value | Measure-Object -Average).Average

}

Thanks

V

0 Kudos
LucD
Leadership
Leadership

Are you going to keep on piggy-backing on answered old threads?

That is not very polite to people doing a search in this community.
If you have a new question, open a new thread.

You can always refer to an existing thread


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

0 Kudos