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.
Hi,
You can try below code snippet. It will create two CSV files, one for Hosts and other for VMs.
Connect-VIServer <server> -User <user> -Password <password> $allvms = @() $allhosts = @() $hosts = Get-VMHost $vms = Get-Vm foreach($vmHost in $hosts){ $hoststat = "" | Select HostName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin $hoststat.HostName = $vmHost.name $statcpu = Get-Stat -Entity ($vmHost)-start (get-date).AddDays(-30) -Finish (Get-Date)-MaxSamples 10000 -stat cpu.usage.average $statmem = Get-Stat -Entity ($vmHost)-start (get-date).AddDays(-30) -Finish (Get-Date)-MaxSamples 10000 -stat mem.usage.average $cpu = $statcpu | Measure-Object -Property value -Average -Maximum -Minimum $mem = $statmem | Measure-Object -Property value -Average -Maximum -Minimum $hoststat.CPUMax = $cpu.Maximum $hoststat.CPUAvg = $cpu.Average $hoststat.CPUMin = $cpu.Minimum $hoststat.MemMax = $mem.Maximum $hoststat.MemAvg = $mem.Average $hoststat.MemMin = $mem.Minimum $allhosts += $hoststat } $allhosts | Select HostName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin | Export-Csv "c:\Hosts.csv" -noTypeInformation foreach($vm in $vms){ $vmstat = "" | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin $vmstat.VmName = $vm.name $statcpu = Get-Stat -Entity ($vm)-start (get-date).AddDays(-30) -Finish (Get-Date)-MaxSamples 10000 -stat cpu.usage.average $statmem = Get-Stat -Entity ($vm)-start (get-date).AddDays(-30) -Finish (Get-Date)-MaxSamples 10000 -stat mem.usage.average $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 | Export-Csv "c:\VMs.csv" -noTypeInformation
Hope this helps.
iwill try this and get back to you. thank you so much for your time and interest to help me.
Hi Jeveenj, how can i change the timeframe that the stats are aggregated? I need to show the stats in a graph that shows stats per hour up to one day then aggregate the per hour per day stats for the last month. I apologize for not making myself clear enough the first time. the stats your script captures are perfect but i cant show what's happening per hour in a full day over the course of last months worth of cpu and mem stats. I'm playing with the get-date command in your script but i'm new at this and its going to take time to figure out scripting in powershell. any help is more than appreciated. Thanks again,
John
Have a look at my PowerCLI & vSphere statistics – Part 2 – Come together post.
It shows how to aggregate 30 minute intervals into 1 hour intervals.
And if you look at PowerCLI & vSphere statistics – Part 1 – The basics you will see that with the Historical INterval 3 and 4 it's impossible to get hourly statistics.
If you want hourly statistics, you will have to collect them within a week and store them somewhere for later use (like a monthly report).
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi,
hope you can help with the below...
1.> How can I limit all fields of the output to less decimal places? To be honest, even no decimal places. I'd be happy with all outputs rounded to the nearest percent or MB for clarity.
2.> any way to speed the running of the script? perhaps an average over less captures. Do I just set the maxsamples to a lower value?
All help appreciated
Thanks
/nute
1) The .Net way is to call the Round function. Something like this
$value = 1.1234567
$roundedValue = [Math]::Round($value,0)
This will round the number to 0 decimal places
An laternative is to use the [int] cast
$roundedValue = [int]$value
2) Making a script faster can depend on many factors and of course what exactly is used in the script.
If you are referring to the script above, you can do the Get-Stat call for all VMHost in 1 go.
This will be considerable faster than making individual calls.
To extract the data for each VMHost, you can use the Group-Object cmdlet. See my PowerCLI & vSphere statistics – Part 4 – Grouping post for examples of the Group-Object cmdlet.
The same applies for the Get-Stat calls for the VMs.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for the quick reply
1.> please excuse my ignorance, I am new to Powerscripting. Where in the original script would I add the .Net or Int call?
2.> Accepted I depends on the scale of what the script is being run against. I am more interested in the per VM min/max/avg stats than host level at the moment. So I have commented out the host section of the script for now. Running against approximately 150 VMs across 2 clusters.
Appreciate the help. Your information and replies have already helped alot on my learning curve with PowerCLI
/nute
1) You could do the conversion when you assign the values
$vmstat.CPUMax = [int]$cpu.Maximum
$vmstat.CPUAvg = [int]$cpu.Average
$vmstat.CPUMin = [int]$cpu.Minimum
$vmstat.MemMax = [int]$mem.Maximum
$vmstat.MemAvg = [int]$mem.Average
$vmstat.MemMin = [int]$mem.Minimum
2) I would do only 1 call to Get-Stat, outside the foreach loop
$stats = Get-Stat -Entity $vms-start (get-date).AddDays(-30) -Finish (Get-Date)-MaxSamples 10000 -stat "cpu.usage.average","
mem.usage.average
"
You can then use the Group-Object to split out the individual VM
Inside each group you can use the where clause to filter out the Memory and the CPU values.
$stats | Group-Object -Property Entity | %{
$cpu = $_.Group | where {$_.MetricId -eq
"cpu.usage.average"} |
Measure-Object -Property value -Average -Maximum -Minimum
$mem =
$_.Group | where {$_.MetricId -eq"mem.usage.average"} |
Measure-Object -Property value -Average -Maximum -Minimum
...
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Top notch! Great help. Thanks
Nute / LuCD,
Can one of you please post the final script? I've tried piecing together the pieces, but I can't seem to get it to work. 😕
Greatly Appreciative,
Joe
The following is for the VMs, the ESX(i) hosts loop is similar
Connect-VIServer <server> -User <user> -Password <password> $allvms = @() $vms = Get-Vm
$stats = Get-Stat -Entity $vms -start (get-date).AddDays(-30) -Finish (Get-Date)-MaxSamples 10000 -stat "cpu.usage.average","mem.usage.average" $stats | Group-Object -Property Entity | %{ $vmstat = "" | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin
$vmstat.VmName = $_.name $cpu = $_.Group | where {$_.MetricId -eq "cpu.usage.average"} | Measure-Object -Property value -Average -Maximum -Minimum
$mem = $_.Group | where {$_.MetricId -eq "mem.usage.average"} | Measure-Object -Property value -Average -Maximum -Minimum
$vmstat.CPUMax = [int]$cpu.Maximum $vmstat.CPUAvg = [int]$cpu.Average $vmstat.CPUMin = [int]$cpu.Minimum $vmstat.MemMax = [int]$mem.Maximum $vmstat.MemAvg = [int]$mem.Average $vmstat.MemMin = [int]$mem.Minimum $allvms += $vmstat
} $allvms | Select VmName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin | Export-Csv "c:\VMs.csv" -noTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Uh, I was so close! This is awesome, thanks again!
2 things that I noticed, just for reference:
1. I have a few VMs in my environment that are not turned on, and haven't been for a while. I had to modify the script a little bit to only include powered-on VMs, as I was getting an error running it against all VMs. I just changed $vms = Get-VM to $vms = Get-VM | where {$_.PowerState -eq "PoweredOn"}
2. Although my script runs fine, and the VMs.csv is created successfully, with all the VMs listed, I still show a value of 0 for all metrics. Come to find out, the 'Metric' value didn't exist and was actually 'MetricId'. I just had to change the 'where' statement in the $cpu and $mem calcs from where {$_.Metric -eq "cpu.usage.average"} to where {$_.MetricId -eq "cpu.usage.average"}
Hope that helps someone. Thanks again LucD!
~Joe
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi Luc,
How are you ?
I´d like know how i can do to get clusters and create a column in cvs with classification of each hosts putting corresponding cluster
Example
host1 cluster min max avg
vmware1 lab-1 x y z
thank you
The simplest, but not most efficient, way is to use the Get-Cluster cmdlet.
Suppose you have the ESX(i) in $vmhost, then you can do
$cluster = (Get-Cluster -VMHost $vmhost).Name
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi
I am looking for the script which you are talking about for generating my weekly report to my client.
I tried using this script but got errors.
can you share the script which you are using.
Thanks in advance!!!
Hi LucD,
Thanks for sharing!!!!
Actually i tried using this script where i got errors and didn't get any output just got a blank csv file.
I have started using the PCLI Scripts newly.
Can you please help me in using this script and get my report done.
Actually we are planning to get weekly report for CPU & Memory usage for both the ESX & VM.
Thanks in advance!!
Which script are you trying to use (there are several in this thread) ?
And which errors are you getting ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi jeevanj,
I have used this scripts. Thnaks for providing it is very useful.
Actually i am new to this scripting. (just running the script and retriving data from it)
But what modifications i can do so that i can have this information daily so that i can plot some graphs which i can use for my weekly report.
Please help me in this.....
Thanks in advance!!!