VMware Cloud Community
bottomofbarrel
Contributor
Contributor

powercli script to capture cpu & mem usage stats

i am new to powercli and am not a good scriptor yet however, i need a script that will capture the max, min, avg cpu & mem usage stats per esxhost & vm for the past month and import into excel so i can create a pivot chart. key is i need to see the cpu/mem usage data per vm per host. can anyone help me with this. i have spent the last two weeks trying to work with powercli to do this and i am unable produce the results i want.

171 Replies
vijayrana968
Virtuoso
Virtuoso

Right, you can make tweak here...

You can save this script and schedule it in task scheduler to run at 7:00 PM Sharp.

Before saving, set hours value to 10 like '(Get-Date).AddHours(-10)' so when scrpit run at 7:00 PM, it get current date and time which is 7PM and then it look status for last 10 hours which is from 9:00 AM to 7:00 PM.

Reply
0 Kudos
hareshn
Enthusiast
Enthusiast

Thanks that make sense, but what about i want to run that on only monthly basis, and wanted result only for the business hours?

Reply
0 Kudos
vijayrana968
Virtuoso
Virtuoso

For this custom report, I would recommend you to use free monitoring tool if you haven't any enterprise tool in your Org.

FREE VM Monitor - VMWare & Hyper-V Monitoring Tools | SolarWinds

http://vmturbo.com/downloads/vmturbo-virtual-health-monitor

You can view and export custom reports there.

Reply
0 Kudos
hareshn
Enthusiast
Enthusiast

Hi LucD,

I am using below script to get hourly host utilization, below script gives me only single host in the cluster. what about if i wanted to have all host CPU usage in the single csv file?

$esxName = "esx01"

$esxImpl = Get-VMHost -Name $esxName

$todayMidnight = (Get-Date -Hour 0 -Minute 0 -Second 0).AddMinutes(-1)

$stats = Get-Stat -Entity $esxImpl -Stat cpu.usage.average -Start $todayMidnight.AddDays(-5) -Finish $todayMidnight.AddDays(-4)

$groups = $stats | Group-Object -Property {$_.Timestamp.Hour, $_.Instance}

$report = $groups | % {

  New-Object PSObject -Property @{

    Description = $_.Group[0].Description

    Entity = $_.Group[0].Entity

    MetricId = $_.Group[0].MetricId

    Timestamp = $_.Group[0].Timestamp.Date.AddHours($_.Group[0].Timestamp.Hour)

    Unit = $_.Group[0].Unit

    Value = [math]::Round(($_.Group | Measure-Object -Property Value -Average).Average, 2)

  }

}

$report | Export-Csv "C:\Hourly-cpu.csv" -NoTypeInformation -UseCulture

Reply
0 Kudos
sydabr
Contributor
Contributor

Hi,

can we have this script modified to get stats based on per cluster, instead of all hosts and all vms only

Reply
0 Kudos
jim33boy
Enthusiast
Enthusiast

Hello Mr. LucD, big fan.

I am trying to adjust your script to group by vm and then by hour instead of day because I am collecting realtime stats. I will run once per day for a daily report.

So in your script here you use the timestamp.day to group as well as the Entity.Name. I want to do something like Timestamp.hour and   Entity.Name.

