VMware Cloud Community
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Get VM`s Host CPU and Memory Usage

Hi,

How can I get VM`s realtime ESX Host CPU and Memory Usage from PowerCLI.

I can see from vCenter, but I am not sure how can I get the realtime details.

Please help

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The Web Client seems to take mem.granted.average instead of mem.active.average.
The corrected code follows.

The difference in values is most probably explained by the difference in the sampling interval.

You take only 1 value, the latest.
While I suspect the Web Client looks over a longer interval and takes the average.
And before you ask, no, I don't know what interval the Web Client uses.

If you want to approach the values in the Web Client, you will have to do some experimenting with the interval duration.

$sStat = @{

        Entity = Get-VMHost -Name 'esx10' | Get-VM

        Stat = 'cpu.usagemhz.average','mem.granted.average'

        Instance = ''

        MaxSamples = 1

        Realtime = $true

        ErrorAction = 'SilentlyContinue'

    }

    Get-Stat @sStat | Group-Object -Property {$_.Entity.Name} -PipelineVariable group |

    ForEach-Object -Process {

        New-Object -TypeName PSObject -Property (

            [ordered]@{

                VmName = $group.Name

                'CPU GHz' = [math]::Round(($group.Group | where{$_.MetricId -eq 'cpu.usagemhz.average'}).Value / 1000,2)

                'Memory GB' = [math]::Round(($group.Group | where{$_.MetricId -eq 'mem.granted.average'}).Value / 1MB,2)

            }

        )

    }| Format-Table -AutoSize

  

  


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

View solution in original post

0 Kudos
19 Replies
LucD
Leadership
Leadership
Jump to solution

You have to use the Realtime switch on the Get-Stat cmdlet.


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Hi LucD,

I tried as below and getting the error

$allvms = @()

$vms = Get-VMHost 'esx1' | get-vm

foreach($vm in $vms){

$vmstat = "" | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin

$vmstat.VmName = $vm.name

$Stat = Get-Stat -entity $vm.name -cpu -memory -maxsamples 1 -realtime

$statcpu    = ($stat | Where-Object {$_.MetricId -eq "cpu.usage.average" -and !$_.Instance}).value

$statmem = ($stat | Where-Object {$_.MetricId -eq "mem.usage.average"}).value

$cpu = $statcpu | Measure-Object -Property value -Average -Maximum -Minimum

$mem = $statmem | Measure-Object -Property value -Average -Maximum -Minimum

$vmstat.CPUMax = $cpu.Maximum

$vmstat.CPUAvg = $cpu.Average

$vmstat.CPUMin = $cpu.Minimum

$vmstat.MemMax = $mem.Maximum

$vmstat.MemAvg = $mem.Average

$vmstat.MemMin = $mem.Minimum

$allvms += $vmstat

}

$allvms | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin | ft -auto

Error

Measure-Object : The property "value" cannot be found in the input for any objects.

At D:\myreports\Performance\perf1.ps1:38 char:19

+ ...  $statcpu | Measure-Object -Property value -Average -Maximum -Minimum ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [Measure-Object], PSArgumentException

    + FullyQualifiedErrorId : GenericMeasurePropertyNotFound,Microsoft.PowerShell.Commands.MeasureObjectCommand

Measure-Object : The property "value" cannot be found in the input for any objects.

At D:\myreports\Performance\perf1.ps1:39 char:19

+ ...  $statmem | Measure-Object -Property value -Average -Maximum -Minimum ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [Measure-Object], PSArgumentException

    + FullyQualifiedErrorId : GenericMeasurePropertyNotFound,Microsoft.PowerShell.Commands.MeasureObjectCommand

Measure-Object : The property "value" cannot be found in the input for any objects.

At D:\myreports\Performance\perf1.ps1:38 char:19

+ ...  $statcpu | Measure-Object -Property value -Average -Maximum -Minimum ...

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You already selected the Value property

$statcpu    = ($stat | Where-Object {$_.MetricId -eq "cpu.usage.average" -and !$_.Instance}).value

$statmem = ($stat | Where-Object {$_.MetricId -eq "mem.usage.average"}).value

so there is no Value property when you do the Measure-object.
You could do

$cpu = $statcpu | Measure-Object -Average -Maximum -Minimum

$mem = $statmem | Measure-Object -Average -Maximum -Minimum

On the other hand, since you used -Maxsamples 1, I don't really see the point of doing the Measure-Object.


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

LucD,

I tried as per your reply and getting the error as below

script

$allvms = @()

$vms = Get-VMHost 'pocesx10.zeomega.loc' | get-vm

foreach($vm in $vms){

$vmstat = "" | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin

$vmstat.VmName = $vm.name

$Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realtime

$cpu = $statcpu | Measure-Object -Property value -Average -Maximum -Minimum

$mem = $statmem | Measure-Object -Property value -Average -Maximum -Minimum

$vmstat.CPUMax = $cpu.Maximum

$vmstat.CPUAvg = $cpu.Average

$vmstat.CPUMin = $cpu.Minimum

$vmstat.MemMax = $mem.Maximum

$vmstat.MemAvg = $mem.Average

$vmstat.MemMin = $mem.Minimum

$allvms += $vmstat

}

$allvms | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin | ft -auto

Error

Get-Stat : 08/24/2020 11:07:29 AM       Get-Stat                The metric counter "mem.usage.average" doesn't exist for entity "APP04".

At D:\myreports\Performance\perf1.ps1:31 char:9

+ $Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realt ...

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (mem.usage.average:String) [Get-Stat], VimException

    + FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

Get-Stat : 08/24/2020 11:07:29 AM       Get-Stat                The metric counter "mem.vmmemctl.average" doesn't exist for entity "APP04".

At D:\myreports\Performance\perf1.ps1:31 char:9

+ $Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realt ...

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (mem.vmmemctl.average:String) [Get-Stat], VimException

    + FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

Get-Stat : 08/24/2020 11:07:29 AM       Get-Stat                The metric counter "mem.active.average" doesn't exist for entity "APP04".

At D:\myreports\Performance\perf1.ps1:31 char:9

+ $Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realt ...

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (mem.active.average:String) [Get-Stat], VimException

    + FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

Get-Stat : 08/24/2020 11:07:29 AM       Get-Stat                The metric counter "mem.granted.average" doesn't exist for entity "APP04".

At D:\myreports\Performance\perf1.ps1:31 char:9

+ $Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realt ...

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (mem.granted.average:String) [Get-Stat], VimException

    + FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

Get-Stat : 08/24/2020 11:07:29 AM       Get-Stat                The metric counter "cpu.usage.average" doesn't exist for entity "APP04".

At D:\myreports\Performance\perf1.ps1:31 char:9

+ $Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realt ...

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (cpu.usage.average:String) [Get-Stat], VimException

    + FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

Get-Stat : 08/24/2020 11:07:29 AM       Get-Stat                The metric counter "cpu.usagemhz.average" doesn't exist for entity "APP04".

At D:\myreports\Performance\perf1.ps1:31 char:9

+ $Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realt ...

+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ResourceUnavailable: (cpu.usagemhz.average:String) [Get-Stat], VimException

    + FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It looks as if that VM is not powered on or not sending statistical data.
You can avoid those errors by adding -ErrorAction SilentlyContinue on the Get-Stat cmdlet.
But that also means that this specific VM will not appear in your report.


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Hi LucD,

After adding the -ErrorAction SilentlyContinue the script executed but I am just seeing the VM Name in the output rest of the output shows blank. Smiley Sad

     

VmNameMemMaxMemAvgMemMinCPUMaxCPUAvgCPUMin
APP203
APP13
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You are using the incorrect variable for the CPU and Memory statistics.

It should be $stat

$Stat = Get-Stat -Entity ($vm.name) -Cpu -Memory -MaxSamples 1 -Realtime -ErrorAction SilentlyContinue

  

$cpu = $stat | Measure-Object -Property value -Average -Maximum -Minimum

$mem = $stat | Measure-Object -Property value -Average -Maximum -Minimum


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Hi LucD,

now I am getting the output but number are not formatted properly. CPU and Memory details are not showing in Mhz and GB

How can I format the output of CPU in Mhz and Memory in GB ?

      

VmNameMemMaxMemAvgMemMinCPUMaxCPUAvgCPUMin
APP20315337472156733501533747215673350
APP1316777216184556001677721618455600
APP1612582912165155201258291216515520
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I have no clue what code you are currently running.
If you are using the average metrics, these are in percentage


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

