VMware Cloud Community
FineSam
Contributor
Contributor

Help for scalable script fetching performance of hosts.

Hello everyone,

I'm working as an operator and every month we have to manually export the performance data (CPU/Memory/Network) of all the esxi hosts of one of our client.

This takes around 4 hours for 18 hosts using the Export option of the vSphere's Performance tab.

That twice a month since usable data (2 hour interval ones) get erased every month.

So it goes like:

the 16th we collect from the 1st to the 15th of the current month

the 3rd we collect from the 16th to the last day of last month

Although I didn't have any skills in powershell I looked for a way to automate this nonsense.

After reading LucD notes and others I wrote that script which does the job, but I want this to be really good before showing it to my manager.

=================================Do that on the 16th==========================================

# Make Powercli executable through a poweshell shortcut

Add-PSSnapin VMware.VimAutomation.Core

# Launch PowerCli from Powershell

. 'C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1'

# Login to vCenter

Connect-VIServer <vCenterName> -User <UserName> -Password <PW>

# Set first day of current month

$FirstDayOfMonth = Get-Date -Day 1 -Hour 0 -Minute 0 -Second 0

# Set 15th day of current month

$FirstPartOfMonth = Get-Date -Day 15 -Hour 23 -Minute 59 -Second 59

# Set hosts

$Hosts = Get-VMHost

# Set current month

$ThisMonth = Get-Date -format yyMM

# Get all hosts data

$report = Get-Stat -Entity $Hosts -Stat 'cpu.usage.average','mem.vmmemctl.average','net.usage.average' -IntervalHours 2 -Start $FirstDayOfMonth -Finish $FirstPartOfMonth

# Export data to a csv file

$report | Export-Csv "C:$ThisMonth_Usage.csv" -NoTypeInformation -UseCulture

# Logoff of vCenter

Disconnect-VIServer -confirm:$false

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

=================================Do that on the 3rd==========================================

# Make Powercli executable through a poweshell shortcut

Add-PSSnapin VMware.VimAutomation.Core

# Launch PowerCli from Powershell

. 'C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1'

# Login to vCenter

Connect-VIServer <vCenterName> -User <UserName> -Password <PW>

# Set last month 16th

$SecondPartOfMonth = ((Get-Date -Day 01 -Hour 0 -Minute 0 -Second 0).AddMonths(-1)).AddDays(15)

# Set last month last day 23:59

$LastDayOfLastMonth = ((Get-Date -Day 01 -Hour 23 -Minute 59 -Second 59).AddDays(-1))

# Select hosts

$Hosts = Get-VMHost

# Select CSV file to be appended

$LastMonth = (Get-Date).AddMonths(-1) | Get-Date -format yyMM

# Get all data of all hosts

$report = Get-Stat -Entity $Hosts -Stat 'cpu.usage.average','mem.vmmemctl.average','net.usage.average' -IntervalHours 2 -Start $SecondPartOfMonth -Finish $LastDayOfLastMonth

# Append last month CSV file

$report | Export-Csv -Append "C:$LastMonth_Usage.csv" -NoTypeInformation -UseCulture

# Logoff of vCenter

Disconnect-VIServer -confirm:$false

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

The thing I can do now:

-Training though the great powercli lab (VMware Learning Platform )

I am now able to create a single CSV file of the needed performance of all the hosts

My final goal:

-Since it's for presentation purposes I want to create a CSV file for every single host and make a chart out of them using excel

-Make a comparison to last month performance data

What I'm thinking about but doesn't fit:

-I could do the following for every host, but when a new host will be implemented I'd need to add text to the script ... which is not really an efficient method

Get-Stat -Entity Get-VMHost -name esx01 -Stat 'cpu.usage.average','mem.vmmemctl.average','net.usage.average' -Start $FirstDayOfMonth -Finish $LastDayOfMonth |

Export-Csv "C:\esx01.csv" -NoTypeInformation -UseCulture

Get-Stat -Entity Get-VMHost -name esx02 -Stat 'cpu.usage.average','mem.vmmemctl.average','net.usage.average' -Start $FirstDayOfMonth -Finish $LastDayOfMonth |

Export-Csv "C:\esx02.csv" -NoTypeInformation -UseCulture

...

What I'm asking you guys:

-make a script that can export performances (average cpu usage, memory usage, network usage) of each host to different CSV files (One CSV file for each host).

-The trick is that the script would not need to be rewritten even if a new host get added.

From there I think I can make an excel macro able to create charts and compare data.

I hope you get the idea of all this,

I'm new to all this so feel free to make remarks/questions.

Sam

0 Kudos
15 Replies
LucD
Leadership
Leadership

Which PowerCLI version are you using?

Do a Get-PowerCLIVersion.


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

0 Kudos
FineSam
Contributor
Contributor

LucDHere is the result from the get-powercliversion command.

PowerCLI Version

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

   VMware vSphere PowerCLI 5.5 Release 2 build 1671586

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

Snapin Versions

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

   VMware AutoDeploy PowerCLI Component 5.5 build 1598391

   VMware ImageBuilder PowerCLI Component 5.5 build 1598391

   VMware License PowerCLI Component 5.5 build 1265954

   VMware VDS PowerCLI Component 5.5 build 1671576

   VMware vSphere PowerCLI 5.5 Release 2 build 1671576

0 Kudos
LucD
Leadership
Leadership

Unless you have a reason to stick with this old PowerCLI version, like for example vSphere compatibility I would suggest to upgrade your PowerCLI installation first.


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

0 Kudos
LucD
Leadership
Leadership

The Group-Object cmdlet makes this quite straightforward.

You can do something like this.

If you schedule this job daily, it will only run on the 3th and 16th of each month.

$now = Get-Date

if($now.Day -eq 16 -or $now.Day -eq 3){

    $stat = 'cpu.usage.average','mem.vmmemctl.average','net.usage.average'

    $interval = 120

    $entities = Get-VMHost

    if($now.Day -eq 16){

        $start = Get-Date -Day 1 -Hour 0 -Minute 0 -Second 0

        $finish = Get-Date -Day 15 -Hour 23 -Minute 59 -Second 59

    }

    elseif($now.Day -eq 3){

        $start = ((Get-Date -Day 01 -Hour 0 -Minute 0 -Second 0).AddMonths(-1)).AddDays(15)

        $finish = ((Get-Date -Day 01 -Hour 23 -Minute 59 -Second 59).AddDays(-1))

    }

    Get-Stat -Entity $entities -Stat $stat -IntervalMins $interval -Start $start -Finish $finish |

    Group-Object -Property {$_.Entity.Name} | %{

        $fileName = "$($_.Name)-$('{0:D2}' -f $start.Day)-$('{0:D2}' -f $start.Month)-$('{0:D2}' -f $start.Year).csv"

        $_.Group | Sort-Object -Property Timestamp | Export-Csv -Path $fileName -NoTypeInformation -UseCulture

    }

}


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

0 Kudos
FineSam
Contributor
Contributor

Thank you for the answer LucD.

I tried it and it delivered a .csv file for each host!

I didn't ask my management for the powercli version upgrade.

They never used powercli before so I'd prefer try to run something on current

version and then convince them about any upgrade.

I'm trying to study at the same time so in your free time,

can you tell me if my understanding of the following is correct:

$_. recalls the data in the last pipeline ?

In the following $_ recalls the Get-Stat cmdlet result right?

    Get-Stat -Entity $entities -Stat $stat -IntervalMins $interval -Start $start -Finish $finish |

    Group-Object -Property {$_.Entity.Name}

Thank you for your help.

Using the group-object cmdlt you talked about I could create a file for each host and

each metric id in a new folder for each host corresponding to the current month.

I felt like it would be easier to apply a vba macro afterwards, to make good looking charts.Smiley Happy

Something like that:

C:esxi01_170407\

     esxi01_CPU.csv

     esxi01_Mem.csv

     esxi01_NW.csv

C:esxi02_170407\

     esxi02_CPU.csv

     esxi02_Mem.csv

     esxi02_NW.csv

...and so on

The next step is to automate the chart creation,

I'm planning onmaking them through excel vba macro but

if you have any suggestion I'm open.

I am aware of the .Net Chart Controls  but can't use it at work right now.

0 Kudos
LucD
Leadership
Leadership

Yes, the $_ variable contains the current object in the pipeline.

