Modify Hyper-V Msvm_StorageAllocationSettingData object with WMI though VBScript

I would like to modify the IOPS limit of vhdx files for a VM running on Windows Server 2012 R2. According to "Storage Quality of Service for Hyper-V" (http://technet.microsoft.com/en-us/library/dn282281.aspx) it is possible to do this through the WMI interface.

When using the below code it gives a Invalid method Parameter(s) when running the ExecMethod_ method.

Option Explicit

Const sVMId = "92B40B3E-7178-403C-A267-29884DC779FF" ' Virtual Machine

Dim oLoc, oVMMs, oVSMS, oVM, oVMSet, oVMCtrls, oVMDisk, oInParams, oOutParams

Set oLoc = CreateObject ("WBemScripting.SWBemLocator")
Set oVMMs = oLoc.ConnectServer (".", "root\virtualization\v2")
Set oVSMS = oVMMS.Get ("Msvm_VirtualSystemManagementService")
Set oVM = oVMMs.ExecQuery ("select * from Msvm_ComputerSystem where Name = '" & sVMId & "'").ItemIndex (0)
Set oVMSet = oVMMs.ExecQuery ("ASSOCIATORS OF {" & oVM.Path_.RelPath & "} WHERE ResultClass = Msvm_VirtualSystemSettingData").ItemIndex (0)

' Get the Msvm_ResourceAllocationSettingData and loop through to find the single SCSI controller
Set oVMDisk = oVMMs.ExecQuery ("ASSOCIATORS OF {" & oVMSet.Path_.RelPath & "} WHERE ResultClass = Msvm_StorageAllocationSettingData").ItemIndex (0)
oVMDisk.IOPSLimit = 450
oVMDisk.IOPSReservation = 400
' Create input parameter object
Set oInParams = oVSMS.Methods_("ModifyResourceSettings").InParameters.SpawnInstance_()
' Fill the input object with the new settings (array is required, otherwise type mismatch)
oInParams.ResourceSettings = Array (oVMDisk.GetText_(1))

' Modify the Msvm_StorageAllocationSettingData, below: Invalid method Parameter(s)
Set oOutParams = oVSMS.ExecMethod_("ModifyResourceSettings", oInParams)

' Display the method return value
WScript.Echo oOutParams.ReturnValue

Set oInParams = Nothing
Set oVMDisk = Nothing
Set oVMSet = Nothing
Set oVM = Nothing
Set oVSMS = Nothing
Set oVMMs = Nothing
Set oLoc = Nothing

I have another script that I use to modify IP adresses of an HyperV guest which uses the following code (I would guess the code to modify Resource Settings should be ok).

Set oInParams = oVSMS.Methods_("SetGuestNetworkAdapterConfiguration").InParameters.SpawnInstance_()
oInParams.ComputerSystem = oVM.Path_.Path
oInParams.NetworkConfiguration = Array (oItem.GetText_(1)) ' oItem is a Msvm_GuestNetworkAdapterConfiguration class
Set oOutParams = oVSMS.ExecMethod_("SetGuestNetworkAdapterConfiguration", oInParams)

The main difference between these is that the Msvm_StorageAllocationSettingData is a derived class of the expected CIM_ResourceAllocationSettingData class and for the SetGuestNetworkAdapterConfiguration method the expected class Msvm_GuestNetworkAdapterConfiguration is used.

I would like to know what should be changed to the VBScript to use the method ModifyResourceSettings for modification of the Msvm_StorageAllocationSettingData object.

Thanks in advance,

Dennis van den Akker
d.vandenakker@icento.nl

January 12th, 2015 1:26pm

Hi Dennis,

Any specific reason you are using Vbscript.

Below is nice PS Script on this

HYper-V QoS:

http://charbelnemnom.com/2014/12/how-to-set-storage-quality-of-service-qos-on-all-virtual-hard-disks-via-powershell-hyperv-powershell/

Few one lines that can do your job very easily.

This targets all VMs inside the Hyper-V-1 server:

Get-VM -ComputerName Hyper-V-1 | Get-VMHardDiskDrive | ft Vmname,ComputerName,*IOPS* -AutoSize

VMName         ComputerName MaximumIOPS MinimumIOPS
------         ------------ ----------- -----------
SERVER-1       Hyper-V-1              0           0
SERVER-2       Hyper-V-1              0           0
SERVER-3       Hyper-V-1              0           0
SERVER-4       Hyper-V-1              0           0

Below cmdlet to set the values to the above listed VMs:

Get-VM -ComputerName Hyper-V-1 | Set-VMHardDiskDrive -MaximumIOPS 450 -MinimumIOPS 400		
Free Windows Admin Tool Kit Click here and download it now
June 19th, 2015 7:19am

Hi Dennis,

Any specific reason you are using Vbscript.

Below is nice PS Script on this

HYper-V QoS:

http://charbelnemnom.com/2014/12/how-to-set-storage-quality-of-service-qos-on-all-virtual-hard-disks-via-powershell-hyperv-powershell/

Few one lines that can do your job very easily.

This targets all VMs inside the Hyper-V-1 server:

Get-VM -ComputerName Hyper-V-1 | Get-VMHardDiskDrive | ft Vmname,ComputerName,*IOPS* -AutoSize

VMName         ComputerName MaximumIOPS MinimumIOPS
------         ------------ ----------- -----------
SERVER-1       Hyper-V-1              0           0
SERVER-2       Hyper-V-1              0           0
SERVER-3       Hyper-V-1              0           0
SERVER-4       Hyper-V-1              0           0

Below cmdlet to set the values to the above listed VMs:

Get-VM -ComputerName Hyper-V-1 | Get-VMHardDiskDrive |Set-VMHardDiskDrive -MaximumIOPS 450 -MinimumIOPS 400		
June 19th, 2015 11:15am

Hi Satyajit,

I would like to modify the settings through VBScript as it's a easy to create a unsealed Operations Manager Management Pack with a task to set IOPS limit for a VM running on a host which doesn't have a trust from the computer initiating the request. A VBScript task can be created within Operations Manager without needing any additional tools such as the Authoring Console or Visual Studio.

The advantage of using WMI that there is no prerequisite required such as the Hyper-V PowerShell modules. Also each WMI method has a ReturnValue that can be used for process tracking if everything works as it should be. No need for try and catch.

I have many things I do automatically on Hyper-V hosts where nor I nor SMA has access to. In that case I make use of tasks which I've created in Operations Manager and can be executed on a Hyper-V host with an Operations Manager agent. Things I currently do this way is creating new Hyper-V replica's, resync Hyper-V replica's (after a alert rises in Operations Manager this is picked up by SMA and SMA creates through Operations Manager a task on the Hyper-V host to resync the VM), expand and shrink vhdx files. As a IOPS limit is depending on the size it would be nice if the expanding the vhdx Operations Manager VBScript task can be combined with changing the IOPS limit.

I've opened in this forum a post as I have no other method to get in contact with Microsoft. I've logged a support call for this at Professional Support services which didn't accept the case (SR 115012212309371). The only answer I got is that I would need a Premium Support Contract (as the Support Engineer saw this as a development question) or try the Microsoft forums.

Free Windows Admin Tool Kit Click here and download it now
June 22nd, 2015 8:06am

I've opened in this forum a post as I have no other method to get in contact with Microsoft. I've logged a support call for this at Professional Support services which didn't accept the case (SR 115012212309371). The only answer I got is that I would need a Premium Support Contract (as the Support Engineer saw this as a development question) or try the Microsoft forums.

Sorry, but there is no service-level agreement in these forums that guarantees an answer for you. Since your request has been unanswered for more than six months I think it is a safe bet that someone doesn't have the time to research this and write the code for you, particularly considering you want to use only VBScript and WMI.

June 22nd, 2015 12:40pm

I don't expect anyone to write the code for me (is not needed as I got that). The thing is that there is something missing from the Microsoft side to execute the code correctly.

It seems to be almost impossible to get things moving to get bugs resolved at Microsoft. For example since 23 of January this year I'm waiting to get a bug resolved in case number 115012212309333(which was confirmed on 10 of March it is a bug and there is no timeline when it will be resolved).

Free Windows Admin Tool Kit Click here and download it now
June 23rd, 2015 1:37am

Hi Dennis,

Thanks for the detailed info. I'll try to see if can get the same thing done via VBscript and WMI only.

Just to confirm is the PowerShell part I gave doing the extact IOPS config you wanted via VBscript. (This would help to match and validate things)

June 23rd, 2015 2:06am

Hi Dennis,

As you had posted in the earlier article, I had also tried out similar WMI only using PowerShell which works for me.

Now as you pointed out "I think it is a issue with the Hyper-V WMI implementation."

This is what I figured out.

When you write a WMI script using VBScript you make use of WMIs scripting API. In the scripting API, the SWbemObject object is used.

By contrast, Windows PowerShell accesses WMI through the .NET Framework and System.Management class. Rather than using SWbemObject, Windows PowerShell uses the System.Management.ManagementObject class.

So using VBscript generating error would mean there is an issue with WMIs scripting API and WMI using .NET Framework and System.Management class is just fine.

We can see where the trend is going by looking at Features Removed or Deprecated in Windows Server 2012:

    • The WMI provider for Active Directory is deprecated. Manage Active Directory with PowerShell cmdlets.
    • The WMI command-line tool (Wmic) is deprecated. Use PowerShell cmdlets instead.

PS WMI only script below incase you wanted to try out.

#Script to Get IOPS of VM and set it as well using PS Hyper-V module and WMI separately

#Using HyperV module----------

#Get-VM -ComputerName Hyper-V-1 | Get-VMHardDiskDrive | ft Vmname,ComputerName,*IOPS* -AutoSize
Get-VM -VMName VM-1 | Get-VMHardDiskDrive | ft Vmname,ComputerName,*IOPS* -AutoSize

#Get-VM -VMName VM-1 | Get-VMHardDiskDrive |Set-VMHardDiskDrive -MaximumIOPS 450 -MinimumIOPS 400


#Using WMI---------- (finally convert this to Vbscript)

$HyperVParent = "localhost"
$HyperVGuest = "VM-1"

$VMManagementService = Get-WmiObject -class "Msvm_VirtualSystemManagementService" -namespace "root\virtualization\v2" -ComputerName $HyperVParent

#Has method
$Vm = Get-WmiObject -Namespace "root\virtualization\v2" -ComputerName $HyperVParent -Query "Select * From Msvm_ComputerSystem Where ElementName='$HyperVGuest'"

$VMSettingData = Get-WmiObject -Namespace "root\virtualization\v2" -Query "Associators of {$Vm} Where ResultClass=Msvm_VirtualSystemSettingData AssocClass=Msvm_SettingsDefineState" -ComputerName $HyperVParent


#Getting the Path's for Attached VHD's 
$VirtualDiskResource = Get-WmiObject -Namespace "root\virtualization\v2" `
    -Query "Associators of {$VMSettingData} Where ResultClass=Msvm_StorageAllocationSettingData"`
    -ComputerName $HyperVParent 
#"Value read by WMI"
#$VirtualDiskResource | ft IOPSLimit,IOPSReservation -AutoSize

$VirtualDiskResource.IOPSLimit=450
$VirtualDiskResource.IOPSReservation=400

"Value set for WMI"
$VirtualDiskResource | ft IOPSLimit,IOPSReservation -AutoSize


#$VMManagementService.InvokeMethod("ModifyVirtualSystemResources", $VirtualDiskResource)
#V2 - for Win2012R2 its no longer exists. use ModifyResourceSettings


#Use the HyperV host object to call the modify function on the VMresourceObject with updated data
#$VirtualDiskResource - VM connection and data
#$VMManagementService - VM host where it will be changed
#psbase to send Raw data

$result = $VMManagementService.ModifyResourceSettings($VirtualDiskResource.psbase.GetText(1))

Get-VM -VMName VM-1 | Get-VMHardDiskDrive | ft Vmname,ComputerName,*IOPS* -AutoSize

#---References-------
#http://blogs.msdn.com/b/taylorb/archive/2008/08/21/hyper-v-wmi-what-vhd-s-physical-disks-are-associated-with-a-virtual-machine.aspx
#https://social.technet.microsoft.com/Forums/en-US/6d4d4ab1-0189-43cc-aa59-0a38a38e17e2/modify-hyperv-msvmstorageallocationsettingdata-object-with-wmi-though-vbscript?forum=ITCG
#Old V1 article - https://gallery.technet.microsoft.com/scriptcenter/93051878-9126-41d5-ba7e-16798fd7c35e
#ModifyResourceSettings( Accepts only 1 input not multiple) https://msdn.microsoft.com/en-us/library/hh850099%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Refernces:

Modifying a Read-Write Property Using Get-WMIObject

https://technet.microsoft.com/en-us/library/ee692805.aspx?f=255&MSPPError=-2147217396

Scripting API for WMI

https://msdn.microsoft.com/en-us/library/aa393258(v=vs.85).aspx

June 23rd, 2015 6:06am

I don't expect anyone to write the code for me (is not needed as I got that). The thing is that there is something missing from the Microsoft side to execute the code correctly.

Unfortunately there's nothing we can do about that from this forum, as we're not Microsoft employees and don't have the ear of the developers working on the problem in question.

Free Windows Admin Tool Kit Click here and download it now
June 23rd, 2015 10:18am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics