Setting VMDK IO Limits via PowerCLI - BCO2649


Our company is leveraging an IO density-based storage tiering solution, and the challenge for we as ESX admins is how to teach the hypervisor to grant access to IOps to a LUN with respect to the size of the VMDK.  A few options for this, but none really as viable for a service provider as VMDK IO limits.

The following script applies IO limits to every VMDK based on the position of a tier string indicator of the housing datastore name.  Different strings, IO density levels, etc. can be customized to your needs.  I have the line that actually applies the IO limits commented out, so it is safe for execution in your environment.  It will generate a report detailing what it found, which can be helpful in finding any outliers.


$VCServer = "VCServer01"
$CsvExport = "c:\tmp\SetIOLimit.csv"

Connect-VIServer $VCServer
$report = @()
$VMs = Get-VM
foreach ($Vm in $Vms) {
     $VmHdds = Get-HardDisk -VM $Vm | select Name, ExtensionData, Filename, CapacityKB
     foreach ($VmHdd in $VmHdds) {
          $row = "" | select VmName, HddName, ScsiID, Datastore, Tier, IODensity, CapacityGB, CurrentIOLimit, CalculatedIOLimit, IOLimitCorrect
          $row.VmName = $Vm.Name
          $row.HddName = $VmHdd.Name
          $row.ScsiID = $([string]$VmHdd.extensiondata.controllerkey).substring(3,1) +":"+ $([string]$VmHdd.extensiondata.unitnumber)
          $row.Datastore = $($VmHdd.Filename.TrimStart("[")).split("]")[0] 
          $row.Tier = $row.Datastore.Split("-")[5]   ###  Our datastore naming convention includes the tier indicator at the 6th delmimited location (i.e. xr-012-n-s-hb-brz-1581-004)
          switch ($row.Tier) {
               "brz" {$row.IODensity = .03}
               "slv" {$row.IODensity = .4}
               "gld" {$row.IODensity = 3.2}
               "t1" {$row.IODensity = 3.2}
               "plt" {$row.IODensity = 20}
               default {$row.IODensity = "Invalid DS name or tier identifier"}
          $row.CapacityGB = $VmHdd.capacitykb / 1024 / 1024
          $row.CurrentIOlimit = $VmHdd.ExtensionData.StorageIOAllocation.limit
          $row.CalculatedIOLimit = [int]($row.IODensity * $row.CapacityGB)
          if ($row.CurrentIOLimit -eq -1) {$row.IOLimitCorrect = "No IO Limit Set"}
          elseif ($row.CurrentIOLimit -gt $row.CalculatedIOLimit) {$row.IOLimitCorrect = "Too High"}
          elseif ($row.CurrentIOLimit -lt $row.CalculatedIOLimit) {$row.IOLimitCorrect = "Too Low"}
          else {$row.IOLimitCorrect = "Just Right"}
          $report += $row
### Uncomment the following and this script will set the IO Limit for VMDKs during execution
#          if ($row.IOLimitCorrect -ne "Just Right") {$Vm | Get-VMResourceConfiguration | Set-VMResourceConfiguration -Disk $VmHdd -DiskLimitIOPerSecond $row.CalculatedIOLimit}

$report | Export-Csv $CsvExport -NoTypeInformation
Disconnect-VIServer $VCServer -Confirm:$false -Force:$true


XRDCLPXTMGT01Hard disk 10:00xr-004-p-s-st-brz-1581-003brz0.0380-12No IO Limit Set
XRDCWPTRMCTX07EHard disk 10:00xr-004-p-s-st-slv-1581-004slv0.440-116No IO Limit Set
XRDCWPTRMCTX07EHard disk 20:01xr-004-p-s-st-slv-1581-018slv0.475-130No IO Limit Set
XRDCWPWEBTAR01BHard disk 10:00xr-004-p-s-st-slv-1581-004slv0.440-116No IO Limit Set
XRDCWPWEBTAR01BHard disk 20:01xr-004-p-s-st-slv-1581-018slv0.450-120No IO Limit Set
1 Reply


thanks for creating this great script.

I extendet it with some Performance Stats for better trancperency.

Script - vSphere VM Disk IO Report und IO Limit - my cloud-(r)evolution

Kind Regards,

Markus | |
0 Kudos