With Group-Object you can split up a result in multiple groups.

And the splitup doesn't need to be limited to one property, you can specify multiple properties.

For example the ESXi name and the counter.

You should have a look at the ImportExcel module.

It allows you to create an XLSX file, so you could have the different ESXi nodes and counters on different worksheets in that 1 Excel file.

And it has an option to create a graph on each Worksheet.


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

0 Kudos
FineSam
Contributor
Contributor

Thank you for your help LucD!

We don't have excel on the vCenter server so we can't use ImportExcel ...

Now my managers want to know if all this scripting stuff will have any bad effect on the

vCenter or the esxi servers' resources while it's running...

If I am correct I read in LucD PowerCLI & vSphere statistics - Part 1 - The basics - LucD notes ​ that the 2 hours interval

performance data blocks are stored in the vCenter db thusthe script does not interact with the esxi servers and only with the vCenter.

Our vCenter has an average of 50% memory usage so I don't think it will cause any problem.

Can anyone back that up?

Best regards

Sam

0 Kudos
LucD
Leadership
Leadership

You don't need to have Excel installed to use ImportExcel (that's the beauty of that module).

Your assumption is correct, the aggregated statistics are stored on the vCenter, not ESXi nodes involved.

The query towards the vCenter will of course use some resources, but normally they should be neglegible.


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

0 Kudos
FineSam
Contributor
Contributor

Thank you for your answers LucD!

I looked up for the excel module but I don't want to have

to ask the customer to install that module, it will make the whole process take longer.

I have a new issue in my project now.

I need to collect 3 memory performance counters and display them on a single csv for each host.

The counters are Ballooning usage (mem.vmmemctl.average) overhead usage (mem.overhead.average) and memory usage (mem.usage.average).

An example of what I would like to do is:

esxi01.csv:

Timestamp          Balloon     Overhead     Usage

5/27/2017 00:00   12              14                45

5/27/2017 00:05   09              14                45

5/27/2017 00:10   14              14                45

5/27/2017 00:15   29              14                45

...

esxi02.csv:

Timestamp          Balloon     Overhead     Usage

5/27/2017 00:00   12              14                45

...

and so on for every host...

I tried many things but this is the last one I tried and failed with:

$start = Get-Date -Hour 5

$finish = Get-Date -Hour 14

$interval = 5

$entities = Get-VMHost

foreach ($name in $entities)

{

$Mem_Balloon = Get-Stat  -stat mem.vmmemctl.average,mem.overhead.average,mem.usage.average -IntervalMins $interval -Start $start -Finish $finish | Sort-Object -Property Timestamp

$Mem_overhead = Get-Stat -stat mem.overhead.average -IntervalMins $interval -Start $start -Finish $finish | Sort-Object -Property Timestamp

$Mem_Usage = Get-Stat -stat mem.usage.average -IntervalMins $interval -Start $start -Finish $finish | Sort-Object -Property Timestamp

$Mem_stats = @{

TimeStamp = $Mem_Usage.timestamp

Balloon = $Mem_Balloon.value

Overhead = $Mem_overhead.value

Usage = $Mem_Usage.value

}

$object = new-object psobject -Property $Mem_stats

}

$object | Select-Object TimeStamp,Balloon,Overhead,Usage

The results of the above script is as follow and the data won't be exported to csv.

Timestamp                                        Balloon     Overhead     Usage

