Creating a Virtual Machine

This section shows how to create a VirtualMachine object, which is complicated but necessary so you can restore data into it. Before creating this object, you must create a
VirtualMachineConfigSpec
describing the virtual machine and all of its supporting virtual devices. Almost all the required information is available from the virtual machine property
config.hardware.device
, which is a table containing the device configuration information. The relationships between devices are described by the value
key
, which is a unique identifier for the device. In turn, each device has a
controllerKey
, which is the key identifier of the controller where the device is connected. Use negative integers as temporary key values in the
VirtualMachineConfigSpec
to guarantee that temporary key numbers do not conflict with real key numbers when they are assigned by the server. When associating virtual devices with default devices, the
controllerKey
property should be reset with the key property of the controller. Below are the settings for a sample
VirtualMachineConfigSpec
used to create a virtual machine.
// beginning of VirtualMachineConfigSpec, ends several pages later {    dynamicType = <unset>,    changeVersion = <unset>, //This is the display name of the VM    name = “My New VM“,    version = "vmx-04",    uuid = <unset>,    instanceUuid = <unset>,    locationId = <unset>, // This is advisory, the disk determines the O/S guestId = "winNetStandardGuest",    alternateGuestName = "Microsoft Windows Server 2008, Enterprise Edition",    annotation = <unset>,    files = (vim.vm.FileInfo) {       dynamicType = <unset>,       vmPathName = "[plat004-local]",       snapshotDirectory = "[plat004-local]",       suspendDirectory = <unset>,       logDirectory = <unset>,    },    tools = (vim.vm.ToolsConfigInfo) {       dynamicType = <unset>,       toolsVersion = <unset>,       afterPowerOn = true,       afterResume = true,       beforeGuestStandby = true,       beforeGuestShutdown = true,       beforeGuestReboot = true,       toolsUpgradePolicy = <unset>,       pendingCustomization = <unset>,       syncTimeWithHost = <unset>,    },    flags = (vim.vm.FlagInfo) {       dynamicType = <unset>,       disableAcceleration = <unset>,       enableLogging = <unset>,       useToe = <unset>,       runWithDebugInfo = <unset>,       monitorType = <unset>,       htSharing = <unset>,       snapshotDisabled = <unset>,       snapshotLocked = <unset>,       diskUuidEnabled = <unset>,       virtualMmuUsage = <unset>,       snapshotPowerOffBehavior = "powerOff",       recordReplayEnabled = <unset>,    },    consolePreferences = (vim.vm.ConsolePreferences) null,    powerOpInfo = (vim.vm.DefaultPowerOpInfo) {       dynamicType = <unset>,       powerOffType = "preset",       suspendType = "preset",       resetType = "preset",       defaultPowerOffType = <unset>,       defaultSuspendType = <unset>,       defaultResetType = <unset>,       standbyAction = "powerOnSuspend",    },    // the number of CPUs    numCPUs = 1,    // the number of memory megabytes    memoryMB = 256,    memoryHotAddEnabled = <unset>,    cpuHotAddEnabled = <unset>,    cpuHotRemoveEnabled = <unset>,    deviceChange = (vim.vm.device.VirtualDeviceSpec) [       (vim.vm.device.VirtualDeviceSpec) {          dynamicType = <unset>,          operation = "add",          fileOperation = <unset>,          // CDROM          device = (vim.vm.device.VirtualCdrom) {             dynamicType = <unset>,             // key number of CDROM             key = -42,             deviceInfo = (vim.Description) null,             backing = (vim.vm.device.VirtualCdrom.RemotePassthroughBackingInfo) {                dynamicType = <unset>,                deviceName = "",                useAutoDetect = <unset>,                exclusive = false,             },             connectable = (vim.vm.device.VirtualDevice.ConnectInfo) {                dynamicType = <unset>,                startConnected = false,                allowGuestControl = true,                connected = false,             },             // connects to this controller             controllerKey = 200,             unitNumber = 0,          },       },       (vim.vm.device.VirtualDeviceSpec) {          dynamicType = <unset>,          operation = "add",          fileOperation = <unset>,          // SCSI controller          device = (vim.vm.device.VirtualLsiLogicController) {             dynamicType = <unset>, // key number of SCSI controller             key = -44,             deviceInfo = (vim.Description) null,             backing = (vim.vm.device.VirtualDevice.BackingInfo) null,             connectable = (vim.vm.device.VirtualDevice.ConnectInfo) null,             controllerKey = <unset>,             unitNumber = <unset>,             busNumber = 0,             hotAddRemove = <unset>,             sharedBus = "noSharing",             scsiCtlrUnitNumber = <unset>,          },       },       (vim.vm.device.VirtualDeviceSpec) {          dynamicType = <unset>,          operation = "add",          fileOperation = <unset>,          // Network controller          device = (vim.vm.device.VirtualPCNet32) {             dynamicType = <unset>,             // key number of Network controller             key = -48,             deviceInfo = (vim.Description) null,             backing = (vim.vm.device.VirtualEthernetCard.NetworkBackingInfo) {                dynamicType = <unset>,                deviceName = "Virtual Machine Network",                useAutoDetect = <unset>,                network = <unset>,                inPassthroughMode = <unset>,             },             connectable = (vim.vm.device.VirtualDevice.ConnectInfo) {                dynamicType = <unset>,                startConnected = true,                allowGuestControl = true,                connected = true,             },             controllerKey = <unset>,             unitNumber = <unset>,             addressType = "generated",             macAddress = <unset>,             wakeOnLanEnabled = true,          },       },       (vim.vm.device.VirtualDeviceSpec) {          dynamicType = <unset>,          operation = "add",          fileOperation = "create",          // SCSI disk one          device = (vim.vm.device.VirtualDisk) {             dynamicType = <unset>,             // key number for SCSI disk one             key = -1000000,             deviceInfo = (vim.Description) null,             backing = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) {                dynamicType = <unset>,                fileName = "",                datastore = <unset>,                diskMode = "persistent",                split = false,                writeThrough = false,                thinProvisioned = <unset>,                eagerlyScrub = <unset>,                uuid = <unset>,                contentId = <unset>,                changeId = <unset>,                parent = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) null,             },             connectable = (vim.vm.device.VirtualDevice.ConnectInfo) {                dynamicType = <unset>,                startConnected = true,                allowGuestControl = false,                connected = true,             },             // controller for SCSI disk one             controllerKey = -44,             unitNumber = 0,             // size in MB SCSI disk one             capacityInKB = 524288,             committedSpace = <unset>,             shares = (vim.SharesInfo) null,          },       },       (vim.vm.device.VirtualDeviceSpec) {          dynamicType = <unset>,          operation = "add",          fileOperation = "create",          // SCSI disk two          device = (vim.vm.device.VirtualDisk) {             dynamicType = <unset>, // key number of SCSI disk two             key = -100,             deviceInfo = (vim.Description) null,             backing = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) {                dynamicType = <unset>,                fileName = "",                datastore = <unset>,                diskMode = "persistent",                split = false,                writeThrough = false,                thinProvisioned = <unset>,                eagerlyScrub = <unset>,                uuid = <unset>,                contentId = <unset>,                changeId = <unset>,                parent = (vim.vm.device.VirtualDisk.FlatVer2BackingInfo) null,             },             connectable = (vim.vm.device.VirtualDevice.ConnectInfo) {                dynamicType = <unset>,                startConnected = true,                allowGuestControl = false,                connected = true,             },             // controller for SCSI disk two             controllerKey = -44,             unitNumber = 1,             // size in MB SCSI disk two             capacityInKB = 131072,             committedSpace = <unset>,             shares = (vim.SharesInfo) null,          },       }    },    cpuAllocation = (vim.ResourceAllocationInfo) {       dynamicType = <unset>,       reservation = 0,       expandableReservation = <unset>,       limit = <unset>,       shares = (vim.SharesInfo) {          dynamicType = <unset>,          shares = 100,          level = "normal",       },       overheadLimit = <unset>,    },    memoryAllocation = (vim.ResourceAllocationInfo) {       dynamicType = <unset>,       reservation = 0,       expandableReservation = <unset>,       limit = <unset>,       shares = (vim.SharesInfo) {          dynamicType = <unset>,          shares = 100,          level = "normal",       },       overheadLimit = <unset>,    },    cpuAffinity = (vim.vm.AffinityInfo) null,    memoryAffinity = (vim.vm.AffinityInfo) null,    networkShaper = (vim.vm.NetworkShaperInfo) null,    swapPlacement = <unset>,    swapDirectory = <unset>,    preserveSwapOnPowerOff = <unset>,    bootOptions = (vim.vm.BootOptions) null,    appliance = (vim.vService.ConfigSpec) null,    ftInfo = (vim.vm.FaultToleranceConfigInfo) null,    applianceConfigRemoved = <unset>,    vAssertsEnabled = <unset>,    changeTrackingEnabled = <unset>, } // end of VirtualMachineConfigSpec
The information above is quite complex, but much of the input consists of defaulted values that are assigned by the system. The remainder of the supplied information can be extracted from the output of the
config.hardware.device
table returned from
PropertyCollector
. Borrowing heavily from an SDK code example, the following code sets up the configuration specification:
// Duplicate virtual machine configuration VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec(); // Set the VM values configSpec.setName("My New VM"); configSpec.setVersion("vmx-04"); configSpec.setGuestId("winNetStandardGuest"); configSpec.setNumCPUs(1); configSpec.setMemoryMB(256); // Set up file storage info VirtualMachineFileInfo vmfi = new VirtualMachineFileInfo(); vmfi.setVmPathName("[plat004-local]"); configSpec.setFiles(vmfi); vmfi.setSnapshotDirectory("[plat004-local]"); // Set up tools config info ToolsConfigInfo tools = new ToolsConfigInfo(); configSpec.setTools(tools); tools.setAfterPowerOn(new Boolean(true)); tools.setAfterResume(new Boolean(true)); tools.setBeforeGuestStandby(new Boolean(true)); tools.setBeforeGuestShutdown(new Boolean(true)); tools.setBeforeGuestReboot(new Boolean(true)); // Set flags VirtualMachineFlagInfo flags = new VirtualMachineFlagInfo(); configSpec.setFlags(flags); flags.setSnapshotPowerOffBehavior("powerOff"); // Set power op info VirtualMachineDefaultPowerOpInfo powerInfo = new VirtualMachineDefaultPowerOpInfo(); configSpec.setPowerOpInfo(powerInfo); powerInfo.setPowerOffType("preset"); powerInfo.setSuspendType("preset"); powerInfo.setResetType("preset"); powerInfo.setStandbyAction("powerOnSuspend"); // Now add in the devices VirtualDeviceConfigSpec[] deviceConfigSpec = new VirtualDeviceConfigSpec [5]; configSpec.setDeviceChange(deviceConfigSpec); // Formulate the CDROM deviceConfigSpec[0].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualCdrom cdrom = new VirtualCdrom(); VirtualCdromIsoBackingInfo cdDeviceBacking = new VirtualCdromRemotePassthroughBackingInfo(); cdDeviceBacking.setDatastore(datastoreRef); cdrom.setBacking(cdDeviceBacking); cdrom.setKey(-42); cdrom.setControllerKey(new Integer(-200)); // Older Java required type for optional properties cdrom.setUnitNumber(new Integer(0)); deviceConfigSpec[0].setDevice(cdrom); // Formulate the SCSI controller deviceConfigSpec[1].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualLsiLogicController scsiCtrl = new VirtualLsiLogicController(); scsiCtrl.setBusNumber(0); deviceConfigSpec[1].setDevice(scsiCtrl); scsiCtrl.setKey(-44); scsiCtrl.setSharedBus(VirtualSCSISharing.noSharing); // Formulate SCSI disk one deviceConfigSpec[2].setFileOperation(VirtualDeviceConfigSpecFileOperation.create); deviceConfigSpec[2].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualDisk disk = new VirtualDisk(); VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo(); diskfileBacking.setDatastore(datastoreRef); diskfileBacking.setFileName(volumeName); diskfileBacking.setDiskMode("persistent"); diskfileBacking.setSplit(new Boolean(false)); diskfileBacking.setWriteThrough(new Boolean(false)); disk.setKey(-1000000); disk.setControllerKey(new Integer(-44)); disk.setUnitNumber(new Integer(0)); disk.setBacking(diskfileBacking); disk.setCapacityInKB(524288); deviceConfigSpec[2].setDevice(disk); // Formulate SCSI disk two deviceConfigSpec[3].setFileOperation(VirtualDeviceConfigSpecFileOperation.create); deviceConfigSpec[3].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualDisk disk2 = new VirtualDisk(); VirtualDiskFlatVer2BackingInfo diskfileBacking2 = new VirtualDiskFlatVer2BackingInfo(); diskfileBacking2.setDatastore(datastoreRef); diskfileBacking2.setFileName(volumeName); diskfileBacking2.setDiskMode("persistent"); diskfileBacking2.setSplit(new Boolean(false)); diskfileBacking2.setWriteThrough(new Boolean(false)); disk2.setKey(-100); disk2.setControllerKey(new Integer(-44)); disk2.setUnitNumber(new Integer(1)); disk2.setBacking(diskfileBacking2); disk2.setCapacityInKB(131072); deviceConfigSpec[3].setDevice(disk2); // Finally, formulate the NIC deviceConfigSpec[4].setOperation(VirtualDeviceConfigSpecOperation.add); com.VMware.vim.VirtualEthernetCard nic = new VirtualPCNet32(); VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo(); nicBacking.setNetwork(networkRef); nicBacking.setDeviceName(networkName); nic.setAddressType("generated"); nic.setBacking(nicBacking); nic.setKey(-48); deviceConfigSpec[4].setDevice(nic); // Now that it is all put together, create the virtual machine. // Note that folderMo, resourcePool, and hostMo, are moRefs to // the Folder, ResourcePool, and Host where the VM is to be created. ManagedObjectReference taskMoRef = serviceConnection.getService().createVM_Task(folderMo, configSpec, resourcePool, hostMo);