VMware Cloud Community
Rajeev_S
Expert
Expert
Jump to solution

get-stat monthly report

Hi,

I'm trying to script the stats on a monthly basis. I'm using the below script,

Get-Stat -Entity (Get-Cluster -Name x) -start (get-date).AddDays(-30) -Finish (Get-Date) -MaxSamples 1000 -stat cpu.usagemhz.average | Export-Csv -Path c:\test.csv

It outputs based on time with 30 min interval.

Is it possible to get it as a single value for a month as it shows in VC ??

Also can we get the Max value reached in the cluster for the particular month.

Hope my question is clear!!!!!

Thanks

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

This should do what you want.

$allclust = @()
$clust = Get-Cluster

foreach($clu in $clust){
  $clusstat = "" | Select ClusterName, MemMax, MemAvg, CPUMax, CPUAvg
  $clusstat.ClusterName = $clu.name
  
  $statcpu = Get-Stat -Entity ($clu) `
           -start (get-date).AddDays(-30) `
           -Finish (Get-Date) `
	       -MaxSamples 10000 `
		   -stat cpu.usagemhz.average
  $statmem = Get-Stat -Entity ($clu) `
           -start (get-date).AddDays(-30) `
           -Finish (Get-Date) `
	       -MaxSamples 10000 `
		   -stat mem.usage.average

  $cpu = $statcpu | Measure-Object -Property value -Average -Maximum
  $mem = $statmem | Measure-Object -Property value -Average -Maximum
  
  $clusstat.CPUMax = $cpu.Maximum
  $clusstat.CPUAvg = $cpu.Average
  $clusstat.MemMax = $mem.Maximum
  $clusstat.MemAvg = $mem.Average
  
  $allclust += $clusstat
}

$allclust | `
  select ClusterName, MemMax, MemAvg, CPUMax, CPUAvg | `
  Export-Csv "c:\g.csv" -noTypeInformation


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

View solution in original post

0 Kudos
33 Replies
LucD
Leadership
Leadership
Jump to solution

Sure, you can use the Measure-Object cmdlet for that.

This will give you the maximum value for the period you are measuring