{5/27/2017 00:00 5/27/2017 00:10...     {0,0...         {0,0...          {33.48,25.45...

If anyone has an idea on how to do it It would be great!

Sam

0 Kudos
LucD
Leadership
Leadership

Try like this.

The first grouping is over the ESXi nodes, the 2nd grouping is on the timestamp.

$start = Get-Date -Hour 5 

$finish = Get-Date -Hour 14 

$interval = 5 

$entities = Get-VMHost 

$stat = 'mem.vmmemctl.average','mem.overhead.average','mem.usage.average' 

Get-Stat -Entity $entities -Stat $stat -Start $start -Finish $finish |

Group-Object -Property Entity | %{

    $report = $_.Group | Group-Object -Property Timestamp | %{

        $obj = [ordered]@{

            Timestamp = $_.Name

            Balloon = $_.Group | where{$_.MetricId -eq 'mem.vmmemctl.average'} | select -ExpandProperty Value

            Overhead = $_.Group | where{$_.MetricId -eq 'mem.overhead.average'} | select -ExpandProperty Value

            Usage = $_.Group | where{$_.MetricId -eq 'mem.usage.average'} | select -ExpandProperty Value

        }

        New-Object PSObject -Property $obj

    }

    $Report | Export-Csv -Path "$($_.Name).csv" -NoTypeInformation -UseCulture

}


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

0 Kudos
FineSam
Contributor
Contributor

Thank you for your help with my project!

I do have a new problem now :

The vcenter is running power version 2 so I can't use the append option for csv-export and the [ordered] attribute.

I found a function to make the append option work but can't find a way to set my hashtable the way I ordered it in the script!

I'm using the one lucD wrote.

I Home someone can help me with that hashtable ordering madness.

By the way I can't update powershell to V3.

Get-Stat -Entity $entities -Stat $stat -Start $start -Finish $finish |

Group-Object -Property Entity | %{

    $report = $_.Group | Group-Object -PropertyTimestamp | %{

        $obj = [ordered]@{

            Timestamp = $_.Name

            Balloon = $_.Group | where{$_.MetricId -eq'mem.vmmemctl.average'} | select -ExpandPropertyValue

            Overhead = $_.Group | where{$_.MetricId -eq'mem.overhead.average'} | select -ExpandPropertyValue

            Usage = $_.Group | where{$_.MetricId -eq'mem.usage.average'} | select -ExpandPropertyValue

        }

        New-Object PSObject -Property $obj

    }

    $Report | Export-Csv -Path "$($_.Name).csv" -NoTypeInformation -UseCulture

}

0 Kudos
LucD
Leadership
Leadership

Some remarks:

  • why are you running these scripts on the vCenter? That is not advisable.
  • since the latest Windows 10 update, PowerShell v2 is not even supported anymore

Don't you have access to a separate workstation, with a more recent PowerShell version?


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

0 Kudos
LucD
Leadership
Leadership

You can use the Select-Object technique to explicitly define the order.

Get-Stat -Entity $entities -Stat $stat -Start $start -Finish $finish |

Group-Object -Property Entity | %{

    $report = $_.Group | Group-Object -PropertyTimestamp | %{

        New-Object PSObject -Property @{

            Timestamp = $_.Name

            Balloon = $_.Group | where{$_.MetricId -eq'mem.vmmemctl.average'} | select -ExpandPropertyValue

            Overhead = $_.Group | where{$_.MetricId -eq'mem.overhead.average'} | select -ExpandPropertyValue

            Usage = $_.Group | where{$_.MetricId -eq'mem.usage.average'} | select -ExpandPropertyValue

        }

    }

    $Report |

    Select Timestamp,Balloon,Overhead,Usage |

    Export-Csv -Path "$($_.Name).csv" -NoTypeInformation -UseCulture

}


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

0 Kudos
FineSam
Contributor
Contributor

Thank you again for your help.

The properties are displayed in the right order!

But(!) the timestamp data is upside down. The newest is on top although I want it to be at the bottom so when I append data it looks fine.

I tried to sort the timestamp using descending but it doesn't work!

Regards, Sam.

0 Kudos
LucD
Leadership
Leadership

Try like this

Get-Stat -Entity $entities -Stat $stat -Start $start -Finish $finish |

Group-Object -Property Entity | %{

    $report = $_.Group | Sort-Object -Property Timestamp | Group-Object -Property Timestamp | %{

        New-Object PSObject -Property @{

            Timestamp = $_.Name

            Balloon = $_.Group | where{$_.MetricId -eq'mem.vmmemctl.average'} | select -ExpandPropertyValue

            Overhead = $_.Group | where{$_.MetricId -eq'mem.overhead.average'} | select -ExpandPropertyValue

            Usage = $_.Group | where{$_.MetricId -eq'mem.usage.average'} | select -ExpandPropertyValue

        }

    }

    $Report |

    Select Timestamp,Balloon,Overhead,Usage |

    Export-Csv -Path "$($_.Name).csv" -NoTypeInformation -UseCulture

}


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

0 Kudos