Hey there, I need to limit the iops of the disks connected to my virtual machines via powercli.
I am using the following command :
Get-VM 'vm_name' | Get-VMResourceConfiguration | Set-VMResourceconfiguration -configuration DiskResourceConfiguration -DiskLimitIOPerSecond 100
But this gives an error:
Set-VMResourceConfiguration : Cannot bind parameter 'Configuration'. Cannot convert the "DiskResourceConfiguration" value of type "System.String
" to type "VMware.VimAutomation.ViCore.Types.V1.VM.VMResourceConfiguration".
At line:1 char:86
+ Get-VM $vm | Get-VMResourceConfiguration | Set-VMResourceconfiguration -configuration <<<< DiskResourceConfiguration -DiskLimitIOPerSecond 10
0
+ CategoryInfo : InvalidArgument: (:) [Set-VMResourceConfiguration], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetVMResourceConfiguration
Can someone please suggest me, where am I going wrong ?
Try it like this
foreach($group in (Import-Csv C:\vmiopslimit.csv -UseCulture | Group-Object -Property vmName)){ $vm = Get-VM -Name $group.Name
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vm.ExtensionData.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualDisk]} | %{ $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
$dev.Operation = "edit"
$dev.Device = $_
$label = $_.DeviceInfo.Label
$dev.Device.StorageIOAllocation.Limit = $group.Group | where {$_.Harddisk -eq $label} | Select -ExpandProperty IOPSLimit
$spec.DeviceChange += $dev
} $vm.ExtensionData.ReconfigVM_Task($spec) }
The CSV file should look like this
"vmName","harddisk","IOPSLimit"
"VM1","Hard disk 1","50"
"VM1","Hard disk 2","75""VM2","Hard disk 1","75"
"VM3","Hard disk 1","35"
"VM3","Hard disk 2","55""VM3","Hard disk 3","65"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
You pass the VMResourceConfiguration through the pipeline from the Get-VMResourceConfiguration
Just do
Get-VM 'vm_name' | Get-VMResourceConfiguration | Set-VMResourceconfiguration -DiskLimitIOPerSecond 100
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hey LucD thanks a lot for your reply. But when I type the command suggested by you :
I am getting the output as
VM NumCpuShares CpuSharesLevel NumMemShares MemShares
evel
-- ------------ -------------- ------------ ---------
Vm_name 16000 Normal 163840 Normal
but its not limiting the iops of the disk.
I am getting the same output if I just type the command :
Get-VM vm_name | Get-VMResourceConfiguration
Can you plaese tell me why its not reading the second pipeline argument. Also if I have more than one disk connected to VM can I specify diffrent iops for each of them.
The Set-VMResourceConfiguration cmdlet returns indeed the same object as the Get-VMResourceConfiguration cmdlet.
But the difference is that the Set- cmdlet will display the updated values, as you specified them on the Set-VMResourceConfiguration cmdlet.
Is that VM powered off ?
Some of the resource changes only take effect after a poweroff/poweron. See KB1038241.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanx again for the reply!!
Yes my Virtual machine is powered off and after executing the command when I try to check the update manually in GUI I dont see the new values there.
Just checked again, and there seems to be indeed a problem with the DiskLimitIOPerSecond parameter :smileycry:
Try it like this
$vmName = "MyVM"
$DiskLimitIOPerSecond = 50
# $DiskLimitIOPerSecond = -1 # Unlimited $vm = Get-VM -Name $vmName $spec = New-Object VMware.Vim.VirtualMachineConfigSpec $vm.ExtensionData.Config.Hardware.Device |
where {$_ -is [VMware.Vim.VirtualDisk]} | %{ $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
$dev.Operation = "edit"
$dev.Device = $_
$dev.Device.StorageIOAllocation.Limit = $DiskLimitIOPerSecond
$spec.DeviceChange += $dev
} $vm.ExtensionData.ReconfigVM_Task($spec)
Note: to set the limit back to unlimited, you have to give the value -1
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks a ton LucD this works perfectly fine .
However this works only for the virtual disk connected to the VM but I also have a large number of raw devices(LUN's) mapped to my VM. Is it possible to control the IOPS on each of them ?
Strange, when the RDM is connected to a VM as a harddisk it works as well.
How are these RDM connected ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I am not sure if I have understood your question correctly. If not then I am sorry and request you to be more specific.
Following is the table shown during the connectivity of a new RDM :
Hardware type: HardDisk
create disk: Use mapped system LUN
Virtual Device Node: SCSI(0:2)
Disk mode: Persistent
Target LUN: Fibre channel Disk(naa.60...)
compatiblity moded: physical
mapped datastore: Store with VM
No, that is what I wanted to know.
The RDM is connected as a virtualdisk.
And the above code doesn't change the IOPS limit for that harddisk ?
Are there any errors in the vSphere client ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
okay I checked it again and it works fine .
But it changes the iops only for single RDM connected to the virtual machine. Can you suggest me the modifications I should perform in order to limit the iops of all the RDM's connected to my VM.
Also can i specify diffrent IOPS limit for diffrent RDM's connected to a single VM.
It should change the IOPS limit for all harddisks connected to a VM.
Tested again, and that seems to work for me.
And yes, you can have different IOPS limits for different harddisks.
You could test on the harddisk label ("Hard disk n") in the DeviceInfo.Label property, and based on that specify different limits.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Strange because in my case it just modifies the IOPS for first hard disk .
As I am not much familiar with the power cli commands I request you to please provide me with a code which can assign diffrent iops to the RDM's of a single VM( I tried it myself but got no sucess )
Sorry if I am asking too much but your support will be a great help to me .
First another question, how do you intend to provide that information to the script ?
In a CSV file ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes,I will be providing values to the script via csv file which will have the hard disk name and the limit of IOPS.
Try it like this
foreach($group in (Import-Csv C:\vmiopslimit.csv -UseCulture | Group-Object -Property vmName)){ $vm = Get-VM -Name $group.Name
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vm.ExtensionData.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualDisk]} | %{ $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
$dev.Operation = "edit"
$dev.Device = $_
$label = $_.DeviceInfo.Label
$dev.Device.StorageIOAllocation.Limit = $group.Group | where {$_.Harddisk -eq $label} | Select -ExpandProperty IOPSLimit
$spec.DeviceChange += $dev
} $vm.ExtensionData.ReconfigVM_Task($spec) }
The CSV file should look like this
"vmName","harddisk","IOPSLimit"
"VM1","Hard disk 1","50"
"VM1","Hard disk 2","75""VM2","Hard disk 1","75"
"VM3","Hard disk 1","35"
"VM3","Hard disk 2","55""VM3","Hard disk 3","65"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hey LucD, it works perfectly :smileygrin:.
Thanks a lot for the great help. you ROCK !!
Hey LucD,
Thanks again for the great help, I have been working on this script from quite some time and it has really helped me with my project.
However, I have one more request. As of now when I execute this script it takes initial 10- 15 seconds to from connection with the server and once the connection is formed it takes almost 1second per VM to get reconfigured, moreover it is done in sequential manner.
Currently in my environment I have around 100 VM, hence it takes around 100 seconds for the task to get finish. Is there any way by which i can execute all this in parallel mode and it should take comparatively less time to reconfigure all.
I need this because I have a seprate set of code which start the benchmarking software on these VM's. The script provided by you and my code works in parallel.
FYI** my server is of very high configuration, so I am sure that this problem is not due to slow hardware
Any kind of suggestion will be really helpful to me.
Best Regards,
Ashish
The script calls the ReconfigVM_Task method.
Each SDK method is mapped to 2 entry points in PowerCLI, the method with a _Task suffix and without that suffix.
If you call the method with _Task suffix it will return immediatly, the entry point without the suffix will wait till the task is complete.
So in fact, the script above should already be launching these calls without waiting for the completion.
Perhaps you are hitting a vSphere limitation on the numbers of tasks that can be running in parallel.
How many of these tasks do you see running in parallel, if any ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hey thanks for your response,
With this I am attaching the event list for first 16 VM's. As you can see the new request start time is always after the end request of the previous one. Also the difference between the starting time of 1st VM and completion time of last VM is 9 seconds.
Moreover as you mentioned regarding task limit, I have one more doubt. As i said in my previous post that I execute 2 sperate scripts in parallel:
1. to control IOPS on each RDM connected to VM (using POWERCLI)
2. to start benchmarking application (FIO) on these VM ( using VMRUN)
I am running both these scripts in a LOOP, such that after every 5 minutes they execute a new set of instructions. What's happening is, for initial few hours( around 6 hours) everything works perfectly. But after that either VM becomes very slow in response to both the request or second script(to start FIO) is totally stopped. However, if I restart the VM's, everything is fine again
Until now I have no valid solution for this kind of behavior, it will be really great if you can suggest something regarding this too.
I hope I was clear enough in specifying my problem, if not then i request you to let me know, will try to elaborate.
Best Regards,
Ashish