VMware Cloud Community
edelldieguez
Contributor
Contributor
Jump to solution

Get VMs CPU and Memory Daily Usage

Good morning guys,

Will be possible to do this?, all i need is get from all our VMs the CPu and Memory Usage (Percent) for the past day (24 Hours Period) for each vm and save it in a .Csv file, also send me an email telling me that vCPU and Memory Usage Daily Report has been created, here is what will be great to have:

CPU and Memory Usage Daily Report:

VM Name | vCPUs Assigned | Max CPU Usage last day | Min CPU Usage last day | Average CPU Usage last day | Men Assigned | Max Men Usage last day | Min Men Usage last day | Average Men Usage last day |.

Appreciate any help.

Thanks in advance.Smiley Wink

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try something like this

$report = @()
$metrics = "cpu.usage.average","mem.active.average" 
$vms = Get-Vm | where {$_.PowerState -eq "PoweredOn"} 
$start = (get-date).AddDays(-1) 

Get-Stat -Entity ($vms) -start $start -stat $metrics | `
  Group-Object -Property EntityId | %{     $row = ""| Select VmName, Timestamp, vCPU, MinCpu,AvgCpu,MaxCpu,MemAlloc,MinMem,AvgMem,MaxMem     $row.VmName = $_.Group[0].Entity.Name     $row.Timestamp = ($_.Group | Sort-Object -Property Timestamp)[0].Timestamp     $row.vCPU = $_.Group[0].Entity.NumCpu     $cpuStat = $_.Group | where {$_.MetricId -eq "cpu.usage.average"} | Measure-Object -Property Value -Minimum -Maximum -Average
   
$row.MinCpu = "{0:f2}" -f ($cpuStat.Minimum)     $row.AvgCpu = "{0:f2}" -f ($cpuStat.Average)     $row.MaxCpu = "{0:f2}" -f ($cpuStat.Maximum)     $row.MemAlloc = $_.Group[0].Entity.MemoryMB     $memStat = $_.Group | where {$_.MetricId -eq "mem.active.average"} | Measure-Object -Property Value -Minimum -Maximum -Average
    $row.MinMem = "{0:f2}" -f ($memStat.Minimum)     $row.AvgMem = "{0:f2}" -f ($memStat.Average)     $row.MaxMem = "{0:f2}" -f ($memStat.Maximum)     $report += $row
} $report | Export-Csv "C:\VM-stats.csv" -NoTypeInformation -UseCulture
$smtpServer
= "MySmtpServer"
$msg = new-object Net.Mail.MailMessage
$smtp
= new-object Net.Mail.SmtpClient($smtpServer) $msg.From = "user@domain.com"
$msg.To.Add("user@domain.com") $msg.Subject = "Report created"
$msg.Body = "The report has been created"
$smtp.Send($msg)


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

View solution in original post

44 Replies
LucD
Leadership
Leadership
Jump to solution

Try something like this

$report = @()
$metrics = "cpu.usage.average","mem.active.average" 
$vms = Get-Vm | where {$_.PowerState -eq "PoweredOn"} 
$start = (get-date).AddDays(-1) 

Get-Stat -Entity ($vms) -start $start -stat $metrics | `
  Group-Object -Property EntityId | %{     $row = ""| Select VmName, Timestamp, vCPU, MinCpu,AvgCpu,MaxCpu,MemAlloc,MinMem,AvgMem,MaxMem     $row.VmName = $_.Group[0].Entity.Name     $row.Timestamp = ($_.Group | Sort-Object -Property Timestamp)[0].Timestamp     $row.vCPU = $_.Group[0].Entity.NumCpu     $cpuStat = $_.Group | where {$_.MetricId -eq "cpu.usage.average"} | Measure-Object -Property Value -Minimum -Maximum -Average
   
$row.MinCpu = "{0:f2}" -f ($cpuStat.Minimum)     $row.AvgCpu = "{0:f2}" -f ($cpuStat.Average)     $row.MaxCpu = "{0:f2}" -f ($cpuStat.Maximum)     $row.MemAlloc = $_.Group[0].Entity.MemoryMB     $memStat = $_.Group | where {$_.MetricId -eq "mem.active.average"} | Measure-Object -Property Value -Minimum -Maximum -Average
    $row.MinMem = "{0:f2}" -f ($memStat.Minimum)     $row.AvgMem = "{0:f2}" -f ($memStat.Average)     $row.MaxMem = "{0:f2}" -f ($memStat.Maximum)     $report += $row
} $report | Export-Csv "C:\VM-stats.csv" -NoTypeInformation -UseCulture
$smtpServer
= "MySmtpServer"
$msg = new-object Net.Mail.MailMessage
$smtp
= new-object Net.Mail.SmtpClient($smtpServer) $msg.From = "user@domain.com"
$msg.To.Add("user@domain.com") $msg.Subject = "Report created"
$msg.Body = "The report has been created"
$smtp.Send($msg)


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

edelldieguez
Contributor
Contributor
Jump to solution

Thank you LucD for your super fast reply, really appreciate it.

I ran your script but i got 2 errors, here is the first and its for all my VMs:

Get-Stat : 7/5/2011 1:16:23 PM    Get-Stat        The metric counter "mem.active.average" doesn't exist for entity "VM_NAME*".
At line:1 char:9
+ Get-Stat <<<<  -Entity ($vms) -start $start -stat $metrics | `
    + CategoryInfo          : ResourceUnavailable: (mem.active.average:String) [Get-Stat], VimException
    + FullyQualifiedErrorId : Client20_RuntimeDataServiceImpl_CheckUserMetrics_MetricDoesntExist,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

Here the second error:

Unexpected token 'smtp' in expression or statement.
At line:1 char:47
+ $msg.Body = "The report has been created"$smtp <<<< .Send($msg)
    + CategoryInfo          : ParserError: (smtp:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

I'm doing something wrong?

Thanks in advance.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It's possible that this specific guest was just created, that way there will not yet be any statistical values in vCenter.

That should be a warning and the script should continue.

The 2nd error was due to a <CR><LF> that got lost during the copy/paste.

I corrected the script, that should in fact have been 2 lines.


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

0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

LucD,

This error happens for all our VMs in the cluster, those VMs are running from couple of years now, we upgraded VC to a new DB but that was 2 months ago, wondering what could cause this error?

Thanks.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Then there is indeed a more serious problem.

Let's start by checking the following.

If you go to the Performance tab, in the vSphere client, for one of those VMs, can you anything in the Advanced performance ?

Make sure to select the Past Day option instead of the Realtime option.

If that doesn't show anything either it might be that the aggregation jobs that should normally run on your vCenter DB are not running.


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

0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

LucD,

Yes, in performance tab i can see CPU and Memory Usage for real time, past day, past week and past month, in the script i can get the CPU usages but not the memory usage.

Thanks.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The mem.usage.average is a level 2 metric.

That means that you must have the level set to at least 2 in <vCenter Server Settings><Statistics> on the first line, which is Historical Interval 1, to gather that metric in the VC DB.

Fyi, the cpu.usage.average metric is a level 1 metric.

If the level is set to 1 then this would explain why you see the CPU metric but not the memory metric.


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

0 Kudos
edelldieguez
Contributor
Contributor
Jump to solution

LucD,

Yes, in Statistics i have Level 1 in all of them, should i change this to Level 2 in order to get that info ??.

Thanks.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you want to get the mem.active.average metric you should set the level to at least 2.

It will take at least 1 hour before the aggregation jobs have ran and before you will see data appearing in Historical Interval 1.

In the mean time have a look at my PowerCLI & vSphere statistics – Part 1 – The basics post, which explains a bit more in detail what historical intervals and statistical levels do.


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

edelldieguez
Contributor
Contributor
Jump to solution

LucD,

Thank you for your help, it works now.

Just a question?, can i get this script modified to take the Statistics for a 24 Hours period, example the script will start at 7AM everyday and will get the stats from last day at 7AM ?, also just for a better understanding , for a specific VM in the cluster i have these values:

MinCpuUsageMaxCpuUsageAvgCpuUsage
7.1910.667.99
MinMemUsageMaxMemUsageAvgMemUsage
-198798921477.04

MaxMenUsage and AvgMemUsage are in percent ??, how can i read ex: AvgMemUsage 21477.04, what is the percent??. for CPU the maxCpuUsage in 10.66 % but i'm confused for the Memory.

I need to understand to be able to explain this to few peoples.

Thanks in advance.

Reading the link you added here, also your book is on the way, thanks for everything.

Regards.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The script request statistics from 1 day ago till now.

That's what this line is doing

$start = (get-date).AddDays(-1)

The cmdlet Get-Date returns the current day and we add -1 day (or we substract 1 day).

So yes, if you run the script at 7 AM, it will give you a report from 7 AM the day before till 7 AM today.

In PowerCLI & vSphere statistics – Part 2 – Come together I show a couple other samples on how to define the time range.

And there are a bunch of Start/Finish samples in the book (thanks for buying it btw). Smiley Happy

No, the mem.active.absolute metric returns values in KB, not percent.


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

edelldieguez
Contributor
Contributor
Jump to solution

Thanks LucD, really appreciate your help, it works like it should.

Got your book this last weekend, lot to read.

Thanks.

0 Kudos
livinma
Contributor
Contributor
Jump to solution

LucD - Saw you and Al in Vmworld in Vegas man. Excellent job on presenting and thanks for all the hardwork you guys do.

Question: To add on to this excellent script. How would I target a subset of virtual machines that are in a excel spreadsheet per say.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Thanks.

You replace this line

$vms = Get-Vm | where {$_.PowerState -eq "PoweredOn"} 

by this

$vms = Get-Vm -Name (Import-Csv "C:\vmnames.csv" -UseCulture | %{$_.Name}) |
    where {$_.PowerState -eq "PoweredOn"} 

It assumes that your CSV file looks like this

"Name"
"VM1"
"VM2"


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

0 Kudos
livinma
Contributor
Contributor
Jump to solution

Wow LucD -- Super fast reply man.. My CSV does not look like that currenlty but I will edit it to look like your example. Thanks so much.

Regards

Mark

0 Kudos
LucD
Leadership
Leadership
Jump to solution

If the Name of the VMs is in a different column in your CSV, you can easily change the code.

How do the headers of your CSV look and which column holds the name of the VMs ?


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

0 Kudos
livinma
Contributor
Contributor
Jump to solution

Hey Luc-

I just started creating my CSV and its only 15 guests so its no biggie to reflect what you have. I will change it and give it a shot now.

Thanks again

Regards

Mark 

0 Kudos
harishbisht
Contributor
Contributor
Jump to solution

Hi LucD, Many thanks for this script. How can we add disk utlisation and network utilisation in this?

Harish

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could add the metrics net.usage.average and disk.usage.average.

Just make sure that you filter on the summation aggregate ($_.Instance -eq ""), because these metrics will also return values for individual instances (vdisks and vnics).

The calculation of the avg, min and max values would follow the same logic the script uses for cpu and memory.


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

0 Kudos