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.
1 2 3 4 |
//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:
1 2 3 4 5 6 7 8 9 10 |
//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:
1 2 3 4 5 6 7 8 9 10 11 |
//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]; } |
Storage From Here
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//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: