I recently saw a post on Reddit about pulling a VM storage policy from a VM using vRO and it was stated that it was not possible which was said to be confirmed by VMware support.
‘Now I don’t know when they asked VMware support, and if it was two years or so ago, then that was true. But it is certainly not true now. Though I will admit, it is not super intuitive to figure out unless you know where to look. Here is how you do it.
Btw, I only tested this with VVol storage policies, but it really should not matter at all.
First off, you can find my exported workflow here:
Click “View Raw” to download the .workflow file.
Now I am using vRO 7.6, but this should work back to 7.3 at least–maybe 7.2.
There is only a single input, a VM.
It returns all of the pbmProfile objects that it finds for that VM. A policy can be assigned to the entire VM, or to the home and disks individually. So it looks through all of those objects and then returns the policies that are unique. This VM has two disks, the same policy is assigned to the home and disk 1, and a different policy is assigned to disk 2.
Okay, so the JavaScript:
The first part is getting the vCenter connection and the Profile Management service:
I’ve removed all of my logging/debug logging to make the below quicker/easier to read. The GitHub file has it all though.
//get connections vcenter = vm.sdkConnection; var storageService = vcenter.storageManagement; var profileManager = storageService.pbmProfileManager;
profileManager is storing the PBM service. In that is a method called pbmQueryAssociatedProfile that gets the policy IDs. I first do it on the home of the VM:
//get VM home policy var myPbmServerObjectRef = new PbmServerObjectRef() ; myPbmServerObjectRef.key = vm.moref.value; myPbmServerObjectRef.objectType = "virtualMachine" var vmProfiles = profileManager.pbmQueryAssociatedProfile(myPbmServerObjectRef); var myPolicy = getPolicyFromId(vmProfiles[0].uniqueId,vcenter); var foundProfiles = []; foundProfiles.push(myPolicy); var foundIDs = []; foundIDs.push(vmProfiles[0].uniqueId);
In order to run that query, we have to pass in a PbmObjectServerRef object. This says the managed object reference of the thing you want to look at and the type. To look at the home of a VM the object type is virtualMachine. The moref is from the VM. Basically a string that looks like vm-132 or whatever number.
I also wrote a quick function (because I will use it a few times) that takes the return of that method and actually finds the corresponding pbmProfile (the storage policy object). The return of pbmQueryAssociatedProfiles only gives an ID which wont include the friendly name of the policy etc. The pbmProfile object has all of the useful info.
The function:
//function to get pbmProfile object from policy ID function getPolicyFromId (policyID, vcenter){ var myPbmProfileId = new PbmProfileId() ; myPbmProfileId.uniqueId = policyID; var storageService = vcenter.storageManagement; var profileManager = storageService.pbmProfileManager; var profileIdArray = []; profileIdArray.push(myPbmProfileId); var policies = profileManager.pbmRetrieveContent(profileIdArray); return policies[0]; }
Takes in the vCenter (sdkConnection) and the policy ID. Returns the profile.
Then I iterate through the disks to do the same thing. If the policy ID has already been found in a previous part of the VM I skip that profile.
To run pbmQueryAssociatedProfile with a disk, it has the VM moref, plus colon, plus the disk key. So something like vm-132:2000.
The object type is virtualDiskId. The rest is the same as above.
//get policies from virtual disks if different than home or previous disks var vmDevices = vm.config.hardware.device; for (var i = 0; i < vmDevices.length; i++) { if (vmDevices[i] instanceof VcVirtualDisk) { var myPbmServerObjectRef = new PbmServerObjectRef() ; myPbmServerObjectRef.key = vm.moref.value + ":" + vmDevices[i].key; myPbmServerObjectRef.objectType = "virtualDiskId" var vmProfiles = profileManager.pbmQueryAssociatedProfile(myPbmServerObjectRef); var myPolicy = getPolicyFromId(vmProfiles[0].uniqueId,vcenter); if (foundIDs.indexOf(vmProfiles[0].uniqueId) != -1) { foundIDs.push(vmProfiles[0].uniqueId); foundProfiles.push(myPolicy); } } }
Enjoy!
I also wrote a post on assigning one to a VM back here:
Thanks for sharing ! Very, very useful. Cheers.
You’re welcome!
Hello,
How can I set the “Datastore Default” VM storage policy?
I can’t find a way to reset to default.
Thanks
The datastore default isn’t really a policy–it just says to use the default policy if there is on. For vVols the default policy will be VVol No Requirements unless you set one. For VMFS, there is no default policy so it will remain listed as datastore default. But to revert it to the default policy just choose the VM and then edit policy and choose default. That will revert it to vVol No requirements or whatever you have configured as a default.
Hello Cody,
We are experiencing some issues with VM Storage Policies. We have created a storage policy that limits the IOPS to 5000.
When we apply the VM storage policy to the VM using the GUI (select vm -> VM policies -> edit vm storage policies), we see that the policy is applied (verified via Edit VM settings), but the Limit-IOPs is still set to ‘unlimited’.
If we run a benchmark inside the VM and check ESXTOP, we see that the IOPS are actually capped to 5000 (with a latency of 12, which is normal because of the IOPs limit). So the VM storage policy does work.
However when we apply the policy, but also change the IOPS-limit to 5000, we encounter performance issues. VM doesn’t reach the 5000 IOPS limit and we get high latency (high KAVG).
Is this normal behaviour? is het normal that when you apply the vm storage policy, the IOPS limit you see via “Edit vm”, should be ‘unlimited’? Are there differences in how you can configure IOPS limit.
We don’t have any SOIC configured on the datastore. And there are no performance issues at the backend storage. If we change the vm storage policy to ‘datastore default’, that VM gets 30k IOPS with no latency.
Thanks for the info.
Cheers,
Chris
Well awhile back the original behavior with IOPS limits in vSphere via the I/O scheduler was that any IO larger than 32K actually counted for each 32K it had–so a 63K I/O was counted as two, a 65K IO was counted as 3 I/Os etc. So it is possible one method is engaging the old scheduler and larger I/Os are making it hit the limit faster. Beyond that could be a bug (likely is anyways I guess). Have you opened a ticket with VMware?