Exporting vSphere Perfomance data in graphs with PowerShell

Exporting vSphere Perfomance data in graphs with PowerShell

UPDATE: If you get an error like:

New-Object : Cannot find type [System.Windows.Forms.DataVisualization.Charting.DataPoint]: make sure the assembly containing this type is loaded.

You may need to install the Microsoft Chart Controls for Microsoft .NET Framework 3.5

I was asked to export some performance data from Virtual Machines. Someone wanted to know the Memory and CPU usage of all VMs in vCenter over the last year. They needed that information in graphs, so I exported the data to a CSV and told them that Excel could create a nice graph form the data. But I knew that Excel objects could be created with PowerShell. I started to google around and found that I don’t even have to use Excel. Windows Forms could create the graphs directly.

With the vSphere client one could export the performance graph per VM, but it must be done for each separate VM It’s not possible with multiple selections.

If ((Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null) {
	Add-PSSnapin VMware.VimAutomation.Core

$vCenter = "Your vCenter Here"
$TimeSpan = 30 # in days, so this graph goes back 30 days. You could change AddDays on lines 26 and 27 to AddMonths or AddYears
$MaxSamples = 1000 # The maximum number of samples to extract, more samples makes for a more detailed graph, but takes more time.

If ($DefaultServers) {
	If (!($DefaultServers -contains $vCenter)) {
		Connect-VIServer $vCenter

Else {
	Connect-VIServer $vCenter

$VirtualMachines = Get-VM

ForEach ($vm in $VirtualMachines) {
	$vmStat= "" | select VMName, MemMax, MemAvg, MemMin, CPUMax, CPUAvg, CPUMin
	$StatCPU = Get-Stat -Entity ($vm) -Start (Get-Date).AddDays(-$TimeSpan) -Finish (Get-Date) -MaxSamples $MaxSamples -Stat cpu.usage.average
	$StatMem = Get-Stat -Entity ($vm) -Start (Get-Date).AddDays(-$TimeSpan) -Finish (Get-Date) -MaxSamples $MaxSamples -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
	$Chart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart
	$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
	$ChartArea.Name = "ChartArea1"
	$ChartArea.AxisX.Title = "Point in Time"
	$ChartArea.AxisX.LabelStyle.Angle = 30
	$ChartArea.AxisY.Title = "Value in Percentage"
	$Chart.Width = 1500
	$Chart.Height = 600
	$Chart.Left = 40
	$Chart.Top = 30
	$Chart.Name = $vm
	$Legend = New-Object System.Windows.Forms.DataVisualization.Charting.Legend
	$Legend.Name = "Legend1"
	$Chart.Series["CPUAvg"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
	$Chart.Series["CPUAvg"].IsVisibleInLegend = $true
	$Chart.Series["CPUAvg"].ChartArea = "ChartArea1"
	$Chart.Series["CPUAvg"].Legend = "Legend1"
	$Chart.Series["CPUAvg"].Color = "#FF0000"
	$Chart.Series["CPUAvg"].xValueType = [System.Windows.Forms.DataVisualization.Charting.ChartValueType]::DateTime
	$Chart.Series["MemAvg"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line
	$Chart.Series["MemAvg"].IsVisibleInLegend = $true
	$Chart.Series["MemAvg"].ChartArea = "ChartArea1"
	$Chart.Series["MemAvg"].Legend = "Legend1"
	$Chart.Series["MemAvg"].Color = "#0000FF"
	$Chart.Series["MemAvg"].xValueType = [System.Windows.Forms.DataVisualization.Charting.ChartValueType]::DateTime
	$CpuPoints = $StatCPU
	$MemPoints = $StatMem

	Foreach ($CpuPoint in $CpuPoints) {
		$DataPoint = New-Object System.Windows.Forms.DataVisualization.Charting.DataPoint($CpuPoint.Timestamp.ToOADate(),$CpuPoint.Value)
	Foreach ($MemPoint in $MemPoints) {
		$DataPoint = New-Object System.Windows.Forms.DataVisualization.Charting.DataPoint($MemPoint.Timestamp.ToOADate(),$MemPoint.Value)
	$StartYear = $BeginDate.Year.ToString()
	$StartMonth = $BeginDate.Month.ToString()
	$StartDay = $BeginDate.Day.ToString()

	If ($StartDay -lt 2) {
		[String]$StartDay = "0" + $StartDay
	[String]$StartDate = $StartYear + $StartMonth + $StartDay
	[String]$EndDate = (Get-Date -Format yyyyMMdd)
	#This part saves the graphs a PNG files
	[String]$DirectoryName = "C:\Scripts\"
	[String]$FileName = $DirectoryName + "\" + $vm + "_MemCpuAvg_" + $StartDate +"_" + $EndDate + ".png"

	#This part shows the graph in a new window.
	#$Chart.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right -bor [System.Windows.Forms.AnchorStyles]::Left
	#$Form = New-Object Windows.Forms.Form
	#$Form.Text = "$vm - CPU & Memory Usage"
	#$Form.Width = 1600
	#$Form.Height = 700