VMware Cloud Community
dukeamo
Contributor
Contributor
Jump to solution

How can I set the memory reservation on all VMs to "0"?

I'm trying to write a script that will set the memory reservation on  all of the guest VMs in a cluster to "0".  We were reserving too much memory, and this setting should allow the VMWare facilities to manage  the memory reservations for me.  I have hundreds of VMs to update, so I can't do it by hand.  I'm hoping it can be done with the CLI.

Can someone help me do this please?

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
allencrawford
Enthusiast
Enthusiast
Jump to solution

Matt's example will certainly work, and I'm sure he was going to follow up with something similar to this after you confirmed if it worked or not since he's way more serious about code optimization for speed, but I'll (try to) save him the effort. In testing his snippet on a cluster of 45 VMs, it took over four minutes to complete.  The snippet below took about 25 seconds.  The difference of course is from using the "Get-View" cmdlet and that it can run asynchronously as well (it kicks off a vCenter task and immediately moves on to the next one).  Of course, this will also put more of a strain in your vCenter server, so keep that in mind.

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.memoryAllocation = New-Object VMware.Vim.ResourceAllocationInfo
$spec.memoryAllocation.Reservation = 0
Get-Cluster "YOUR_CLUSTER" | Get-VM | Get-View -Property Config.MemoryAllocation | %{$_.ReconfigVM_Task($spec)}

View solution in original post

0 Kudos
7 Replies
mattboren
Expert
Expert
Jump to solution

Hello, dukeamo-

Welcome to the forums.  Similar to what LucD did in this thread, you should be able to do that easily with the Set-VMResourceConfiguration cmdlet.  For this instance, though, it would be using the -MemReservationMB parameter.  Something like:

## set the MemReservationMB to 0 for given VMs
Get-Cluster "myCluster" | Get-VM | Get-VMResourceConfiguration | Set-VMResourceConfiguration -MemReservationMB 0 -Confirm:$false

Then, to verify, you can get the new resource config, like:

## retrieve the values for MemReservationMB for the given VMs
Get-Cluster "myCluster" | Get-VM | Get-VMResourceConfiguration | select VM,MemReservationMB

That do it for you?

allencrawford
Enthusiast
Enthusiast
Jump to solution

Matt's example will certainly work, and I'm sure he was going to follow up with something similar to this after you confirmed if it worked or not since he's way more serious about code optimization for speed, but I'll (try to) save him the effort. In testing his snippet on a cluster of 45 VMs, it took over four minutes to complete.  The snippet below took about 25 seconds.  The difference of course is from using the "Get-View" cmdlet and that it can run asynchronously as well (it kicks off a vCenter task and immediately moves on to the next one).  Of course, this will also put more of a strain in your vCenter server, so keep that in mind.

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.memoryAllocation = New-Object VMware.Vim.ResourceAllocationInfo
$spec.memoryAllocation.Reservation = 0
Get-Cluster "YOUR_CLUSTER" | Get-VM | Get-View -Property Config.MemoryAllocation | %{$_.ReconfigVM_Task($spec)}

0 Kudos
dukeamo
Contributor
Contributor
Jump to solution

This mostly worked, except for one problem.  It works for some VMs but not others.  Why can't I change the memory reservation for disconnected VMs?

PowerCLI C:\Program Files\VMware\Infrastructure\vSphere PowerCLI> Get-Cluster "Cluster1" | Get-VM F5* | Get-VMResourceConfiguration | Set-VMResourcConfiguration -MemReservationMB 2048 -Confirm:$false

Set-VMResourceConfiguration : 9/14/2011 11:24:05 PM    Set-VMResourceConfiguration        The operation for the entity VirtualMachine-vm-131 failed with the following message: "Unable to communicate with the remote host, since it is disc
onnected."
At line:1 char:108
+ Get-Cluster "ManagementCluster" | Get-VM F5CSP* | Get-VMResourceConfiguration
| Set-VMResourceConfiguration <<<<  -MemReservationMB 2048 -Confirm:$false
    + CategoryInfo          : NotSpecified: (:) [Set-VMResourceConfiguration],
    HostNotConnected
    + FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpda
   tes_OperationFailed,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetVMReso
  urceConfiguration

0 Kudos
dukeamo
Contributor
Contributor
Jump to solution

Allen,

You said the "faster" script could put a strain on the vCenter server.  Would running the "faster" script decrease performance of the VMs in the cluster while it's processing, or would it just affect the performance of the vSphere clients?

We're trying to update a couple thousand VMs across several clusters.  The "slow" script takes about 7 seconds per VM on my test setup.  I think it would be OK to let the scripts run for a couple of hours, if that means it won't interfere with the VM performance as much.

One other question - will we need to restart the VMs or anything like that to get their current memory reservations to change?  Or will it happen on the running VMs automatically?  (The goal here being to get the setup back to a state where the VMWare HA memory reservations are working correctly.)

Thank you both very much.  I'm still really new to this!

0 Kudos
allencrawford
Enthusiast
Enthusiast
Jump to solution

My script should not affect the VM performance, just that of the vCenter server itself.  And I should say that I've done it on a very large vCenter instance with no issues, so it really isn't much to worry about in my opinion.

It will work immediately as far as I understand it on powered on VMs.  One thing to note, however.  If you didn't already know the VM swap file size is based on assigned memory minus memory reservation (also assuming no limits in this case).  So if you have a VM with 8GB of memory but a 4GB reservation, then when you power it on, it'll create a 4GB VM swap file on the datastore.  If you have that same 8GB VM with no reservation and power it on, it would create an 8GB VM swap file.  However, if you use this script to change the existing reservations on powered on VMs, that VM swap file size will not change on the fly.  So in the first example (8GB VM, 4GB reservation) that 4GB VM swap file will remain at 4GB.  If for some reason you were so oversubscribed on memory, you could in theory use up the 4GB swap file and be struggling for good performance.  But, if you are that oversubscribed, you've likely got other issues to worry about anyway.  The same goes for the reverse--if you were using the script to set new reservations on running VMs, that VM swap file isn't going to change in size until the next VM power cycle.

Hope this helps.  And if it does, can I have some points?  I need to catch up with Matt.  🙂

Speaking of, you can further optimize that script with the -SearchRoot parameter on the "Get-View" cmdlet.  If you are interested, one of us can give you an example if you can't figure it out on your own.

mattboren
Expert
Expert
Jump to solution

Hello, dukeamo-

As for things not working on VMs in Disconnected state -- not much of anything (nothing) will working on those, as vCenter cannot communicate with the host on which they reside, as (per the error message), the VMHost itself is Disconnected in vCenter.  Get the host(s) back to a Connected state, and things should work fine.

About the code optimized for speed, Allen is definitely correct -- and his technique does great to reduce the amount of time it takes to complete the process.  As he also mentioned, the code could be optimized a bit more by using the -SearchRoot parameter on Get-View, which allows us to remove the Get-Cluster and Get-VM cmdlets.  So, something like:

## cluster whose VMs to config
$strClusterName = "myCluster"
## create a new VirtualMachineConfigSpec object
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec -Property @{
    memoryAllocation
= New-Object VMware.Vim.ResourceAllocationInfo -Property @{
        Reservation
= 0
    }
## end new ResourceAllocationInfo
} ## end new VirtualMachineConfigSpec
#
# get the .NET View objects for the VMs in the given cluster, and reconfigure them with the new spec
Get-View -ViewType VirtualMachine -Property Name -SearchRoot (Get-View -ViewType ClusterComputeResource -Property Name -Filter @{"Name" = $strClusterName}).MoRef | %{$_.ReconfigVM_Task($spec)}

This also consolidates a couple of the New-Object lines a bit, and gets just the Name property in the Get-View call.

The speeds:  the code that still needed a bit of tweaking took about 25 seconds.  The example here took about 15 seconds.  Not as drastic of a drop as his original improvement, but, it can still add up in larger environments.

0 Kudos
dukeamo
Contributor
Contributor
Jump to solution

Thank you both very much.  The very simple one-liner scripts definitely work, as long as the VMs are connected.  I'll try the faster versions next.

BTW, we'll be changing our recommendation to be that people always set the memory reservation to 0, unless there's a specific reason to do otherwise (I know there are a few cases where it helps to reserve some memory on startup.)  Especially for HA servers.

0 Kudos