PowerCLI

 View Only
Expand all | Collapse all

Get VMs CPU and Memory Daily Usage

  • 1.  Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 03:45 PM

    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.:smileywink:



  • 2.  RE: Get VMs CPU and Memory Daily Usage
    Best Answer

    Posted Jul 05, 2011 04:30 PM

    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)


  • 3.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 05:24 PM

    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.



  • 4.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 05:29 PM

    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.



  • 5.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 05:34 PM

    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.



  • 6.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 06:33 PM

    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.



  • 7.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 06:38 PM

    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.



  • 8.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 06:43 PM

    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.



  • 9.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 06:57 PM

    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.



  • 10.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 07:03 PM

    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.



  • 11.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 08:27 PM

    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.



  • 12.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 05, 2011 08:45 PM

    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). :smileyhappy:

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



  • 13.  RE: Get VMs CPU and Memory Daily Usage

    Posted Jul 11, 2011 02:55 PM

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

    Got your book this last weekend, lot to read.

    Thanks.



  • 14.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 21, 2017 07:58 AM

    Hi LucD,

    How can I get this report for 30 days?

    I did the following changes

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

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

    Get-Stat -Entity ($vms) -start $start -finish $finish -stat $metrics

    However, the csv gives me output for any random date in the month. Any pointers would be helpful.



  • 15.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 21, 2017 08:39 AM

    The $start and $finish should be ok, could it be that the data just needs sorting on the Timestamp?



  • 16.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 21, 2017 08:52 AM

    Thanks for the quick reply LucD.

    The timestamp is exactly 30 days back from when the report was run for 98% of VM's, for the other 2% it is scattered across the month (possibly the VM's were newly created or were powered down).

    So does it mean that it has considered just that single day for the report?



  • 17.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 21, 2017 09:03 AM

    That timestamp would be the first day which it has considered in calculating the statistics.

    The statistics would be calculated from that day till the $finish date, unless there have been other stop/start of the VM in between.



  • 18.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 21, 2017 09:41 AM

    Thanks LucD.

    So this would mean that the data I have in the csv would be for the period between the date present in the timestamp and the last date that I have specified in the script.



  • 19.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 21, 2017 09:45 AM

    That is correct



  • 20.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 21, 2017 09:47 AM

    Thanks for your help!! Appreciate it.



  • 21.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 24, 2017 06:06 AM

    Hi again,

    What would be the best possible way to loop this day wise, so that I can get a daily data for all VM's for past 30 days?



  • 22.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 24, 2017 06:19 AM

    The Group-Object cmdlet is ideal for that, group on the day in the timestamp.

    Something like this for example

    $esx = Get-VMHost

    Get-Stat -Entity $esx -Start (Get-Date).AddDays(-7) |

    Group-Object -Property {$_.Timestamp.Day}



  • 23.  RE: Get VMs CPU and Memory Daily Usage

    Posted Apr 25, 2017 06:27 AM

    I am bit new to Power Cli :smileyhappy:

    can we pull same report as per folder structure in VM and Templates.

    in my organization i need to show the utilization of the VM  as per the folder(teams).

    Thanks in advance.

    cheers



  • 24.  RE: Get VMs CPU and Memory Daily Usage

    Posted Sep 30, 2011 01:24 PM

    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.



  • 25.  RE: Get VMs CPU and Memory Daily Usage

    Posted Sep 30, 2011 01:31 PM

    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"


  • 26.  RE: Get VMs CPU and Memory Daily Usage

    Posted Sep 30, 2011 01:37 PM

    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



  • 27.  RE: Get VMs CPU and Memory Daily Usage

    Posted Sep 30, 2011 01:39 PM

    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 ?



  • 28.  RE: Get VMs CPU and Memory Daily Usage

    Posted Sep 30, 2011 01:45 PM

    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 



  • 29.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 04, 2011 02:30 PM

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

    Harish



  • 30.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 04, 2011 03:26 PM

    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.



  • 31.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 04, 2011 03:30 PM

    Thanks for the reply. let me try this. also want to know wht do to if vms are in cluster?

    I got the following error:

    Get-Stat : 10/4/2011 8:05:22 PM    Get-Stat        Object reference not set to an instance of an object.At C:\test.ps1:6 char:9
    + Get-Stat  <<<< -Entity ($vms) -start $start -stat $metrics | `Group-Object -Poperty EntityId | %{

    when using $vms = Get-Cluster -Name XXXX |Get-Vm | where {$_.PowerState -eq "PoweredOn"}

    Harish



  • 32.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 05, 2011 10:38 AM

    Hi LucD, Any Suggestion on this.

    Harish



  • 33.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 05, 2011 12:11 PM

    It looks as if the variable $vms is empty.

    Does

    Get-Cluster -Name XXXX | Get-Vm | where {$_.PowerState -eq "PoweredOn"}

    return anything ?



  • 34.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 05, 2011 12:21 PM

    yes I got list of VMs when run

    Get-Cluster -Name XXXX | Get-Vm | where {$_.PowerState -eq "PoweredOn"}

    Actully I got properresponce for some VMs also but it stuck in the middle. like VM1,VM3,VM4 .....

    I am working on this issue from yesterday and found some thing insteresting.

    when I run script with perticular vm like VM1

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

    I got proper responce.

    but when I repeat it with VM5 it give me the error :

    Get-Stat : 10/5/2011 5:48:46 PM    Get-Stat        Object reference not set to an instance of an object.
    At C:\test.ps1:6 char:9
    + Get-Stat <<<<  -Entity ($vms) -start $start -stat $metrics | `Group-Object -Property EntityId | %{
        + CategoryInfo          : NotSpecified: (:) [Get-Stat], VimException
        + FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetViStats

    there is something wrong with this VM5 but I unable to find it.

    Harish



  • 35.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 05, 2011 12:34 PM

    That probably means there is no statistical data available for that specific VM.

    Do you see data when using the Performance tab for VM for the datetime range you use in the script ?

    The script will still complete and return the data for the VMs where there was statistical data available.



  • 36.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 05, 2011 12:47 PM

    Yes you are correct. I am not able to see last week data for CPU & Memory in performance tab. But able to see the real time data only. thats the issue. How can I chk for this?

    Is that possible in this script to bypass those VMs that do not having any statistical data?

    Harish



  • 37.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 05, 2011 01:36 PM

    That depends, if these VMs were created recently, it's possible that the aggregation for ther statistical data wasn't don yet.

    You can also check the Statistics level on the vCenter.

    To avoid the VMs that do not have statistical data, is a kind of a chicken-and-the-egg problem, to check if there is data, you will have to try to fetch the data.

    Easiest is to suppress the error message with the -ErrorAction SilentlyContinue parameter. You won't see the error messages anymore at least.



  • 38.  RE: Get VMs CPU and Memory Daily Usage

    Posted Oct 13, 2011 12:20 PM

    Thanks LucD,

    the script worked for me  But I have to put the all vm names (one time job only).

    ###############################################################################################

    $report = @()
    $metrics = "cpu.usage.average","mem.usage.average","disk.usage.average","net.usage.average"
    $vms = Get-Vm | where {$_.PowerState -eq "PoweredOn"}
    $start = (Get-Date).adddays(-7)

    Get-Stat -Entity ($vms) -start $start -stat $metrics | `Group-Object -Property EntityId | %{
        $row = ""| Select VmName, Timestamp, vCPU, MinCpu,AvgCpu,MaxCpu,MemAlloc,MinMem,AvgMem,MaxMem,Mindisk,Avgdisk,Maxdisk,Minnic,Avgnic,Maxnic
        $row.VmName = $_.Group[0].Entity.N
        $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.usage.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)
        $row.vdisk = $_.Group[0].Entity.vdisks
        $diskStat = $_.Group | where {$_.MetricId -eq "disk.usage.average"} | Measure-Object -Property Value -Minimum -Maximum -Average   
        $row.Mindisk = "{0:f2}" -f ($diskStat.Minimum)
        $row.Avgdisk = "{0:f2}" -f ($diskStat.Average)
        $row.Maxdisk = "{0:f2}" -f ($diskStat.Maximum)
        $row.vnic = $_.Group[0].Entity.vnic
        $netStat = $_.Group | where {$_.MetricId -eq "net.usage.average"} | Measure-Object -Property Value -Minimum -Maximum -Average   
        $row.Minnic = "{0:f2}" -f ($netStat.Minimum)
        $row.Avgnic = "{0:f2}" -f ($netStat.Average)
        $row.Maxnic = "{0:f2}" -f ($netStat.Maximum)
            $report += $row}
    $report | Export-Csv "C:\test.csv" -NoTypeInformation

    ################################################################



  • 39.  RE: Get VMs CPU and Memory Daily Usage

    Posted Mar 01, 2021 04:41 PM

    Hi LucD,

    I am using your script to pull CPU and memory usage of VMs (last one day or month).

    CPU usage pulled using script is same as I am seeing it in vsphere, however, memory stats are not matching.

    Am i missing anything? Actually, i want to pull maximum memory usage for all VMs.

    Script output for one VM:

    VmName : XYZ
    Timestamp : 1/02/2021 19:00:00
    vCPU : 4
    MinCpu : 2,93
    AvgCpu : 4,08
    MaxCpu : 14,82
    MemAlloc : 32768
    MinMem : 385254,00
    AvgMem : 542721,47
    MaxMem : 2963973,00

    But in vcenter, its is showing 19,216,612 (MaxMem)  



  • 40.  RE: Get VMs CPU and Memory Daily Usage

    Posted Mar 01, 2021 05:21 PM

    There are a few points to consider

    - the Maximum metric is only captured when the Statistics Level for the Historical Interval you are looking at is sufficiently high
    - Historical Intervals show aggregated values, meaning that these are averages of a specific period (for Last Month that is 1 value per day)
    - which VCSA data are you looking at? The current values or the values under Performance?

    If you want to compare current values shown in the VCSA, you will have to retrieve metrics with the Realtime switch



  • 41.  RE: Get VMs CPU and Memory Daily Usage

    Posted Mar 02, 2021 07:55 AM

    Thanks for your response LucD!

    I want to capture mainly Maximum Memory usage of all the VMs for last year or month, the one that we see under performance (Advanced>Memory>Consumed).

    We will use this report to reduce memory allocation of the VMs where its not being used completly as we are seeing resource crunch on the complete cluster.



  • 42.  RE: Get VMs CPU and Memory Daily Usage

    Posted Mar 02, 2021 08:18 AM

    You will need Statistics Level 4 for Historical Interval 4 (Past Year).
    If that is not already set a year ago, you will not have the Maximum values.
    Also, note that setting that Statistics Level will increase the size of your VCSA DB enormously.

    The next best thing is to use the Average and look for maximums in those.
    But with only 1 observation per day (for the Past Year interval), I'm not sure that will produce any valid data to make justified decisions about memory allocation.



  • 43.  RE: Get VMs CPU and Memory Daily Usage

    Posted Mar 04, 2021 07:41 AM

    Thanks LucD!

    We have Statistics Level 2 set in or environment. Ideally, it should provide max and min memory usage i guess but not sure for how much historical data we can consider valid.

    Level 2
    • Level 1 metrics
    • CPU – idle, reservedCapacity
    • Disk – All metrics, excluding numberRead and numberWrite.
    • Memory – All metrics, excluding memUsed and maximum and minimum rollup values.
    • Virtual Machine Operations – All metrics
    Use for long-term performance monitoring when device statistics are not required but you want to monitor more than the basic statistics.


  • 44.  RE: Get VMs CPU and Memory Daily Usage

    Posted Mar 04, 2021 08:06 AM

    I don't think so, it clearly states "... excluding memUsed and maximum and minimum rollup values."



  • 45.  RE: Get VMs CPU and Memory Daily Usage

    Posted Mar 04, 2021 12:03 PM

    I got active memory usage matched (script=vcenter), though its not same at OS level.

    Apologies for the confusion (I was matching consumed memory which should not be the case).

     

    Thanks again for the wonderful script!!