vCloud Automation Center – vCAC – Workflow and Script to Change CPU’s to Cores

During a POC something was brought to my attention that I haven’t heard anyone ask for before, but it seems like a very useful and valid need. The ask was to be able to set CPU Cores during provisioning rather than CPU’s. Operating Systems and other apps license by sockets, not cores so instead of having 8 CPU Sockets with 1 core, why not have 1 CPU Socket with 8 Cores. So I decided to build a solution that would solve this and change the CPU Sockets to Cores.

Now I prefer to do as much as I can in the design center and with the WorkFlow stubs because then they will work for everyone without the need for the CDK so taking that into consideration here is what I have built.

Background Info:

I am executing my script at the MachineProvisioned state of the virtual machines lifecycle. This can mean different things based on the provisioning type that is selected. If we are talking about cloning then it means that the clone has finished, vCAC hardware customization has taken place, Customization Specification has executed, any operation performed by the guest agent are complete and the VM for all intents is complete.Using the WFStubMachineProvisioned workflow however I can perform additional operations before the machine is handed off to the owner. In this case I’m using the workflow stub to execute a powershell script named SocketsToCores.

a little about vSphere vCPU’s:

In case you aren’t familiar with how vCPU assignment works in vCenter here is a brief run down. vSphere has three component to it looks at for vCPU’s:

  • Total CPU – This is the total Socket’s multiplied by the total cores
  • CPU Sockets – Total Number of CPU Sockets
  • CPU Cores – Total number of cores per socket

There are api calls for Total CPU and CPU Cores, but none for CPU sockets. As a result a few things happen. When you set CPU via total CPU it default to setting Sockets and total CPU’s to that number. So if I set 2 CPU’s it would create a total of CPU’s and assign them to sockets. Initially I thought after the machine was provisioned I would set CPU’s to 1 and Cores to 2, however this results in an invalid configuration. When I set CPU’s to 1 it changes the total CPU’s to 1 and then when I set cores to 2 and try and edit or power on the VM it throws and error because the total CPU’s is 1.

However is I set the total CPU’s to 2, I get 2 CPU sockets and if I then set the cores to 2 vSphere takes care of the issue by setting cores to 1 making everything the way it should be. If I provisioned 16 CPU’s and set the cores to 8 it will give me 2 Sockets with 8 cores each. Only time this becomes an issue is if an odd number of CPU’s is set. If 7 CPU’s were set and then you were to try and set 3 cores per cpu it would result in would result in an invalid configuration leaving CPU Sockets at 7 and adding 3 Cores to Each Socket making it have 21 CPU’s while the configured total was still 7. However if I set 6 Socket and then set 3 cores per Socket I would get 2 Sockets each with 3 cores and all would be good.

The code to change the Sockets to Cores using the PowerCLI is:

$spec=New-Object –Type VMware.Vim.VirtualMachineConfigSpec –Property @{“NumCoresPerSocket” = $numCores}
(Get-VM –Name $vm).ExtensionData.ReconfigVM_Task($spec)

What my script does:
The script does a few things.

  1. The very first thing it does is check to see if it should expect a Guest OS in the VM and if it should it makes sure the VMware Tools are running, it does this because we can’t shut the Guest down safely unless they are. If the tools aren’t running it will wait until they are for a total of 5 minutes before it times out (You can change this in the script). Once the tools are running it shuts down the virtual machine. If it doesn’t expect a Guest OS it checks to see if the VM is powered On, and if it is, it powers it off. If the VM is already off it proceeds on.
  2. Next it’s going to change the CPU cores of the Virtual Machine using the snippet of code above and then validate that the change was successful. This will by default change to 1 CPU Socket and put the total number of CPU’s as cores.
  3. Once the Sockets have been changed to cores it will then look to see if it should expect a Guest OS in the VM. If ti does it will power on the virtual machine and check to make sure the VMware tools start. Otherwise if it doesn’t expect a guest OS it will leave the VM off.

    You can grab the Script and the workflow from the downloads page under Sockets to Cores. If you just want to use it, it comes with an install script or you can manually install the script to an existing workflow if you like. Note: If you have made changes to your WFStubMachineProvisioned workflow stub you should manually install the script and update your workflow.

  4. Custom Properties
    The script uses a few custom properties that need to be defined. They are outlined below:

    • VMware.vCenterServer.Address – This is so the PowerCLI can connect to vCenter, I define this at the endpoint. Simple put the FQDN of the vCenter server as the value, no need to http/s or /SDK.
    • GuestOSInstalled – This should be defined in the blueprint to let the script know if it should expect a guest OS or not. Values are True or False.
    • ExternalWFStubs.MachineProvisioned – This tells vCAC to launch the WFStub.Machine Provisioned workflow.

    For information on using the workflow Designer check out this post.


  1. Yoni Shperling says:


    Be aware there is performance impact working with core over socket.

    Great article.

    • There should be NO performance impact allocating socket vs core. ESXi should allocate CPU cycles based on vCPU regardless if that CPU is designated as socket or core.


  1. […] machine to a vCenter and then want to change the socket/core ratio of that machine as described in vCloud Automation Center – vCAC – Workflow and Script to Change CPU’s to Cores. For this to actually work you not only need the vCenter address but also some valid credentials […]

Leave a comment

%d bloggers like this: