Hello there.
I need to set the IOPS limit on VMDKs with particular Storage Policy assigned, and the amount of IOPS should be set depending on the size of the VMDK. For example, 2 IOPS per gigabyte for Tier1, 1 IOPS per gigabyte for Tier2 and 0.5 IOPS per GB for Tier3. There will be 3 Policies total (maybe 4 later), and disks with Policy, which is different from the described three tiers (or with Default policy), should not get a limit.
I have written such script:
#Set the IOPS per Gigabyte for particular Storage Policy ("Tier1", "Tier2" and "Tier3" in my case and 2, 1 and 0.5 IOPS per GB accordingly)
$Tier1IOPSperGB = 2
$Tier2IOPSperGB = 1
$Tier3IOPSperGB = 0.5
#To store credentials in the XML file you should get credentials in a variable:
#$credentials = Get-Credential
#An then export it into file (which can be used only on the same machine):
#$credentials | Export-Clixml -Path "C:\Users\anatoliy\credentials.cred"
#Import credentials from XML file
$credentials = Import-Clixml -Path "C:\Users\anatoliy\credentials.cred"
#Connect the vCenter
Connect-VIServer vcsa1.nokogerra.lab -Credential $credentials
#Names of the VMs to be excluded from setting the IOPS limit are stored in the CSV. You can use a full name of the VM or a wildcard ("excludevms" if a column name):
#excludevms
#exclude1-test
#*clude2*
$csv = Import-Csv "C:\Users\anatoliy\Desktop\ExcludeVMs.csv"
#Fill the string array with names of the VMs to be excluded
foreach ($statement in $csv) {[string[]]$exclude += Get-VM -Name $statement.excludevms}
#Now get all VMs of the Virtual infrastructure except the VMs, which names were specified in the CSV file
$vms = Get-VM | ?{$exclude -notcontains $_.Name}
foreach ($vm in $vms){
#For each VM get all VMDKs
$VMDisk = $vm | Get-HardDisk
#For each VMDK get it's Storage Policy
foreach ($disk in $VMDisk){
$Policy = ($disk | get-SpbmEntityConfiguration).StoragePolicy.Name
#If "Tier1" Policy is assigned for the disk AND the correct limit is not already set
if (($Policy -eq "Tier1") -and
(($disk.Parent.ExtensionData.Config.Hardware.Device | where {($_ -is [VMware.Vim.VirtualDisk]) -and ($_.deviceinfo.label -eq $disk.name)}).StorageIOAllocation.Limit -ne ($disk.CapacityGB * $Tier1IOPSperGB))) {
#then set the limit, which depends of the disk size and Storage Policy
$disk.Parent | Get-VMResourceConfiguration | Set-VMResourceConfiguration -Disk $disk -DiskLimitIOPerSecond ($disk.CapacityGB * $Tier1IOPSperGB)
}
#Same for "Tier2"
elseif (($Policy -eq "Tier2") -and
(($disk.Parent.ExtensionData.Config.Hardware.Device | where {($_ -is [VMware.Vim.VirtualDisk]) -and ($_.deviceinfo.label -eq $disk.name)}).StorageIOAllocation.Limit -ne ($disk.CapacityGB * $Tier2IOPSperGB))) {
$disk.Parent | Get-VMResourceConfiguration | Set-VMResourceConfiguration -Disk $disk -DiskLimitIOPerSecond ($disk.CapacityGB * $Tier2IOPSperGB)}
#Same for "Tier3"
elseif (($Policy -eq "Tier3") -and
(($disk.Parent.ExtensionData.Config.Hardware.Device | where {($_ -is [VMware.Vim.VirtualDisk]) -and ($_.deviceinfo.label -eq $disk.name)}).StorageIOAllocation.Limit -ne ($disk.CapacityGB * $Tier3IOPSperGB))) {
$disk.Parent | Get-VMResourceConfiguration | Set-VMResourceConfiguration -Disk $disk -DiskLimitIOPerSecond ($disk.CapacityGB * $Tier3IOPSperGB)}
#Do nothing for other policies
else {Write-Host "Doing nothing"}
}
}
Remove-Variable exclude -Force -ErrorAction SilentlyContinue
Remove-Variable vms -Force -ErrorAction SilentlyContinue
Disconnect-VIServer vcsa1.nokogerra.lab -Confirm:$false
It seems that the script works properly, however I still need help to make some things:
1. I need to "trim" the size of a VMDK, which is returned by "$disk.CapacityGB". For example, if the disk size somehow became 100.825367 GB, then it should be counted as 101 GB. Actually, if it will be counted as 100GB it will be OK too, the difference in 2 IO per second is not significant.
2. I think, I need some report, which will cover the script execution result. To be honest, I'm still not sure how it should look like, may be an email with errors? I'm planning to run this script periodically (every day, I guess), so I need some info if the execution was sucessful.
3. Any idea how to optimize this script in any other way? I'm a pretty bad writer, so it would be nice to get some advice :smileyhappy: