Hello,
We have many VMs with over provisioned CPUs, need to remove 1 CPU from them.
Appreciate any help.
Thank you in advance!
Is there a list of VMs, in a text file?
Are these VMs powered off?
Or does the script need to take care of that?
And do all the VMs have the VMware Tools installed and running?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This is for a specific VM.
The script checks the powerstate, and brings the VM back to that state when the CPU number is lowered by 1.
Also I builtin a safety for VMs that only have 1 vcpu
$vmName = 'MyVM'
foreach($vm in Get-VM -Name $vmName){
if($vm.NumCpu -ne 1){
$wasPoweredOn = $false
if($vm.PowerState -ne 'PoweredOff'){
$wasPoweredOn = $true
Shutdown-VMGuest -VM $vm
while($vm.PowerState -ne 'PoweredOff'){
sleep 5
$vm = Get-VM -Name $vm.Name
}
}
$vm = Set-VM -VM $vm -NumCpu ($vm.NumCpu - 1) -Confirm:$false
if($wasPoweredOn){
Start-VM -VM $vm -Confirm:$false
}
}
else{
Write-Output "VM $vm.Name only has 1 vcpu"
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, there will be a list of VMs in a text file.
These VMs are powered on with VMware tools installed
That is a slight modification of the previous script
$vmnames = '.\vmnames.txt'
foreach($vm in Get-VM -Name (Get-Content -Path $vmnames)){
if($vm.NumCpu -ne 1){
$wasPoweredOn = $false
if($vm.PowerState -ne 'PoweredOff'){
$wasPoweredOn = $true
Shutdown-VMGuest -VM $vm
while($vm.PowerState -ne 'PoweredOff'){
sleep 5
$vm = Get-VM -Name $vm.Name
}
}
$vm = Set-VM -VM $vm -NumCpu ($vm.NumCpu - 1) -Confirm:$false
if($wasPoweredOn){
Start-VM -VM $vm -Confirm:$false
}
}
else{
Write-Output "VM $vm.Name only has 1 vcpu"
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you!
I will test and let you know.
These VMs are Windows 7 and support maximum 2 CPUs but any number of cores.
So to configure 3 CPUs VM has 1 CPU and 3 cores for example. So to decrease a number of CPUs we need to decrease a number of cores.
Would be possible to modify the script?
If you 1 CPU block with 3 cores and you change NumCPU to 2, you will end up with 1 CPU block with 2 cores.
Or do you mean something else?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Current configuration for example 1 CPU and 3 cores. Need to change to 1 CPU and 2 cores instead
Ok, got you.
Try like this, but note that this solution has a flaw if you have more than 1 CPU block.
Assume you have configured 2 CPU blocks, each with 3 cores. That gives 6 for NumCPU.
Lowering that to 5 will not work, you can only lower to 4, and change the CoresPerBlock from 3 to 2.
foreach($vm in Get-VM -Name $vmName){
if($vm.NumCpu -ne 1){
$wasPoweredOn = $false
if($vm.PowerState -ne 'PoweredOff'){
$wasPoweredOn = $true
Shutdown-VMGuest -VM $vm
while($vm.PowerState -ne 'PoweredOff'){
sleep 5
$vm = Get-VM -Name $vm.Name
}
}
if($vm.CoresPerSocket -gt 1){
$vm = Set-VM -VM $vm -NumCpu ($vm.NumCpu - 1) -CoresPerSocket ($vm.CoresPersocket - 1) -Confirm:$false
}
else{
$vm = Set-VM -VM $vm -NumCpu ($vm.NumCpu - 1) -Confirm:$false
}
if($wasPoweredOn){
Start-VM -VM $vm -Confirm:$false
}
}
else{
Write-Output "VM $vm.Name only has 1 vcpu"
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This is what happened - please attached screen shot
Changed Total number of cores to 2 but still report Number of cores per socket as 3
Did you start the VM?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes
That seems ot be an issue with the Set-VM cmdlet, because it actually says total number of cores is 2.
While the cores per socket keeps saying 3.
Perhaps we should try the ReconfigVM method?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Not familiar with this
Try this way.
foreach($vm in Get-VM -Name $vmName){
if($vm.NumCpu -ne 1){
$wasPoweredOn = $false
if($vm.PowerState -ne 'PoweredOff'){
$wasPoweredOn = $true
Shutdown-VMGuest -VM $vm
while($vm.PowerState -ne 'PoweredOff'){
sleep 5
$vm = Get-VM -Name $vm.Name
}
}
if($vm.CoresPerSocket -gt 1){
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.NumCoresPerSocket = $vm.CoresPersocket - 1
$spec.NumCPUs = $vm.NumCpu - 1
$vm.ExtensionData.ReconfigVM($spec)
}
else{
$vm = Set-VM -VM $vm -NumCpu ($vm.NumCpu - 1) -Confirm:$false
}
if($wasPoweredOn){
Start-VM -VM $vm -Confirm:$false
}
}
else{
Write-Output "VM $vm.Name only has 1 vcpu"
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Unfortunately same result
Works for me.
No clue why it doesn't work for you.
Which vSphere version are you using?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It looks as if the CoresPerSocket behaviour has been changed in vSphere 6.5.
I tested my script in vSphere 6.7.
If you're on vSphere 6, or older, that might explain our different results.
Frank's post Decoupling of Cores per Socket from Virtual NUMA Topology in vSphere 6.5
gives some more details on this.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference