Hi there, I have a worfklow where I modified the basic Clone VM WF to clone my VM to a set of datastores based on the disk. I have a step in the workflow that determines which disk goes where, then passes into a final script that is supposed to build the StoragePlacementSpec. It all looks correct to me, given the documentation and examples I can find. However, I always get the following error after the applyStorageDrsRecommendation_Task call:
Task 'ApplyStorageDrsRecommendation_Task' error: A specified parameter was not correct. Key does not match StoragePlacementSpec.podSelectionSpec.initialVmConfig (Dynamic Script Module name : vim3WaitTaskEndDrs#27)
The error doesn't' make any sense to me.
Here is the script I'm using:
System.log("Source VM: " + vm.name); System.log("New VM Name: " + vmName); System.log("Target VM Host: " + targetVmHost.name); // Setup the hard disk mappings: var defaultDatastoreCluster = initialVmConfig.vmxDatastoreCluster; // Setup the Storage Specification: var storageSpec = new VcStoragePlacementSpec(); storageSpec.type = "clone"; storageSpec.vm = vm; storageSpec.cloneSpec = cloneSpec; storageSpec.cloneName = vmName; storageSpec.podSelectionSpec = new VcStorageDrsPodSelectionSpec(); storageSpec.podSelectionSpec.storagePod = defaultDatastoreCluster; var placementArray = []; if ( initialVmConfig.initialVmConfig != null && initialVmConfig.initialVmConfig.length > 0 ) { for each ( plc in initialVmConfig.initialVmConfig ) { placementArray.push(plc); } } else { System.debug("No disks specified."); // Default placement of all VM disks in the same DS Cluster: var placement = new VcVmPodConfigForPlacement(); placement.storagePod = defaultDatastoreCluster; placementArray.push(placement); } // You have to assign a filled array object to this property, you can't just initialize an empty array and add elements to it for some reason: storageSpec.podSelectionSpec.initialVmConfig = placementArray; System.debug("VM File DatastoreCluster: " + storageSpec.podSelectionSpec.storagePod.name); System.debug("StorageSpec InitialConfig: " + storageSpec.podSelectionSpec.initialVmConfig); if ( storageSpec.podSelectionSpec.initialVmConfig ) { System.debug("StorageSpec InitialConfig Length: " + storageSpec.podSelectionSpec.initialVmConfig.length.toString()); for each ( plc in storageSpec.podSelectionSpec.initialVmConfig ) { System.debug("Disk: " + plc.disk[0].diskId + " will be created in DatastoreCluster " + plc.storagePod.name); } } if ( !vmFolder ) { // Default to "Discovered Virtual Machines": vmFolder = System.getModule("com.plex.vco").getVmFolderByName("Discovered Virtual",vCenterSdkConnection)[0]; } storageSpec.folder = vmFolder; if ( targetVmHost != null ) { storageSpec.host = targetVmHost; } // Get the DRS Recommendations for disk placement: var managedObject = vm.sdkConnection.storageResourceManager; var myVcStoragePlacementResult = VcStoragePlacementResult(); myVcStoragePlacementResult = managedObject.recommendDatastores(storageSpec); // Apply the DRS Recommendations: var myKey = new Array(); myKey[0] = myVcStoragePlacementResult.recommendations[0].key; myVcTask = managedObject.applyStorageDrsRecommendation_Task(myKey); return myVcTask;
In this script, I'm passing in an array of VcVmPodConfigForPlacementObjects to build the initialConfig. Each placement has a disk locator defined and it's target datastore defined. Here is that code:
var vmDiskAssignments = diskAssignmentResultPowershellObject.getRootObject(); var vmConfig = { initialVmConfig : [], vmxDatastoreCluster : null }; // Assign disk relocaton specification: for each ( da in vmDiskAssignments ) { var datastoreCluster = da.getProperty("Target"); var diskId = Number(da.getProperty("DiskId")); var datastoreClusterVcoObject = System.getModule("com.plex.vco").getVcoObjectByPowerShellObject(datastoreCluster); if ( diskId > 0 ) { // Add the disk mapping to the initial config: var locator = new VcPodDiskLocator(); locator.diskId = diskId; var placement = new VcVmPodConfigForPlacement(); placement.disk = [locator]; placement.storagePod = datastoreClusterVcoObject; vmConfig.initialVmConfig.push(placement); } else { // Add the vmx file location: vmConfig.vmxDatastoreCluster = datastoreClusterVcoObject; } } return vmConfig;
Here is the output I get from VCO:
[2015-10-25 18:22:11.121] [D] UID: /VIServer=domain\myaccount@myvcenter.domain.com:443/DatastoreCluster=StoragePod-group-p865/
[2015-10-25 18:22:11.121] [D] ID to convert: myvcenter.domain.com/group-p865
[2015-10-25 18:22:11.121] [D] VCO Type found: VC:StoragePod
[2015-10-25 18:22:11.121] [D] Adding DiskId: 2000 DSC: dsc_dv-db-cluster01_sqldb_sata_01
[2015-10-25 18:22:11.121] [D] UID: /VIServer=domain\myaccount@myvcenter.domain.com:443/DatastoreCluster=StoragePod-group-p811/
[2015-10-25 18:22:11.121] [D] ID to convert: myvcenter.domain.com/group-p811
[2015-10-25 18:22:11.121] [D] VCO Type found: VC:StoragePod
[2015-10-25 18:22:11.121] [D] Adding DiskId: 2001 DSC: dsc_dv-db-cluster01_guest_swap_01
[2015-10-25 18:22:11.121] [D] UID: /VIServer=domain\myaccount@myvcenter.domain.com:443/DatastoreCluster=StoragePod-group-p864/
[2015-10-25 18:22:11.121] [D] ID to convert: myvcenter.domain.com/group-p864
[2015-10-25 18:22:11.121] [D] VCO Type found: VC:StoragePod
[2015-10-25 18:22:11.121] [D] Adding DiskId: 2002 DSC: dsc_dv-db-cluster01_sql_tempdb_01
[2015-10-25 18:22:11.121] [D] UID: /VIServer=domain\myaccount@myvcenter.domain.com:443/DatastoreCluster=StoragePod-group-p865/
[2015-10-25 18:22:11.121] [D] ID to convert: myvcenter.domain.com/group-p865
[2015-10-25 18:22:11.121] [D] VCO Type found: VC:StoragePod
[2015-10-25 18:22:11.121] [D] Adding Default DSC: dsc_dv-db-cluster01_sqldb_sata_01
[2015-10-25 18:22:11.168] [D] Session is not new and will be left open.
[2015-10-25 18:22:11.621] [I] Source VM: DV-DB14-2k12r2-t2
[2015-10-25 18:22:11.621] [I] New VM Name: dv-vcotest01
[2015-10-25 18:22:11.621] [I] Target VM Host: dv-esxi-db02.plex.com
[2015-10-25 18:22:11.636] [D] VM File DatastoreCluster: dsc_dv-db-cluster01_sqldb_sata_01
[2015-10-25 18:22:11.636] [D] StorageSpec InitialConfig: DynamicWrapper (Instance) : [VcVmPodConfigForPlacement]-[class com.vmware.vim.vi4.VmPodConfigForPlacement] -- VALUE : com.vmware.vim.vi4.VmPodConfigForPlacement@f109aad2,DynamicWrapper (Instance) : [VcVmPodConfigForPlacement]-[class com.vmware.vim.vi4.VmPodConfigForPlacement] -- VALUE : com.vmware.vim.vi4.VmPodConfigForPlacement@f109aa34,DynamicWrapper (Instance) : [VcVmPodConfigForPlacement]-[class com.vmware.vim.vi4.VmPodConfigForPlacement] -- VALUE : com.vmware.vim.vi4.VmPodConfigForPlacement@f109aad3
[2015-10-25 18:22:11.636] [D] StorageSpec InitialConfig Length: 3
[2015-10-25 18:22:11.636] [D] Disk: 2000 will be created in DatastoreCluster dsc_dv-db-cluster01_sqldb_sata_01
[2015-10-25 18:22:11.636] [D] Disk: 2001 will be created in DatastoreCluster dsc_dv-db-cluster01_guest_swap_01
[2015-10-25 18:22:11.636] [D] Disk: 2002 will be created in DatastoreCluster dsc_dv-db-cluster01_sql_tempdb_01
[2015-10-25 18:22:12.698] [I] Task 'ApplyStorageDrsRecommendation_Task' error: A specified parameter was not correct.
Key does not match StoragePlacementSpec.podSelectionSpec.initialVmConfig (Dynamic Script Module name : vim3WaitTaskEndDrs#27)
[2015-10-25 18:22:12.729] [D] Closing session with ID: 06c65bed-5aa9-4080-9ad3-5dc3a4346b98
Most of the examples I see show people cloning a VM and all of it's disks to a single DS Cluster, so they're only partially helpful. Does anyone have any idea where I'm off the track? Thanks!