VMware

« You can manage VMware Server with PowerShell too. | Main | More Fun With PowerShell Mashups »

April 25, 2008

Changing CPU and Memory Allocations For All VMs

We here at VMware often get requests by people who are trying to tweak the default resource allocations that VMs have. This post shows you how easy it is to automate configuring and changing resource allocations is when using PowerShell.

First, a bit of background information. Each VM has a certain level of CPU and memory shares. In addition these levels may be limited or unlimited. Even further, a VM can have CPU or memory reservations, which means the VM will always have at least this minimal level of resources available to it. When shares are unlimited, a VM may receive more resources than its share allocation, provided these resources are not being used by some other VM.

By default, a VM gets normal CPU and memory shares with no reservation and no limit. This is a sensible default, but many times you want to tune this to improve performance for some applications.

This first example shows you how to set all VMs in your entire Virtual Infrastructure to high CPU shares and no limit.

Get-VM | % {Get-View $_.ID} | 
    % {$spec = new-object VMware.Vim.VirtualMachineConfigSpec;
        $spec.cpuAllocation = New-Object VMware.Vim.ResourceAllocationInfo;
        $spec.cpuAllocation.Shares = New-Object VMware.Vim.SharesInfo;
        $spec.cpuAllocation.Shares.Level = "high";
        $spec.cpuAllocation.Limit = -1;
        Get-View($_.ReconfigVM_Task($spec))}

This script works whether you have 1 VM or 1,000 VMs. The next example shows how to set a VM's memory allocation to normal, with no limit, and ensure that each VM has at least 1 GB of memory.

Get-VM | % {Get-View $_.ID} |
    % {$spec = new-object VMware.Vim.VirtualMachineConfigSpec;
        $spec.memoryAllocation = New-Object VMware.Vim.ResourceAllocationInfo;
        $spec.memoryAllocation.Shares = New-Object VMware.Vim.SharesInfo;
        $spec.memoryAllocation.Shares.Level = "normal";
        $spec.memoryAllocation.Limit = -1;
        $spec.memoryAllocation.Reservation = 1024;
        Get-View($_.ReconfigVM_Task($spec))}

Chances are these are not quite the policies you're looking for, but you easily determine what values you want by referring to the VMware API Reference Guide.

This is extremely powerful, but it's even more so when you consider that you can combine it with cmdlets like

Get-ResourcePool

and

Get-Folder

to select exactly the VMs you want to modify. For example, using

Get-ResourcePool

you could very easily set all VMs in one resource pool to have CPU resources set to high and all VMs in another resource pool to have CPU resources set to low.

This is just one of the great things you can do when you manage VMware with PowerShell, so if you haven't looked at it yet you should definately download the VI Toolkit (for Windows) Beta.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/t/trackback/1051344/28500954

Listed below are links to weblogs that reference Changing CPU and Memory Allocations For All VMs:

Comments

You said: "you could very easily set all VMs in one resource pool to have CPU resources set to high and all VMs in another resource pool to have CPU resources set to low". This is useless, setting shares low or high for all VMs in the same RP won't have any effect at all, as the all. RP they have their own shares, so setting all VMs with the same sub-sharing is pointless.

True, that's certainly not the most useful thing you can do with these samples. The only time this would be useful is if you wanted to ensure that all VMs in a pool have equal access to resources by reconfiguring them to have the same value (for example if you have different shares values for each VM in the pool.) But, as you point out, it wouldn't matter if their shares were set to High, Low or anything else for that matter.

Great post...I am trying to use the same idea to add some CPU masking bits, but have run into a wall...can you offer some insight?

Doug,

You should consider this post in the forum: http://communities.vmware.com/message/962775#962775

It's a starting point anyway.

Sorry, slightly wrong link, use this one instead: http://communities.vmware.com/message/960626#960626

Hi there

I've been struggling with this for a couple of days now; I can execute the scripts no problem, however no updates are seen on my objects. I think I must be missing something very simple here but can't see it.

I simply want to update the reservation for Memory and CPU based on the requirments from a front-end interface. I can pass all the values to the script - but then nothing:

run the script (as above)

I get:

Info : VMware.Vim.TaskInfo
Value :
AvailableField :
MoRef : VMware.Vim.ManagedObjectReference
Client : VMware.Vim.VimClient

If anyone can offer any assistance that would be great.

When you run it do you see jobs created if you're logged in using VI Client? If you need some more help, try the forum at http://communities.vmware.com/community/developer/windows_toolkit

Post a comment

If you have a TypeKey or TypePad account, please Sign In