LucD,

I am using below code

$allvms = @()

$vms = Get-VMHost 'esx10' | get-vm

foreach($vm in $vms){

$vmstat = "" | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin

$vmstat.VmName = $vm.name

$Stat = Get-Stat -entity ($vm.name) -cpu -memory -maxsamples 1 -realtime -ErrorAction SilentlyContinue

$cpu = $Stat | Measure-Object -Property value -Average -Maximum -Minimum

$mem = $Stat | Measure-Object -Property value -Average -Maximum -Minimum

$vmstat.CPUMax = $cpu.Maximum

$vmstat.CPUAvg = $cpu.Average

$vmstat.CPUMin = $cpu.Minimum

$vmstat.MemMax = $mem.Maximum

$vmstat.MemAvg = $mem.Average

$vmstat.MemMin = $mem.Minimum

$allvms += $vmstat

}

$allvms | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin | ft -auto

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Still not sure why you calculate the minimum and maximum when you do a MaxSamples 1.
That makes no sense.

In any case, this is how I would run this

$sStat = @{

        Entity = Get-VMHost -Name 'esx10' | Get-VM

        Stat = 'cpu.usagemhz.average','mem.active.average'

        Instance = ''

        MaxSamples = 1

        Realtime = $true

        ErrorAction = 'SilentlyContinue'

    }

    Get-Stat @sStat | Group-Object -Property {$_.Entity.Name} -PipelineVariable group |

    ForEach-Object -Process {

        New-Object -TypeName PSObject -Property (

            [ordered]@{

                VmName = $group.Name

                'CPU GHz' = [math]::Round(($group.Group | where{$_.MetricId -eq 'cpu.usagemhz.average'}).Value / 1000,2)

                'Memory GB' = [math]::Round(($group.Group | where{$_.MetricId -eq 'mem.active.average'}).Value / 1MB,2)

            }

        )

    }| Format-Table -AutoSize

  

  


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

LucD,

I am able to get the values but I see the output values captured is not matching with vCenter

PowerCLI output

pastedImage_0.png

vCenter output

pastedImage_1.png

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The Web Client seems to take mem.granted.average instead of mem.active.average.
The corrected code follows.

The difference in values is most probably explained by the difference in the sampling interval.

You take only 1 value, the latest.
While I suspect the Web Client looks over a longer interval and takes the average.
And before you ask, no, I don't know what interval the Web Client uses.

If you want to approach the values in the Web Client, you will have to do some experimenting with the interval duration.

$sStat = @{

        Entity = Get-VMHost -Name 'esx10' | Get-VM

        Stat = 'cpu.usagemhz.average','mem.granted.average'

        Instance = ''

        MaxSamples = 1

        Realtime = $true

        ErrorAction = 'SilentlyContinue'

    }

    Get-Stat @sStat | Group-Object -Property {$_.Entity.Name} -PipelineVariable group |

    ForEach-Object -Process {

        New-Object -TypeName PSObject -Property (

            [ordered]@{

                VmName = $group.Name

                'CPU GHz' = [math]::Round(($group.Group | where{$_.MetricId -eq 'cpu.usagemhz.average'}).Value / 1000,2)

                'Memory GB' = [math]::Round(($group.Group | where{$_.MetricId -eq 'mem.granted.average'}).Value / 1MB,2)

            }

        )

    }| Format-Table -AutoSize

  

  


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

0 Kudos
ganapa2000
Hot Shot
Hot Shot
Jump to solution

Thank you LucD. that matched the output Smiley Happy

0 Kudos
gangadhar4950
Contributor
Contributor
Jump to solution

may i know why you had used this values

1000

1MB

0 Kudos
LucD
Leadership
Leadership
Jump to solution

1000: to go from MHz to GHz.
1024: to go from KB to GB


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

0 Kudos
GLBHCLVMWARE
Contributor
Contributor
Jump to solution

 
0 Kudos
GLBHCLVMWARE
Contributor
Contributor
Jump to solution

Re: powercli script that will pull the available cpu core to consumed CPU core and availablememory

0 Kudos
LucD
Leadership
Leadership
Jump to solution

???


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

0 Kudos