Get-Stat -Entity (Get-Cluster -Name x) -start (get-date).AddDays(-30) -Finish (Get-Date) -MaxSamples 1000 -stat cpu.usagemhz.average | `
Measure-Object -property Value  -maximum | select Maximum | Out-Default

With the Measure-Object you can get the maximum, minimum, average and the sum.


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

Rajeev_S
Expert
Expert
Jump to solution

Thanks LucD. That helped. I'm trying to put it in a proper format for all the cluster in my environment,

$clust = Get-Cluster

foreach($clu in $clust)

{Get-Stat -Entity ($clu) -start (get-date).AddDays(-30) -Finish (Get-Date) -MaxSamples 10000 -stat cpu.usagemhz.average | Measure-Object -Property value -Average -Maximum | select $clu.name, average, maximum | Out-File -Append c:\g.csv}

out-file doesnt format that correctly.. I'm not sure how to use export-csv cmdlet in this scenario.

Also can i add the memory avg & max value along with CPU values in the same report. My report should look like

ClusterName Memory Max Avg CPU Max Avg

Could anyone guide me to do that.

Thanks

0 Kudos
LucD
Leadership
Leadership
Jump to solution

This should do what you want.

$allclust = @()
$clust = Get-Cluster

foreach($clu in $clust){
  $clusstat = "" | Select ClusterName, MemMax, MemAvg, CPUMax, CPUAvg
  $clusstat.ClusterName = $clu.name
  
  $statcpu = Get-Stat -Entity ($clu) `
           -start (get-date).AddDays(-30) `
           -Finish (Get-Date) `
	       -MaxSamples 10000 `
		   -stat cpu.usagemhz.average
  $statmem = Get-Stat -Entity ($clu) `
           -start (get-date).AddDays(-30) `
           -Finish (Get-Date) `
	       -MaxSamples 10000 `
		   -stat mem.usage.average

  $cpu = $statcpu | Measure-Object -Property value -Average -Maximum
  $mem = $statmem | Measure-Object -Property value -Average -Maximum
  
  $clusstat.CPUMax = $cpu.Maximum
  $clusstat.CPUAvg = $cpu.Average
  $clusstat.MemMax = $mem.Maximum
  $clusstat.MemAvg = $mem.Average
  
  $allclust += $clusstat
}

$allclust | `
  select ClusterName, MemMax, MemAvg, CPUMax, CPUAvg | `
  Export-Csv "c:\g.csv" -noTypeInformation


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

0 Kudos
Rajeev_S
Expert
Expert
Jump to solution

Thanks LucD. You got me exactly what i was looking for. Amazing

0 Kudos
grog
Contributor
Contributor
Jump to solution

Luc,

Is there a way to make this report work for vms instead of the cluster? I am looking to report on average CPU and Memory utilization for vms over a month period. I would like to output to either csv or html. Any ideas?

Thanks,

Marc

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, shouldn't be too hard.

Try something like this

$allvms = @()
$vms = Get-Vm

foreach($vm in $vms){
  $vmstat = "" | Select VmName, MemMax, MemAvg, CPUMax, CPUAvg
  $vmstat.VmName = $vm.name
  
  $statcpu = Get-Stat -Entity ($vm) `
           -start (get-date).AddDays(-30) `
           -Finish (Get-Date) `
	       -MaxSamples 10000 `
		   -stat cpu.usagemhz.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
  $mem = $statmem | Measure-Object -Property value -Average -Maximum
  
  $vmstat.CPUMax = $cpu.Maximum
  $vmstat.CPUAvg = $cpu.Average
  $vmstat.MemMax = $mem.Maximum
  $vmstat.MemAvg = $mem.Average
  
  $allvms += $vmstat
}

$allvms | `
  select VmName, MemMax, MemAvg, CPUMax, CPUAvg | `
  Export-Csv "c:\VMs.csv" -noTypeInformation


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

0 Kudos
grog
Contributor
Contributor
Jump to solution

Thanks LucD! Huge help! One more question for you? Is there anyway to gather this data for work hours only? Say 9am-5pm? I think the 24 hour period may skew the data a bit being that most of the vms are sitting idle over night. I would love to pinpoint this data to work hours.

Thanks,

Marc

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm afraid that is not possible with the Get-Stat cmdlet itself, nor with the underlying QueryPerf method from the SDK.

You could get all your statistical data and then use a Select-Object or an If-Then-Else construct on the Timestamp property to filter out the data you want.


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

0 Kudos
admin
Immortal
Immortal
Jump to solution

Luc.. that was superb!

Question:

How do I change the syntax for the date period?

This subroutine:

-start (get-date).AddDays(-30) `
-Finish (Get-Date) `

My intent is to go back 30 days at a time.. If I can go perhaps start and finish dates per calender 30 days..

aug, july, june etc.

As is it runs date executed script minus 30 days.

Merci! Thanks!

-Vuong

p.s. also I guess it is one vcenter at a time. I tried to connect-viserver to multiple vcenters, but the ouput wasn't there.

I assume it was the output file doesn't append.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

With a bit of conversion you could use the actual calendar months.

The following script shows you the last 12 calendar months.

$thisMonth = [datetime](Get-Date -Format "y")
12..1 | %{
	$from = $thisMonth.AddMonths(- $_)
	$to = $thisMonth.AddMonths(- $_ + 1).AddDays(-1)
	
}

If you use the $from in the -Start parameter and the $to in the -Finish parameter you can pull reports over the last 12 calendar months.


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

0 Kudos
admin
Immortal
Immortal
Jump to solution

Hmm

I tried (still learning) to modify the code:

$allclust = @()

$clust = Get-Cluster

foreach($clu in $clust){

$clusstat = "" | Select ClusterName, MemMax, MemAvg, CPUMax, CPUAvg

$clusstat.ClusterName = $clu.name

$thisMonth = datetime(Get-Date -Format "y")

12..1 | %{

$from = $thisMonth.AddMonths( - $_)

$to = $thisMonth.AddMonths( - $_ + 1).AddDays(-1)

}

$statcpu = Get-Stat -Entity ($clu) `

