Using PowerCLI to get VM Disk Stats

Jump to solution

Firstly - this is really a message to LucD (who I know from previous assistance tends to prowl this forumSmiley Happy )  , just figured I'd share it, as it's all usefull info and any insight LucD has will no doubt be usefull for all.

Hi LucD,
Firstly - thanks for a great selection of posts on Reporting vSphere from Powershell - Well worth the time and a worth read for anyone.
I'm certainly not any good at PowerShell - but I was able to understand and make some changes for my benefit - so I figured I'd share my results and ask a couple of questions.
With your script as a basis - I've been able to come up with the following that SHOULD allow me to review ALL VMs in VC one at a time collect virtual disk stats for the VMs various disks, (IOPS, Throuput & Latency) I'm using VC 4.1 and and the storage is NFS attached, I believe these stats are OK but would appreciate your insight on this.
I'm quite pleased with the script - but it needs more testing on a valid site, rather than my small test area, but I'm sure from a 'PS' perspective there is more efficiency to be gained.
Firstly - is there any way of getting all the stats at once - rather than doing 6 calls per VM? (I'm also sure the '+=' one stat the the next can not be ideal)
Also - is there a way can control the output to the CSV, it seems to put colums in any order it likes and layout does not seem to be related to the group object command? Can this be controlled so I can have the 'value' and 'unit' entries next to each other?
Any insight and assistance would be appreciated, and I hope others will give it a test and let me know if it works for them too.
Thanks again for the inspiration and insight that got me this far Smiley Happy
ESX 4.1, VC 4,1, PShell 2.0, PowerCLI 4.1.1
# Main Variables
$sVCentre = "VC IP"
$sVCUser = "administrator@domain"
$sVCPwd = "password"
$strVMWildCard = "*"
$strCSVName = "Stats-AvgVMDiskWriteStatsWorkingday"
$strCSVLocation = "c:\"
# define the start and finish times for a working day.
$today9am = (Get-Date -Hour 9 -Minute 0 -Second 0)
$today5pm = (Get-Date -Hour 17 -Minute 0 -Second 0)
$intStartDay = -1
$intEndDay = -1
## Begin Script
#Connect to VC
Connect-VIServer $sVCentre -User $sVCUser -Password $sVCPwd -ea silentlycontinue
$arrVMs = Get-VM | where-object {$_.Name -like $strVMWildCard}
foreach ($strVM in $arrVMs)
Write-Host "Getting Stats for : " $strVM.Name
Write-Host " - collating Write latency Stats"
$stats += Get-Stat -Entity $strVM -Stat virtualDisk.totalWriteLatency.average -Start $today9am.AddDays($intStartDay) -Finish $today5pm.AddDays($intEndDay)
Write-Host " - collating Read latency Stats"
$stats += Get-Stat -Entity $strVM -Stat virtualDisk.totalReadLatency.average -Start $today9am.AddDays($intStartDay) -Finish $today5pm.AddDays($intEndDay)
Write-Host " - collating Read IOPS Stats"
$stats += Get-Stat -Entity $strVM -Stat virtualDisk.numberReadAveraged.average -Start $today9am.AddDays($intStartDay) -Finish $today5pm.AddDays($intEndDay)
Write-Host " - collating Write IOPS Stats"
$stats += Get-Stat -Entity $strVM -Stat virtualDisk.numberWriteAveraged.average -Start $today9am.AddDays($intStartDay) -Finish $today5pm.AddDays($intEndDay)
Write-Host " - collating Read Throughput Stats"
$stats += Get-Stat -Entity $strVM -Stat virtualDisk.read.average -Start $today9am.AddDays($intStartDay) -Finish $today5pm.AddDays($intEndDay)
Write-Host " - collating Write Throughput Stats"
$stats += Get-Stat -Entity $strVM -Stat virtualDisk.write.average -Start $today9am.AddDays($intStartDay) -Finish $today5pm.AddDays($intEndDay)
Write-Host $stats.length
# group the data and collate the stats into averages for the day.
}$groups = $stats | Group-Object -Property {$_.Entity, $_.MetricId, $_.Instance}
$report = $groups | % {
New-Object PSObject -Property @{
Description = $_.Group[0].Description
Entity = $_.Group[0].Entity
EntityId = $_.Group[0].EntityId
Instance = $_.Group[0].Instance
MetricId = $_.Group[0].MetricId
Timestamp = $_.Group[0].Timestamp.Date.AddHours($_.Group[0].Timestamp.Hour)
Unit = $_.Group[0].Unit
Value = [math]::Round(($_.Group | Measure-Object -Property Value -Average).Average, 2)
#Exporting the report to a CSV file.
$strCSVSuffix = (get-date).toString('yyyyMMddhhmm')
$strCSVFile = $strCSVLocation + $strCSVName + "_" + $strCSVSuffix + ".csv"
$report | Export-Csv $strCSVfile -NoTypeInformation -UseCulture
61 Replies

warnox‌ many thanks for sharing your great site 😉

/* Any kind of comment or input would be greatly appreciated */
0 Kudos

Awesome script! 

FYI...  you can set the order of columns in a CSV by using the Select statement, like so...

$report | select Entity, EntityId, Description, Instance, MetricId, Unit, Value, Timestamp | export-csv $strCSVfile -notypeinformation -useculture

Re-arrange the property names in the select statement in any order you wish...  boom!

Smiley Wink

0 Kudos