PowerCLI Script to dump VDI VM IO Stats

During a VDI pilot you really need to gather some real-world stats on how your client VMs are performing. People generally underestimate the workload VDI can put on a SAN. Thankfully if you are using vSphere 4.x, you can easily pull the stats with a short PowerShell script. I took a great script LucD has overe here and changed it up a bit to be more VDI specific. I’ll be the first to admit PowerShell is an area I need to learn more in, so the script could probably be more efficient, but hey, this works for me!

Unlike the LucD version, this requires a couple of command line arguments so you can more rapidly change the VM names and time period you are reporting against. The first argument is the VM name and the second is whole number which represents the number of minutes the stats need to be displayed for. The report is displayed both on the screen and dumped to a CSV file with a unique date stamp, so you don’t accidentally overwrite your results.

Unfortunately VMware sets the minimum realtime stats sample size at 20 seconds, so the IOPSmax value is over a 20 second interval. Within that 20 seconds there could well be higher spikes, so don’t take that value as the absolute max. Make sure you take into account the 20 second window when setting the sample time, so you don’t lose some data.

Update: Script has been modified a bit so that you can use wildcards for the hostname and it will properly calculate all the stats for each VM.


$vms = $args[0]
$time = $args[1]
$metrics = “disk.numberwrite.summation”,”disk.numberread.summation”
$start = (Get-Date).AddMinutes(-$time)
$report = @()
$stats = Get-Stat -Realtime -Stat $metrics -Entity $vms -Start $start
$interval = $stats[0].IntervalSecs
$date = get-date -format “dd-hh-mm-ss”
$report = $stats | Group-Object -Property {$_.Entity.Name},Instance | %{

$AvgIOPS = [math]::round((($_.Group | `
Group-Object -Property Timestamp | `
%{$_.Group[0].Value + $_.Group[1].Value} | `
Measure-Object -Average).Average / $interval),2)

$MaxIOPS = ($_.Group | `
Group-Object -Property Timestamp | `
%{$_.Group[0].Value + $_.Group[1].Value} | `
Measure-Object -maximum).maximum /$interval

$WriteIOs = ($_.Group | Group-Object -Property Timestamp | `
%{$_.Group[0].Value} | Measure-Object -sum).sum

$ReadIOs = ($_.Group | Group-Object -Property Timestamp | `
%{$_.Group[1].Value} | Measure-Object -sum).sum

$TotalIOs = ($_.Group | `
Group-Object -Property Timestamp | `
%{$_.Group[0].Value + $_.Group[1].Value} | `
Measure-Object -sum).sum

$ReadRatio = [math]::round(($readios / $totalios),2)

$WriteRatio = [math]::round(($writeios / $totalios),2)

New-Object PSObject -Property @{
VM = $_.values[0]
AvgIOPS = $Avgiops
WriteIOs = $writeios
ReadIOs = $readios
TotalIOs = $totalios
ReadRatio = $readratio
WriteRatio = $writeratio

$report | Export-Csv “D:\IOPSMax-report-$date.csv” -NoTypeInformation -UseCulture

Print Friendly, PDF & Email

Related Posts

Notify of
Newest Most Voted
Inline Feedbacks
View all comments
July 13, 2011 3:53 pm

Yes the script above just dumps the data to the CSV. If you want it also displayed on the screen you can add a line:


before the other $report line, and you will get the results printed to your screen.

September 30, 2012 3:29 pm

im getting errors when running the script

Get-Stat : 9/30/2012 7:27:04 PM Get-Stat Value cannot be found for th
e mandatory parameter Entity
At C:\Users\citrix\Desktop\bootstorm1.ps1:6 char:18
+ $stats = Get-Stat <<<< -Realtime -Stat $metrics -Entity $vms -Start $start
+ CategoryInfo : NotSpecified: (:) [Get-Stat], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomatio

Cannot index into a null array.
At C:\Users\citrix\Desktop\bootstorm1.ps1:7 char:20
+ $interval = $stats[ <<<< 0].IntervalSecs
+ CategoryInfo : InvalidOperation: (0:Int32) [], RuntimeException
+ FullyQualifiedErrorId : NullArray

Export-Csv : Cannot bind argument to parameter ‘InputObject’ because it is null
At C:\Users\citrix\Desktop\bootstorm1.ps1:48 char:21
+ $report | Export-Csv <<<< "c:\IOPSMax-report-$date.csv" -NoTypeInformation -
+ CategoryInfo : InvalidData: (:) [Export-Csv], ParameterBindingV
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,M