-start (get-date).AddDays(-30) `

-Finish (Get-Date) `

-MaxSamples 10000 `

-stat cpu.usagemhz.average

$statmem = Get-Stat -Entity ($clu) `

-start (get-date).AddDays(-30) `

-Finish (Get-Date) `

-MaxSamples 10000 `

-stat mem.usage.average

$cpu = $statcpu | Measure-Object -Property value -Average -Maximum

$mem = $statmem | Measure-Object -Property value -Average -Maximum

$clusstat.CPUMax = $cpu.Maximum

$clusstat.CPUAvg = $cpu.Average

$clusstat.MemMax = $mem.Maximum

$clusstat.MemAvg = $mem.Average

$allclust += $clusstat

}

$allclust | `

select ClusterName, MemMax, MemAvg, CPUMax, CPUAvg | `

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

But I got a syntax error:

The term 'datetime' is not recognized as a cmdlet, function, operable program, or script fil

again.

At C:\Documents and Settings\phamv\Desktop\clusterstats2.ps1:7 char:22

+ $thisMonth = datetime <<<< (Get-Date -Format "y")

+ CategoryInfo : ObjectNotFound: (datetime:String) [], CommandNotFoundException

+ FullyQualifiedErrorId : CommandNotFoundException

You cannot call a method on a null-valued expression.

At C:\Documents and Settings\phamv\Desktop\clusterstats2.ps1:9 char:30

+ $from = $thisMonth.AddMonths <<<< ( - $_)

+ CategoryInfo : InvalidOperation: (AddMonths:String) [], RuntimeException

+ FullyQualifiedErrorId : InvokeMethodOnNull

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That's a problem of the forum sw that has problems with square brackets.

The line should read: $thisMonth = \[datetime\](Get-Date -Format "y").

But the way you inserted my sample code in the script won't work.

I gave those last lines as an example of how to get the actual start and finish dates for the last 12 calendar months.

Attached (to avoid the square brackets problem) a script that gets the report for the previous calendar month.

I hope this clarifies a bit what I was trying to show.


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

0 Kudos
admin
Immortal
Immortal
Jump to solution

LucD

sorry to be so dense. I haven't had a chance to visit this topic in a while. I still don't understnad the formating syntax to get the last full 12 calendar months?

Could you explain? Thank you very much.

V

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, I'll give it a try

This was the skeleton code to get the last 12 months

$thisMonth = [datetime](Get-Date -Format "y")
12..1 | %{
	$from = $thisMonth.AddMonths(- $_)
	$to = $thisMonth.AddMonths(- $_ + 1).AddDays(-1)
	
}

The first line uses the Get-Date cmdlet with the Format parameter to get just the Month and the Year ("March 2010").

Unfortunately that output is a string and we want a DateTime value for the rest of the script, so we cast the string to a DateTime object.

And we store that in the $thisMonth variable.

The cast will store the 1st day of the current month in the $thisMonth variable.

Today this would give "Monday 01 March 2010 00:00:00".

Then I start a loop where I count down from 12 to 1.

The ".." operator indicates a range of integers between the two values left and right.

In this case the result is 12 11 10 9 8 7 6 5 4 3 2 1.

The "%" statement is an alias for the Foreach-Object cmdlet.

In the code block that follows (the lines between the curly braces) the $_ variable represents the actual value.

So this variable will get the values 12 11 10 9 8 7 6 5 4 3 2 1 respectively.

We calculate the $from variable.

We subtract a number of months (value in $_) from the DateTime object in $thisMonth. We do this with the AddMonths method that is available on a DateTime object.

Remember the $thisMonth variable contained "Monday 01 March 2010 00:00:00" , so if we subtract 12 months we get "Sunday 01 March 2009 00:00:00".

The $to variable is again calculated from the $thisMonth variable.

We subtract $_ minus 1 month, which gives us "Wednesday 01 April 2009 00:00:00".

But we want the last day of the previous month so we subtract 1 day with the AddDays method.

And this gives us "Tuesday 31 March 2009 00:00:00".

Since we do this for all the values of the range we get 12 start-end dates for the past 12 months.

I hope this cleared it up a bit.

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos
admin
Immortal
Immortal
Jump to solution

That makes sense..except I get and error.. executing

Missing expression after unary operator '-'.

At C:\Documents and Settings\user\Desktop\xxxxx\powercli\scripts\report-last

-2calendar-month.ps1:16 char:3

+ - <<<< start $from

+ CategoryInfo : ParserError: (-:String) [], ParseException

+ FullyQualifiedErrorId : MissingExpressionAfterOperator

====

HUH?

$thisMonth = (Get-Date -Format "y")

12..1 | %{

$from = $thisMonth.AddMonths(- $_ )

$to = $thisMonth.AddMonths(- $_ +1).AddDays(-1)

}

=================

0 Kudos
admin
Immortal
Immortal
Jump to solution

This is what I running...

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

Luc,

The typecasting to datetime seems to work only if your computer uses the English language pack. I use Windows 7 Ultimate 64-bits with the Dutch language pack installed. Now I get an error with the typecasting. In English it works fine:

[vSphere PowerCLI] C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI> [datetime] "March 2010"

maandag 1 maart 2010 0:00:00


[vSphere PowerCLI] C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI> 

But if I use your code, I get an error:

[vSphere PowerCLI] C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI> [datetime] (Get-Date -Format "y")
Cannot convert value "maart 2010" to type "System.DateTime". Error: "De tekenreeks is niet herkend als een geldige Date
Time. Index 0 begint met een onbekend woord."
At line:1 char:11
+ [datetime] <<<<  (Get-Date -Format "y")
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

[vSphere PowerCLI] C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI>

I get the same error if I replace (Get-Date -Format "y") by it's value "maart 2010"

vSphere PowerCLI] C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI> [datetime] "maart 2010"
Cannot convert value "maart 2010" to type "System.DateTime". Error: "De tekenreeks is niet herkend als een geldige Date
Time. Index 0 begint met een onbekend woord."
At line:1 char:11
+ [datetime] <<<<  "maart 2010"
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

[vSphere PowerCLI] C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI>

For people who don't understand Dutch, I will give a translation of the Dutch words in English:

maandag = monday

maart = March

De tekenreeks is niet herkend als een geldige Date = The characterstring is not recognized as a valid Date

Index 0 begint met een onbekend woord = Index 0 starts with an unknown word

Luc, do you know if there is a way to use.NET typecasting in Dutch instead of English?

Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you want to split up a line over multiple lines in your script, you have to use the back-tick.

Like this

Get-VM `
-Name "MyVM"

Otherwise PowerShell considers the 2nd line as a seperate statement.

That's why you get the "Missing expression after unary operator '-'." message. PowerShell considers the 2nd line "-start $from" as a new statement.

The calls to the Get-Stat cmdlet should be inside the loop over the last 12 months. See the attached script.

Btw there is in this case no need to use the MaxSamples parameter.

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Robert,

That behaviour is, in my opinion, a PowerShell "feature".

The "culture" concept is not implemented in all PowerShell features as thorough as it should be.

Since you're using a Dutch PS version, the DateTime casting operator should be able to read the Dutch-formatted datetime string. But apparently it isn't.

Have a look at Keith Hil's [Windows PowerShell 2.0 String Localization|

http://keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!7132.entry] post.

It contains an improved Using-Culture function. That could be a bypass for this problem.

____________

Blog: LucD notes

Twitter: lucd22


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

0 Kudos