# setVmDynamicMemoryInVmm.ps1
# Optimize Dynamic RAM
$minGb='16GB'
$maxGb='32GB'
$startupGb='2GB'
$buffer=20
$memoryWeight=5000
$forcedRestart=$false
$vmmServer='localhost'
function getUnoptimizedMemoryVms{
param(
$minGb='16GB',
$maxGb='1024GB',
$vmmServer='localhost'
)
Import-Module -Name "virtualmachinemanager"
$vms=Get-VM -vmmserver $vmmServer
$targetVms=$vms|?{$($_.MemoryAssignedMB -ge $minGb/1MB -and $_.MemoryAssignedMB -le $maxGb/1MB) -and $($_.DynamicMemoryDemandMB -ne $_.MemoryAssignedMB)} # -and !$_.DynamicMemoryEnabled
# Memory = startup memory
# DynamicMemoryDemandMB = memory demand
# MemoryAssignedMB = memory currently assigned
# DynamicMemoryMaximumMB = Maximum Memory (non-zero value only if Dynamic Memory is enabled)
return $($targetVMs|select-object Name,Version,DynamicMemoryEnabled,DynamicMemoryDemandMB,MemoryAssignedMB|sort-object -Property Name)
}
function setVmDynamicMemoryInVmm{
param(
$vmName,
$setMinMb,
$setMaxMb,
$setStartupMb,
$forcedRestart=$false,
$buffer=20,
$memoryWeight=5000,
$vmmServer='localhost'
)
Import-Module -Name "virtualmachinemanager"
$vm=get-scvirtualmachine -name $vmName -vmmserver $vmmServer
$staticMemory=!$vm.DynamicMemoryEnabled # if Dynamic Memory is enabled and VM generation is 9.0 or higher, then Dynamic RAM can be configured while VM remains online
$maximumMB=if($setMaxMb -gt $vm.MemoryAssignedMB){$setMaxMb}elseif($vm.MemoryAssignedMB -gt $vm.DynamicMemoryDemandMB){$vm.MemoryAssignedMB}elseif($vm.DynamicMemoryDemandMB -gt $vm.Memory){$vm.DynamicMemoryDemandMB}else{4096}
$startupMb=if($startupMb){$startupMb}elseif($vm.DynamicMemoryDemandMB -lt $maximumMB/2){$vm.DynamicMemoryDemandMB}else{2048}
$minimumMB=if($setMinMb){$setMinMb}elseif($vm.DynamicMemoryDemandMB -lt $maximumMB/2){$vm.DynamicMemoryDemandMB}else{$startupMb}
if(!$vm -or $vm.count -gt 1){
write-warning "VM Name $vmName cannot be queried"
return $false
}
$vmHasFailed=$vm.Status -eq 'Failed'
if($vmHasFailed){
try{
# Manually repair virtual machine in a failed state
Repair-SCVirtualMachine $vm -Dismiss
}catch{
write-warning $_
return $false
}
}
$vmIsOnline=$vm.VirtualMachineState -eq 'Running'
if($vmIsOnline -and $forceRestart -and $staticMemory){
Stop-SCVirtualMachine -VM $vm
write-host "$vmName has been stopped temporarily"
}elseif($vmIsOnline -and !$forceRestart -and $staticMemory){
write-warning "VM Name $vmName status is 'Running' and the `$forceRestart flag has been set to `$false"
return $false
}elseif(!$staticMemory){
write-host "VM name $vmName memory config is detected as dynamic"
}
# Hyper-V Commands - will not work in VMM
# $startupBytes=$startupGb/1
# $minBytes=$minGb/1
# $maxBytes=$maxGb/1
# Set-VMMemory $vmName -DynamicMemoryEnabled $true -MinimumBytes $minBytes -StartupBytes $startupBytes -MaximumBytes $maxBytes -Priority $priority -Buffer $buffer
# VMM Command
try{
Set-SCVirtualMachine -VM $vm -DynamicMemoryEnabled $true `
-MemoryMB $startupMb -DynamicMemoryMinimumMB $minimumMB -DynamicMemoryMaximumMB $maximumMB `
-DynamicMemoryBufferPercentage $buffer -MemoryWeight $memoryWeight
if($vmIsOnline -and $forceRestart){
Start-SCVirtualMachine -VM $vm
if($vm.Status -eq 'Running'){
write-host "$vmName has started"
}else{
write-host "$vmName has NOT started successfully"
return $false
}
}
write-host "VM name $vmname memory has been set to dynamic with min of $minGb GB and $maxGb GB"
return $true
}catch{
write-warning $_
return $false
}
# Set Static RAM
# Set-VM -StaticMemory -Name $vmName -MemoryStartupBytes $($startupGb/1)
}
# setVmDynamicMemoryInVmm $vmName $setMinMb $setMaxMb $forceRestart $buffer $memoryWeight $vmmServer
function optimizeMemoryVms{
param(
$minGb='16GB',
$maxGb='64GB',
$startupGb='2GB',
$forcedRestart=$false,
$buffer=20,
$memoryWeight=5000,
$vmmServer='localhost'
)
$targetVMs=getUnoptimizedMemoryVms $minGb $maxGb $vmmServer
if($targetVMs.count){
$results=[hashtable]@{}
foreach($vm in $targetVMs){
$vmName=$vm.Name
$setMaxMb=if($vm.DynamicMemoryDemandMB -gt $vm.MemoryAssignedMB){$vm.DynamicMemoryDemandMB}else{$vm.MemoryAssignedMB}
$setStartupMb=if($startupGb){$startupGb/1MB}elseif($vm.DynamicMemoryDemandMB -lt $setMaxMb/2){$vm.DynamicMemoryDemandMB}else{2048}
$setMinMb=if($($vm.MemoryAssignedMB/2) -lt $setStartupMb){$vm.MemoryAssignedMB/2}else{$setStartupMb}
$result=setVmDynamicMemoryInVmm $vmName $setMinMb $setMaxMb $setStartupMb $forceRestart $buffer $memoryWeight $vmmServer
write-host "$vmName Memory config as been set to Dynamic with Min $setMinMb MB and Max $setMaxMb MB"
$results+=@{$vmName=$result}
}
return $results
}
}
optimizeMemoryVms $minGb $maxGb $startupGb $forcedRestart $buffer $memoryWeight $vmmServer
# Set-SCVirtualMachine -Name TESTWINDOWS -DynamicMemoryEnabled $true -DynamicMemoryMinimumMB $(8*1024)
# Set-VMMemory TESTWINDOWS -StartupBytes $(8GB/1)
# PS C:\Windows\system32> Set-VMMemory $vmName -StartupBytes $($startupGb/1)
# Set-VMMemory : Failed to modify device 'Memory'.
# 'TESTWINDOWS' failed to modify device 'Memory'. (Virtual machine ID
# 0A1E6930)
# Changing memory size of running virtual machine 'TESTWINDOWS' failed. VM version must be at least 6.0.
# At line:1 char:1
# + Set-VMMemory $vmName -StartupBytes $($startupGb/1)
# + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# + CategoryInfo : NotSpecified: (:) [Set-VMMemory], VirtualizationException
# + FullyQualifiedErrorId : OperationFailed,Microsoft.HyperV.PowerShell.Commands.SetVMMemory
# Install-WindowsFeature -Name Hyper-V-PowerShell
# Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell
Categories: