Scripting dynamic memory, part 5: changing minimum memory

If you looked closely at the sample script I provided yesterday, you will have noticed that there are actually 3 memory settings for dynamic memory.  VirtualQuantity (which is called “Startup RAM” in the user interface), Limit (which is called “Maximum RAM” in the user interface) and finally Reservation – which is not shown anywhere.

The memory reservation setting is the equivalent of “Minimum RAM”.

Whenever you configure dynamic memory through the user interface we always set the value for minimum RAM to the same as the startup RAM.  The reason why we do this is because while you might be able to get better memory utilization by having a lower minimum memory setting – it can cause problems when starting and restarting the virtual machine.

Imaging the following scenario:

A virtual machine is configured with a minimum RAM value of 128MB, a startup RAM value of 512MB and a maximum RAM value of 2048MB.  The virtual machine is started and after a while other virtual machines start as well.  The original virtual machine is relatively idle and is now only using 256MB of RAM.  For some reason the virtual machine is restarted (e.g. a configuration change to the guest operating system).  However, Hyper-V is not able to get the 512MB RAM needed to satisfy the startup RAM setting – so instead of restarting the virtual machine just turns off.

Hopefully you can see the problem with this.

All that said – while we do not allow you to configure minimum memory through the user interface – you can configure it through WMI.  Here is a modified version of my script from yesterday that allows you to do just that:

 # Function for handling WMI jobs / return values
 Function ProcessResult($result, $successString, $failureString)
 {
    #Return success if the return value is "0"
    if ($result.ReturnValue -eq 0)
       {write-host $successString} 
  
    #If the return value is not "0" or "4096" then the operation failed
    ElseIf ($result.ReturnValue -ne 4096)
       {write-host $failureString "  Error value:" $result.ReturnValue}
  
    Else
       {#Get the job object
       $job=[WMI]$result.job
  
       #Provide updates if the jobstate is "3" (starting) or "4" (running)
       while ($job.JobState -eq 3 -or $job.JobState -eq 4)
          {write-host $job.PercentComplete "% complete"
           start-sleep 1
  
           #Refresh the job object
           $job=[WMI]$result.job}
  
        #A jobstate of "7" means success
        if ($job.JobState -eq 7)
           {write-host $successString}
        Else
           {write-host $failureString
           write-host "ErrorCode:" $job.ErrorCode
           write-host "ErrorDescription" $job.ErrorDescription}
        }
 }
  
 # Prompt for the Hyper-V Server to use
 $HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
  
 # Prompt for the virtual machine to use
 $VMName = Read-Host "Specify the name of the virtual machine"
  
 # Get the management service
 $VMMS = gwmi -namespace root\virtualization Msvm_VirtualSystemManagementService -computername $HyperVServer
  
 # Get the virtual machine object
 $VM = gwmi MSVM_ComputerSystem -filter "ElementName='$VMName'" -namespace "root\virtualization" -computername $HyperVServer
  
 # SettingType = 3 ensures that we do not get snapshots
 $SystemSettingData = $VM.getRelated("Msvm_VirtualSystemSettingData") | where {$_.SettingType -eq 3}
  
 # Get the memory setting data
 $MemSetting = $SystemSettingData.getRelated("Msvm_MemorySettingData") | select -first 1
  
 # Setup parameters for the prompt
 $message = "Do you want to enable dynamic memory?"
 $enable = New-Object System.Management.Automation.Host.ChoiceDescription "&Enable", "Enable dynamic memory on this virtual machine."
 $disable = New-Object System.Management.Automation.Host.ChoiceDescription "&Disable", "Disable dynamic memory on this virtual machine."
 $options = [System.Management.Automation.Host.ChoiceDescription[]]($enable, $disable)
  
 # Prompt for a response
 $promptResult = $host.ui.PromptForChoice("", $message, $options, 0)
 write-host 
  
 switch ($promptResult)
    {
       0 {# Enable dynamic memory
       
          # Prompt for the memory settings
          $VirtualQuantity = Read-Host "Specify the startup memory for the virtual machine (MB)"
          $Reservation = Read-Host "Specify the minimum memory for the virtual machine (MB)"
          $Limit = Read-Host "Specify the maximum memory for the virtual machine (MB)"
          $TargetMemoryBuffer = Read-Host "Specify the memory buffer for the virtual machine (5- 95)"
          $Weight = Read-Host "Specify the memory weight for the virtual machine (1 - 10000)"
       
          # Update the memory data setting object
          $MemSetting.DynamicMemoryEnabled = 1
          $MemSetting.Reservation = $Reservation
          $MemSetting.VirtualQuantity = $VirtualQuantity
          $MemSetting.Limit = $Limit
          $MemSetting.TargetMemoryBuffer = $TargetMemoryBuffer
          $MemSetting.Weight = $Weight        
         }
      
       1 {# Disable dynamic memory
       
          # Prompt for the memory settings
          $VirtualQuantity = Read-Host "Specify the amount of memory for the virtual machine (MB)"
          $Weight = Read-Host "Specify the memory weight for the virtual machine (1 - 10000)"
       
          # Update the memory data setting object
          $MemSetting.DynamicMemoryEnabled = 0
          $MemSetting.Reservation = $VirtualQuantity
          $MemSetting.VirtualQuantity = $VirtualQuantity
          $MemSetting.Limit = $VirtualQuantity
          $MemSetting.Weight = $Weight
         }
            
    }
  
 # Apply the changes to the memory setting data back to the virtual machine
 $result = $VMMS.ModifyVirtualSystemResources($VM, $MemSetting.GetText(1))
  
 # Process the result
 ProcessResult $result "Memory settings have been updated." "Failed to update memory settings."

Note that once you have configured a virtual machine with a lower minimum memory value – you will see the following warning in the memory settings user interface:

DMMinimum

Cheers,

Ben

ConfigureDM2.zip