Collect ESXi stats with powershell and send it to Graphite server

Categories: ESXi, PowerShell, Scripts, VMware, vSphere

I was not quite happy with the statistics from the vCenter. It is not possible to get an overview overall my ESXi servers. šŸ™ Someone pointed me to the tool Graphite that this is a cool solution to visualize such kind of statistics. So I decided to give it a try.

I created and virtual machine running Centos and Graphite as target for my collected statistics. I will post an How to later.

Furthermore I had to create an powershell script which collects the stats of each ESXi in my cluster, transform it a graphite compatible format and transfer it to the graphite server.

#vCenter settings
$vCenter = "VCENTER-IP"
$user = "USERNAME"
$password = "PASSWORD"
$cluster = "YOUR-CLUSTER"
#Graphite server 
$remoteHost = "GRAPHITE-SERVER-IP"

#Socket to send results to Graphite server	 
$socket = new-object System.Net.Sockets.TcpClient($remoteHost, 2003)
$stream = $socket.GetStream()
$writer = new-object System.IO.StreamWriter $stream

Write-Host "Connected"
#Connect to vCenter
Connect-VIServer -Server $vCenter -User $user -Password $password 

#Get all ESXi hosts from Cluster
$esxhosts = Get-VMHost -Location $cluster | Sort

#Collect stats foreach ESXi server and bring it in a Graphite compatible format
foreach ($esxName in $esxhosts){

	$allstats = Get-Stat -Entity (Get-VMHost $esxName) -MaxSamples 1 -Realtime -Stat cpu.usage.average,disk.usage.average,net.usage.average | Sort
	Write-Host $esxName
	foreach($stat in $allstats){
		#Get Timestamp of stats and convert to UNIX timestamp
		$time = $stat.Timestamp
		$date = [int][double]::Parse((Get-Date -Date $time -UFormat %s))
		#Filter only average stats (Stats for CPU's are available foreach CPU and as average of all CPU's)
		$instance = $stat.Instance
		if($instance -eq [DBNull]::Value){
			#create a base for the graphite tree
			$base = ""
			#remove the .usage.average
			$type = (($stat.MetricId).Replace(".usage.average",""))
			#remove the domain from the esxi name
			$name = (($esxName.Name).Replace(" ","")).Replace("","")
			$value = $stat.Value
			#build the graphite compatible string
			$result = "$base$name.$type $value $date"
			#Console output just for testing
			Write-Host "Sent Result: $result"
			#send result to graphite server
	Write-Host " "
## Close the streams
#disconnect from vcenter
Disconnect-VIServer -Server $vCenter -Confirm:$false -Force
Write-Host "Done"

Below is a screenshot of an Graphite graph displaying the CPU average usage of all ESXi servers.

That’s it šŸ™‚

  • This was everything I needed to implement vCenter to Graphite trending in my environment. Thanks for putting this together!

  • I see it added with above script thanks… but i see no data … i added 4 busy servers … any clue

    How does it pulls data from esxi node ? which port & protocol is used, ? snmp ?

    • The data gets collected using the VMware API using the vCenter connection on port 443. Please double check that you have provided the correct port of the Graphite.

      $remoteHost = “GRAPHITE-SERVER-IP”

      #Socket to send results to Graphite server
      $socket = new-object System.Net.Sockets.TcpClient($remoteHost, 2003)

Leave a Reply to Anonymous Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.