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
ThompsG
Virtuoso
Virtuoso

Hi,

You could also filter the input to remove PoweredOff VMs. Something like:

$vms = Get-VM | Where { $_.PowerState -eq "PoweredOn" }

This saves checking and error handling objects that you don't want.

Just a thought...

Reply
0 Kudos
grinning_devil
Contributor
Contributor

Hello Luc,

First off, thanks for the script.  I was able to get an exported CSV file. 

But about a week or two later, when I tried it on production platform, it continued to run, I was able to see the exported file in C:\temp\....with size ZERO. 

What am I missing here !?

Reply
0 Kudos
LucD
Leadership
Leadership

This is becoming a monster thread :smileygrin:

Which script are you referring to ?

Perhaps it would be easier to start a new thread


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

Reply
0 Kudos
blaize12
Contributor
Contributor

HI Lucd,

Hope you are doing good.

Am a beginner on powercli script slowly getting a hang of it,I have tried this below script which you have posted on page1. And am getting the below operator error. can you let me know were am going wrong.

powercli.PNG

Connect-VIServer <192.168.***.***> -User <root> -Password <Password**>

$allvms = @()

$vms = Get-Vm

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

$metrics = "cpu.usage.average","mem.usage.average"

$stats = Get-Stat -Entity $vms -Start $start -Stat $metrics 

$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

  $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 |

Export-Csv "c:\VMs.csv" -noTypeInformation

Reply
0 Kudos
LucD
Leadership
Leadership

I replied to the other thread where you launched the question.


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

Reply
0 Kudos
blaize12
Contributor
Contributor

Thankyou for the quick reply and your patience.

After the correction, am able to run the script.

Capture.PNG

However, am getting a blank output with Zero Kb

Capture.PNG

let me know what need to be done.

Reply
0 Kudos
LucD
Leadership
Leadership

Can you check, is there anything in $stats and $allvms ?


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

Reply
0 Kudos
blaize12
Contributor
Contributor

where can I check the $stats and $allvms ? Is it in performance tab.\\

Capture.PNG

Reply
0 Kudos
LucD
Leadership
Leadership

No, I mean the content of those variables at the PowerCLI prompt.

Just type the name of the variable, and hit <Enter>


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

Reply
0 Kudos
blaize12
Contributor
Contributor

Thanks Lucd! It worked.

## One last thing, I want the syntax for the last one week, one month & last 5 Hrs on the below script what changes I need to do:-

_______________________________________________________________________________________________________________________--

Connect-VIServer 192.168.***.*** -User root -Password Password12

$allvms = @()

$vms = Get-Vm

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

$metrics = "cpu.usage.average","mem.usage.average"

$stats = Get-Stat -Entity $vms -Start $start -Stat $metrics  

$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

  $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 |

Export-Csv "c:\VMs.csv" -noTypeInformation

_____________________________________________________________________________________________________________________

Reply
0 Kudos
LucD
Leadership
Leadership

The Get-Stat cmdlet can take a Start and a Finish parameter.

You use these to determine the period over which you want metrics to be returned.

# Last month

$Finish = Get-Date

$start = $Finish.AddMonths(-1)

# Last week

$Finish = Get-Date

$Start = $Finish.AddDays(-7)

# Last 5 hours

$Finish = Get-Date

$Start = $Finish.AddHours(-5)


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

Reply
0 Kudos
blaize12
Contributor
Contributor

Thankyou Lucd!

______________________________________________________________________________________________________________

Connect-VIServer 192.168.***.*** -User root -Password Password12

$allvms = @()

$vms = Get-Vm

$Finish = Get-Date

$start = $Finish.AddMonths(-1)

$metrics = "cpu.usage.average","mem.usage.average"

$stats = Get-Stat -Entity $vms -Start $start -Stat $metrics

$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

  $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 |

Export-Csv "c:\VMs.csv" -noTypeInformation

_____________________________________________________________________________________________________________________

Question:- On the above highlighted in bold blue for 1 month usage report ,When I run the script am getting the output in day as (yesterdays's date) and time is  null

as below screenshot:-

Capture.PNG

please provide a syntax which display the correct date and time for the month & weeks on the above script let me know were I need to add the parameter.

Reply
0 Kudos
LucD
Leadership
Leadership

One method to format the DateTime object is the following

$vmstat.Day = $_.Group[0].Timestamp.ToString('dd/MM/yyyy')


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

Reply
0 Kudos
blaize12
Contributor
Contributor

How about for the month and hours

Do have to change it like:-

$vmstat. month = $_.Group[0].Timestamp.ToString('dd/MM/yyyy')

Reply
0 Kudos
LucD
Leadership
Leadership

Or you can leave out the days and do

$vmstat. month = $_.Group[0].Timestamp.ToString('MMM/yyyy')


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

Reply
0 Kudos
hareshn
Enthusiast
Enthusiast

Hello Luc,

What is i would like to the stats only for 2 VM ??

how do i have define condition in following section?

$allvms = @()

$vms = Get-Vm -Name VM1 and VM2

Reply
0 Kudos
Goswin_Visscher
Contributor
Contributor

You can do

$vms = Get-Vm -Name VM1,VM2

Reply
0 Kudos
hareshn
Enthusiast
Enthusiast

Thanks

Reply
0 Kudos
EChokshi
Contributor
Contributor

HI LucD,

I tried to run the below script it works nicely but it stops after 2 iterations!?

Also, how do I include Disks and Network Stats. I have referred to your previous script on the same but the output doesn't seem quite right especially when a VM may have multiple disks. 


Please help!

Thanks

-----------------------------------

Connect-VIServer **** -User **** -Password ****

$allvms = @()

$Finish = Get-Date

$start = $Finish.AddDays(-14)  # script stops iterating after 2 days ?

$metrics = "cpu.usage.average","mem.usage.average"

$stats = Get-Stat -Entity $vms -Start $start -Finish $Finish -Stat $metrics

$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.ToString('dd/MM/yyyy')

  $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 |

Export-Csv "C:\VMs.csv" -noTypeInformation

Reply
0 Kudos
LucD
Leadership
Leadership

What is in the variable $vms?

Did you do a '$vms = Get-VM'?

To include other metrics, you will have to

  1. Add the metrics to the $stats variable
  2. Add a property, and how it is calculated, to the $vmStat object


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

Reply
0 Kudos