First off, there already is a built-in workflow for adding a new virtual disk so this isn’t exactly groundbreaking knowledge, but I think it is helpful to understand how it is constructed. Furthermore, most of the existing posts and community articles out there assume way too much about ones knowledge of reading the API guide and understanding what is needed.
So let’s boil it down to only what you need to know to create default, commonly used virtual disks. If you want more advanced configurations this should give you a good starting point. Knowing the basics makes it way it is easier to edit and change.
So there are essentially two main steps in creating a virtual disk:
- Defining the file itself (the VMDK)
- Defining the connection info for the VMDK
The lines blur a bit between these two. Let’s start with the file, referred to as the “backing”.
The object type that holds the backing info is called VcVirtualDiskFlatVer2BackingInfo. A bit of a mouthful but that’s the name. So let’s start by declaring that.
var diskBackingInfo = new VcVirtualDiskFlatVer2BackingInfo();
- Disk mode. Invariably this is “persistent”. This is your default option.
- File name. Since this is a new virtual disk the file name is just the datastore that it will be stored on. This is a string with the datastore name in brackets like so “[MyDatastore]”
- Virtual disk type. This is denoted by one of two boolean properties, either “thinProvisioned” or “eagerlyScrubbed”. If thinProvisioned is set to true, it will be thin. If eagerlyScrubbed is set to true it will be eagerzeroedthick. If they are both false (or not present, it will be zeroedthick.
So if I want to put a persistent virtual disk on my datastore called “MyDatastore” and it is to be thin it will be like:
var diskBackingInfo = new VcVirtualDiskFlatVer2BackingInfo(); diskBackingInfo.diskMode = "persistent"; diskBackingInfo.fileName = "[SQLProddata]"; diskBackingInfo.thinProvisioned = true;
If I want it to be eagerzeroedthick it would be like:
var diskBackingInfo = new VcVirtualDiskFlatVer2BackingInfo(); diskBackingInfo.diskMode = "persistent"; diskBackingInfo.fileName = "[SQLProddata]"; diskBackingInfo.eagerlyScrub = true;
var diskBackingInfo = new VcVirtualDiskFlatVer2BackingInfo(); diskBackingInfo.diskMode = "persistent";
So now that the backing file is done let’s create the connection to the VM itself. This part (at a minimum) requires four things:
- The backing info designated above.
- The SCSI controller key (more on this in a second)
- The unit number, which is basically just the SCSI slot on the controller.
- A capacity in KB.
So first let’s define the virtual disk. I define this type and call it “disk”
var disk = new VcVirtualDisk();
The properties have specific names, just like before. So add the backing information above (which I named earlier “diskBackingInfo”).
disk.backing = diskBackingInfo;
Now the SCSI controller key. This is the identifying number of the virtual SCSI controller. As far as I can tell this is pretty straight forward. The first SCSI controller key is 1000, the second is 1001, the third is 1002 and the fourth is always 1004. What is confusing is if you look at the virtual SCSI controller properties in the SDK, the controller has a property called “controllerKey”. This is NOT the right number–it is always 100. The “property” called “key” is the right one.
The next part is the unit number. This can be anything from zero to 15, except for 7–this is reserved. Then lastly the capacity of the virtual disk in KB. So here would be the full code for a 25 GB virtual disk on the first virtual SCSI controller at slot 4:
var disk = new VcVirtualDisk(); disk.backing = diskBackingInfo; disk.controllerKey = 1000; disk.unitNumber = 4; disk.capacityInKB = 262144004;
Now it is time to put it together. We need to now put the new device we defined into a new object called VcVirtualDeviceConfigSpec. I will define it in an object called deviceConfigSpec.
var deviceConfigSpec = new VcVirtualDeviceConfigSpec();
Now I need to populate that object with its properties:
- The device being added, in this case my virtual disk.
- The operation required for that file, is it being created or is it pre-existing or is being deleted?
- What is being done to the virtual machine itself. Is the device being changed, removed or added?
So to add the disk it is simply this:
deviceConfigSpec.device = disk
I want to create a new virtual disk, so the “fileOperation” property should be set to “create”. This needs to be a special object called VcVirtualDeviceConfigSpecFileOperation:
deviceConfigSpec.fileOperation = VcVirtualDeviceConfigSpecFileOperation.create;
The finally what is being done to the VM–in this case adding it:
deviceConfigSpec.operation = VcVirtualDeviceConfigSpecOperation.add;
Now we cannot just pass in the deviceConfigSpec directly, as the property that stores that object expects an array object. So let’s define an empty array called deviceConfigSpecs (notice the pluralization). Then push the singular deviceConfigSpec into that array:
var deviceConfigSpecs = ; deviceConfigSpecs.push(deviceConfigSpec);
What this means is that you can define multiple virtual disks at once and use .push to put them all into that array. Once you have defined your virtual disks and added them to the array, it is time to add them to the final object the virtual machine configuration object called VcVirtualMachineConfigSpec.
I will define my final object of that type and call it configSpec.
var configSpec = new VcVirtualMachineConfigSpec();
Now I will add it to the deviceChange property:
configSpec.deviceChange = deviceConfigSpecs;
Now let’s actually run it! This is the virtual machine object method called “reconfigVM_Task”. My virtual machine object is stored in an object called “virtualMachine”:
Run it and the virtual disk is added! We’re done. I will follow up with adding an existing virtual disk and then deleting in subsequent posts.
This is all of the code in one snippet to add one persistent, thin virtual disk that is 25 GB to virtual SCSI controller 0 to slot 14 on datastore “MyDatastore”.
Note for simplification of understanding I have ripped out error handling etc.
// Create Disk BackingInfo var diskBackingInfo = new VcVirtualDiskFlatVer2BackingInfo(); diskBackingInfo.diskMode = "persistent"; diskBackingInfo.fileName = "[MyDatastore]"; diskBackingInfo.thinProvisioned = true; // Create VirtualDisk var disk = new VcVirtualDisk(); disk.backing = diskBackingInfo; disk.controllerKey = 1000; disk.unitNumber = 14; disk.capacityInKB = 262144004; // Create Disk ConfigSpec var deviceConfigSpec = new VcVirtualDeviceConfigSpec(); deviceConfigSpec.device = disk; deviceConfigSpec.fileOperation = VcVirtualDeviceConfigSpecFileOperation.create; deviceConfigSpec.operation = VcVirtualDeviceConfigSpecOperation.add; var deviceConfigSpecs = ; deviceConfigSpecs.push(deviceConfigSpec); // List of devices var configSpec = new VcVirtualMachineConfigSpec(); configSpec.deviceChange = deviceConfigSpecs; // Launch the reconfigVM task virtualMachine.reconfigVM_Task(configSpec);