VMware Cloud Community
Keese
Contributor
Contributor
Jump to solution

Capacity Reporting Based on Memory

Hi Everyone,

I am trying to write a script based on some very specific requirements from management that will measure the capacity of multiple clusters based upon memory.


The template I was given was a CSV that looks like this:


               UsedMemGB     MaxMemGB     AvailableMemGB     CurrentVMs     AvgMemGB(per VM)     MaxVMs(based on the average)     AvailVMs

Cluster1

Cluster2

Cluster3

Grand Total

My current hurdle is that management wants allocated memory, not memory currently in use which, to my understanding, is what MemoryUsageMB reflects. It doesnt make sense for me to move further as the AvgMemGB field is going to be dependent on the total allocated memory

Here is what I have so far:

Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$true | Out-Null

$vcenters = @(

    "vCenter1",

    "vCenter2",

    "vCenter3",

);

Connect-VIServer -Server $vcenters -User <username> -Password <password>

foreach($cluster in Get-Cluster){

    $esx = $cluster | Get-VMHost

    $ds = Get-Datastore -VMHost $esx | where {$_.Type -eq "VMFS"}

    $cluster | Select @{N="Clustername";E={$cluster.Name}},

        @{N="UsedMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryUsageMB -Sum).Sum / 1024, 0)) }},

  @{N="MaxMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024, 0)) }},

        @{N="AvailMemGB";E={([Math]::Round(($esx | Measure-Object -InputObject {$_.MemoryTotalMB - $_.MemoryUsageMB} -Sum).Sum / 1024, 0)) }},

  @{N=“NumVM“;E={($_ |Get-VM).Count}},

        @{N=“AvgMemGB“;E={([Math]::Round((($esx | Measure-Object -Property MemoryUsageMB -Sum).Sum / 1024) / (($_ |Get-VM).Count), 2))}}

}

format-list

Thanks in advance to anyone who can provide some help. Please let me know if you need any more information.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The Export-Csv should be after the last curly brace.


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

View solution in original post

0 Kudos
8 Replies
LucD
Leadership
Leadership
Jump to solution

Isn't the MaxMemGB the total amount of memory over all the ESXi in the cluster ?

Isn't that the value you want ?

Perhaps show the corresponding value of what you want in the vSphere client or the webclient


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

0 Kudos
Keese
Contributor
Contributor
Jump to solution

Hi LucD,

Thank you for responding.

I do want the MaxMemGB and I can get that in this line:

@{N="MaxMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024, 0)) }}


My issue is UsedMemGB:

@{N="UsedMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryUsageMB -Sum).Sum / 1024, 0)) }}


"UsedMemGB" may be an incorrect label. "AllocatedGB" would be more accurate.


On Cluster1 if I run the posted script the output is:

Clustername : ONEVPS02a

UsedMemGB   : 1396 < ---desired location of "Sum" output seen below

MaxMemGB    : 3360

AvailMemGB  : 1964

NumVM       : 209

AvgMemGB    : 6.68

On Cluster1 if I run "Get-cluster | Get-VM -Name * | Measure-Object -Property MemoryGB -Sum" the output is:

Count    : 209

Average  :

Sum      : 1622.046875 < ---desired output

Maximum  :

Minimum  :

Property : MemoryGB

I want to get the "Sum" of all memory allocated to VMs as seen in the second script to output as "UsedMemGB" in the first script.

I hope I articulated that well. Please let me know if any more information is needed.

Thanks!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could just replace the calculated property in your first script with this line I guess

@{N="UsedMemGB";E={([Math]::Round(($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum, 0)) }},


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

Keese
Contributor
Contributor
Jump to solution

Thanks, that worked. I think I'm almost there.

I am having trouble with the export of all things. When I run the script as seen below it lists the metric in the PowerCLI window and generates an empty csv file on C:\. Any ideas?

Also, do you know of any way to total up the values for all cluster(ie add MaxMemGB for all clusters)?

Here is the working script and output in case anyone else needs to reference it:

$TimeStamp = Get-Date -format yyyy-MM-dd

Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$true | Out-Null

$vcenters = @(

    "vCenter1",

    "vCenter2",

    "vCenter3",

    "vCenter4"

);

Connect-VIServer -Server $vcenters -User <username> -Password <password>

foreach($cluster in Get-Cluster){

   

    $esx = $cluster | Get-VMHost

    $ds = Get-Datastore -VMHost $esx | where {$_.Type -eq "VMFS"}

    $cluster | Select @{N="Clustername";E={$cluster.Name}},

        @{N="AllocatedMemGB";E={([Math]::Round(($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum, 0))}},

  @{N="MaxMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024, 0)) }},

  @{N="AvailMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024)) - [Math]::Round(($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum, 0) }},

        @{N=“AvgMemGB“;E={([Math]::Round((($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum) / (($_ |Get-VM).Count), 2))}},

  @{N=“NumVM“;E={($_ |Get-VM).Count}},

  @{N=“MaxVMs“;E={([Math]::Round(((($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024)) / ((($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum) / (($_ |Get-VM).Count))))}},

  @{N=“AvailVMs“;E={([Math]::Round((((($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024)) / ((($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum) / (($_ |Get-VM).Count))) - ($_ |Get-VM).Count)) }}

}

Export-CSV C:\ClusterCapacity-$timestamp.csv

Output:

Clustername    : Cluster1

AllocatedMemGB : 1622

MaxMemGB       : 3360

AvailMemGB     : 1738

AvgMemGB       : 7.76

NumVM          : 209

MaxVMs         : 433

AvailVMs       : 224

Clustername    : Cluster2

AllocatedMemGB : 675

MaxMemGB       : 856

AvailMemGB     : 181

AvgMemGB       : 7.03

NumVM          : 96

MaxVMs         : 122

AvailVMs       : 26

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The ForEach codeblock doesn't place anything in the pipeline, hence the empty CSV file.

You can bypass this by using the call operator.

Something like this

...

&{foreach($cluster in Get-Cluster){

...

} | Export-CSV C:\ClusterCapacity-$timestamp.csv -NoTypeInformation -UseCulture

The question on the MaxMemGB depends on where you want this value to be displayed.

In the CSV in each row, or on the console at the end of the script ?


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

0 Kudos
Keese
Contributor
Contributor
Jump to solution

I am getting:

An empty pipe element is not allowed.

At C:\Users\onkeesej\Desktop\ClusterReport.ps1:23 char:4

+ } | <<<<  Export-CSV C:\ClusterCapacity-$timestamp.csv -NoTypeInformation -U

eCulture

    + CategoryInfo          : ParserError: (:) [], ParseException

    + FullyQualifiedErrorId : EmptyPipeElement

I believe I modified the script correctly as seen below.

$TimeStamp = Get-Date -format yyyy-MM-dd

Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$true | Out-Null

$vcenters = @(

    "vCenter1",

    "vCenter2",

    "vCenter3",

    "vCenter4"

);

Connect-VIServer -Server $vcenters -User <username> -Password <password>

&{foreach($cluster in Get-Cluster){

   

    $esx = $cluster | Get-VMHost

    $ds = Get-Datastore -VMHost $esx | where {$_.Type -eq "VMFS"}

    $cluster | Select @{N="Clustername";E={$cluster.Name}},

        @{N="AllocatedMemGB";E={([Math]::Round(($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum, 0))}},

  @{N="MaxMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024, 0)) }},

  @{N="AvailMemGB";E={([Math]::Round(($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024)) - [Math]::Round(($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum, 0) }},

        @{N=“AvgMemGB“;E={([Math]::Round((($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum) / (($_ |Get-VM).Count), 2))}},

  @{N=“NumVM“;E={($_ |Get-VM).Count}},

  @{N=“MaxVMs“;E={([Math]::Round(((($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024)) / ((($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum) / (($_ |Get-VM).Count))))}},

  @{N=“AvailVMs“;E={([Math]::Round((((($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1024)) / ((($cluster | Get-VM | Measure-Object -Property MemoryGB -Sum).Sum) / (($_ |Get-VM).Count))) - ($_ |Get-VM).Count)) }}

} | Export-CSV C:\ClusterCapacity-$timestamp.csv -NoTypeInformation -UseCulture

}

As for the MaxMemGB and the other values I would like a total across all clusters within the CSV to display after the individual cluster values. Below is an example. I don't know if this is possible though.

Output:

Clustername    : Cluster1

AllocatedMemGB : 1622

MaxMemGB       : 3360

AvailMemGB     : 1738

AvgMemGB       : 7.76

NumVM          : 209

MaxVMs         : 433

AvailVMs       : 224

Clustername    : Cluster2

AllocatedMemGB : 675

MaxMemGB       : 856

AvailMemGB     : 181

AvgMemGB       : 7.03

NumVM          : 96

MaxVMs         : 122

AvailVMs       : 26

Total

AllocatedMemGB : 1297

MaxMemGB       : 4612

AvailMemGB     : 1919

NumVM          : 305

MaxVMs         : 555

AvailVMs       : 250

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The Export-Csv should be after the last curly brace.


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

0 Kudos
Keese
Contributor
Contributor
Jump to solution

Needed to put the Export-CSV after and add an extra curly brace. Thank you sir.

0 Kudos