I needed the performance charts for a couple of VMs. It’s an easy task which can be done via the GUI. But I needed the charts for tens of VMs, and needed a faster (and more lazy way), so I write this script that uses the Windows Charting APIs to plot the data from vCenter onto a PNG that I could send to the requester. I though to share the script here so it can help somebody else’s day be a little less grinding. This has been the second time I’ve been asked to deliver this kind of data, see my post from 2014 (which I forgot I made, and assumed I lost the script) So I wrote a new script. So why share it then, because this time it has been written better, and supports two Y-axis. Plotting CPU and RAM values at the same time with the method I used this time wasn’t possible so there you go, more of the same, but different. And you can have may stats plotted, it just dynamically adds data series.

Function GenerateChart {
[CmdletBinding()]
param (
[STRING][Parameter(HelpMessage='Type of chart to generate, see "https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datavisualization.charting.seriescharttype" Default is "FastLine"')]$ChartType="FastLine",
[STRING][Parameter(Mandatory,HelpMessage='Please give atleast one VirtualMachine Name')]$VirtualMachine,
[STRING[]][Parameter(Mandatory,HelpMessage='Please give atleast one statistic, e.g. "cpu.consumed.average"')]$Statistic,
[STRING][Parameter(HelpMessage='Location the save the generated charts, no need for a trailing "\". Default to TEMP variable')][Alias('Path')]$FilePath=$env:TEMP,
[INT][Parameter(Mandatory,HelpMessage='Please indicate the timespan in days, for which you need the data')]$Days
)
$VirtualMachine = Get-VM -Name $VirtualMachine
$StartDate = (Get-Date).AddDays(-$Days)
$Statistics = Get-Stat -Entity $VirtualMachine -Stat $Statistic -Start $StartDate | Sort-Object -Property Timestamp,VM | Select-Object @{Name='VirtualMachine';Expression={$_.Entity.Name}},Timestamp,MetricId,Value
$Chart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart
$Chart.Width = 1920
$Chart.Height = 1080
$Chart.BackColor = [System.Drawing.Color]::White
[void]$Chart.Titles.Add($Statistics.VirtualMachine[0])
$Chart.Titles[0].Alignment = "topLeft"
$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$ChartArea.Name = "ChartArea1"
$Chart.ChartAreas.Add($ChartArea)
$Statistics | Select-Object -ExpandProperty MetricId | Sort-Object -Unique -Descending | Foreach-Object {
[STRING]$SeriesName = $_
$SeriesStatistics = $Statistics | Where-Object {$_.MetricId -eq $SeriesName}
[void]$Chart.Series.Add($SeriesName)
$Chart.Series[$SeriesName].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::$ChartType
If ($SeriesName -eq "mem.entitlement.average" -or $SeriesName -eq "mem.consumed.average") {
$ChartArea.AxisY2.Enabled = [System.Windows.Forms.DataVisualization.Charting.AxisEnabled]::True
$Chart.Series[$SeriesName].YAxisType = [System.Windows.Forms.DataVisualization.Charting.AxisType]::Secondary
}
$Chart.Series[$SeriesName].Points.DataBindXY($SeriesStatistics.TimeStamp,$SeriesStatistics.Value)
$Legend = New-Object System.Windows.Forms.DataVisualization.Charting.Legend
$Legend.IsEquallySpacedItems = $True
$Legend.Position.Auto = $true
$Chart.Legends.Add($Legend)
$ChartArea.RecalculateAxesScale()
}
$FileName=$FilePath.TrimEnd("\") + "\" + $VirtualMachine + ".png"
$Chart.SaveImage($FileName,"png")
Return $FileName
}
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization") | Out-Null
Import-Module VMware.VimAutomation.Core
Connect-VIServer -Server MyVirtualCenter -User Me -Password MySecr3t!
#Most likely you need information from more than one VM, You could use RegEx, or an inputfile but a single VM is equally possible:
#$VMs = Get-VM | Where-Object {$_.Name -match "(?i)^\D\d{4}srv\D{3}\d{3}"}
#$VMs = Get-Content C:\MyReports\InputList.txt
#$VMs = Import-CSV C:\MyReports\VirtaulMachines.csv -Delimiter ',' | Select-Object $_.VirtualMachineName
$VMs = Get-VM MyVirtualMachine
$Statistic = @(
"cpu.demand.average",
"mem.entitlement.average",
"mem.consumed.average"
)
$VMs | ForEach-Object {
GenerateChart -ChartType FastLine -VirtualMachine $_ -Statistic "cpu.demand.average","mem.entitlement.average","mem.consumed.average" -Days 7 -FilePath C:\MyReports
}