$stats | Group-Object -Property {$_.Timestamp.Day},{$_.Entity.Name} | %{
 
$vmstat = "" | Select VmName, Day, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin
  $vmstat.VmName = $_.Values[1]
 
$vmstat.Day = $_.Group[0].Timestamp.Date


can you please help me to adjust this part? I tried running with timestamp.hour but the grouping does not work.


Thanks

Reply
0 Kudos
LucD
Leadership
Leadership

You would have to do a nested Group-Object, other wise you would have the same hour for all days in the same loop iteration.

Something like this for example

$stats | Group-Object -Property {$_.Timestamp.Day},{$_.Entity.Name} | %{

  $_.Group | Group-Object -Property {$_.Timestamp.Hour} | %{

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

      $vmstat.VmName = $_.Values[1]

      $vmstat.Day = $_.Group[0].Timestamp.Date

  }

}


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

Reply
0 Kudos
jim33boy
Enthusiast
Enthusiast

Thanks LucD

I am only collecting for one day, I believe realtime stats are only kept for 1 day before they are aggregated in the 5 minute rollups.

So since I am doing realtime stats I wanted to do timestamp.hour instead of timestamp.day. I will play with it and see if I can get it going.

Thanks again

Reply
0 Kudos
russjar
Enthusiast
Enthusiast

Hey all,

This is a great script. Can it be updated to include the vm guest os type to help with filtering in excel?

Thanks in advance...

VCP,MCSE NT4/W2k/W2k3, MCSA W2k3
Reply
0 Kudos
LucD
Leadership
Leadership

Not sure which of the many variations on the original script in this thread your are using, but the statistical data does contain the full VM properties under the Entity property.

Note that the following requires to have the VMware Tools to be installed on the VMs.

$allvms = @()

$vms = Get-VM

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

$stats = 'cpu.usage.average','mem.usage.average'

Get-Stat -Entity $vms -Start $start -Stat $stats |

Group-Object -Property {$_.Timestamp.Day},{$_.Entity.Name} | %{

  $vmstat = "" | Select VmName, Day, OS, MemAvg, CPUAvg

  $vmstat.VmName = $_.Values[1]

  $vmstat.OS = $_.Group[0].Entity.ExtensionData.Guest.GuestFullName

  $vmstat.Day = $_.Group[0].Timestamp.Date

  $vmstat.CpuAvg = $_.Group | where {$_.MetricId -eq "cpu.usage.average"} | Measure-Object -Property value -Average | Select -ExpandProperty Average

  $vmstat.MemAvg = $_.Group | where {$_.MetricId -eq "mem.usage.average"} | Measure-Object -Property value -Average | Select -ExpandProperty Average

  $allvms += $vmstat

}

$allvms


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

Reply
0 Kudos
hareshn
Enthusiast
Enthusiast

Hello LucD,

start (get-date).AddDays(-7) gives last 7 days result. but what about i need something like

Current date : 16th Nov 2015 and I would like to pull report from 1st Nov to 7th Nov ?

thanks

Reply
0 Kudos
grinning_devil
Contributor
Contributor

Hello Luc !

Let me reply to an old comment of yours Smiley Happy

I did tried the script, and it works fine for CPU/Memory etc  - I am looking for all 4 components in the export for a group of VM's - CPU, Memory, Datastore and Network - Peak Usage in all these components in the last 2 months or so.  Can you please help out here ?!

Reply
0 Kudos
LucD
Leadership
Leadership

You mean something like this ?

$vms = Get-VM

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

$stats = 'cpu.usage.average','mem.usage.average','disk.usage.average','net.usage.average'

Get-Stat -Entity $vms -Start $start -Stat $stats -Instance "" |

#Get-Stat -Entity $vms -Realtime -MaxSamples 1 -Stat $stats -Instance "" |

Group-Object -Property {$_.Timestamp.Day},{$_.Entity.Name} | %{

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

    VmName = $_.Values[1]

    OS = $_.Group[0].Entity.ExtensionData.Guest.GuestFullName

    Day = $_.Group[0].Timestamp.Date

    'CpuAvg %' = $_.Group | where {$_.MetricId -eq "cpu.usage.average"} | Measure-Object -Property value -Average | Select -ExpandProperty Average

    'MemAvg %' = $_.Group | where {$_.MetricId -eq "mem.usage.average"} | Measure-Object -Property value -Average | Select -ExpandProperty Average

    'DiskAvg KBps' = $_.Group | where {$_.MetricId -eq "disk.usage.average"} | Measure-Object -Property value -Average | Select -ExpandProperty Average

    'NetAvg KBps' = $_.Group | where {$_.MetricId -eq "net.usage.average"} | Measure-Object -Property value -Average | Select -ExpandProperty Average

  })

  

} | Export-Csv report.csv -NoTypeInformation -UseCulture


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

Reply
0 Kudos
Nomi_epc
Enthusiast
Enthusiast

LucD

Hi Lucd,

I have tried your above script and got the attached error. Could you please help me out on this Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership

It looks like the $vms variable is empty.

Did you do the Get-VM at the top of the last script ?

What is in $vms ?


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

Reply
0 Kudos
Nomi_epc
Enthusiast
Enthusiast

I just copied your script on this post and tried didn't change or add anything.

Basically i want to pull the same information in my multi cluster environment on per VM basis.

Reply
0 Kudos
MasaNakano
Enthusiast
Enthusiast

Hi!

In that case, I think the specification, -MaxSamples 10000 for a month, means that the sample rate to retrieve the usage is roughly 5 minutes.

Does vSphere actually measure the usage every 5 minute?

Thanks,

Masa

Regards, - Masa
Reply
0 Kudos
icrow1978
Contributor
Contributor

Hi LucD,

Im trying to add the -ErrorAction Slientlycontinue for bypass VM that are poweroff but i got the following error :

Get-Stat : Cannot bind parameter 'ErrorAction'. Cannot convert value "SlientlyC

ontinue" to type "System.Management.Automation.ActionPreference" due to invalid

enumeration values. Specify one of the following enumeration values and try ag

ain. The possible enumeration values are "SilentlyContinue, Stop, Continue, Inq

uire".

At C:\PS-Scripts\cpu-mem-stats-PAV.ps1:15 char:31

+ $stats = Get-Stat -ErrorAction <<<<  SlientlyContinue -Entity $vms -start (ge

t-date).AddDays(-7) -Finish (Get-Date)-MaxSamples 10000 -stat "cpu.usage.averag

e","mem.usage.average"

    + CategoryInfo          : InvalidArgument: (:) [Get-Stat], ParameterBindin

   gException

    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomat

   ion.ViCore.Cmdlets.Commands.GetViStats

Also i have another question, if a want a report of VM with the last 7 days , i need to chane the AddDay(-30) to -7 .Thats right?

$stats = Get-Stat -Entity $vms -start (get-date).AddDays(-7) -Finish (Get-Date)-MaxSamples 10000 -stat "cpu.usage.average","mem.usage.average"  ?

Best regards

Reply
0 Kudos
LucD
Leadership
Leadership

I think you might have a typo in SilentlyContinue.

Yes, that is how you would specify the last 7 days.


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

Reply
0 Kudos
icrow1978
Contributor
Contributor

THanks!!!

DIONE!!

10 pts

Reply
0 Kudos