Enable Hot Add vCPU and Memory on VMs using PowerShell (V2)

This is a script which will allow you to enable the Hot Add vCPU and Memory feature on all or a sub set of your VMs.

IMPORTANT NOTE – the script will recursively power off each VM defined in CSV (unless Hot Add is already enabled), apply the config then power each VM back on. So make sure you run this script in an outage window.

When creating the CSV, make sure to include the header row – Name.

The script will also generate a log file.

#############################################################################
#       Author: Cengiz Ulusahin
#       Version: 3.0
#       Date: 04/08/2020
#       Description: Enable HotAdd CPU and Memory on VMs
#
#############################################################################

#Function to generate wait time progress bar
function Start-Sleep($seconds) {
    $doneDT = (Get-Date).AddSeconds($seconds)
    while($doneDT -gt (Get-Date)) {
        $secondsLeft = $doneDT.Subtract((Get-Date)).TotalSeconds
        $percent = ($seconds - $secondsLeft) / $seconds * 100
        Write-Progress -Activity "Sleeping" -Status "Sleeping..." -SecondsRemaining $secondsLeft -PercentComplete $percent
        [System.Threading.Thread]::Sleep(500)
    }
    Write-Progress -Activity "Sleeping" -Status "Sleeping..." -SecondsRemaining 0 -Completed
}

#Function for Logging
Function Write-Log
{
Param ([string]$logstring)
$stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
$line = "$stamp $logstring"
Add-content $logfile -value $line
}

#Function for Enabling Hot Add
function EnableHotAdd{
$VMConfig = Get-VM $VM.Name | Get-View
$VMConfig.ReconfigVM($vmConfigSpec)

        $HotAddStatus = Get-VM $VM.Name
        $HotAddCPUStatus = [System.Convert]::ToBoolean($($HotAddStatus.ExtensionData.Config.CpuHotAddEnabled))
        $HotAddMEMStatus = [System.Convert]::ToBoolean($($HotAddStatus.ExtensionData.Config.MemoryHotAddEnabled))
                
                If ($HotAddCPUStatus -eq $True -OR $HotAddMEMStatus -eq $True) {

                    write-log("[SUCCESS] HotAdd for $($VM.Name) was enabled")

                }else{

                    write-log("[FAIL] HotAdd for $($VM.Name) was not enabled")
                } 
}

#Function for Powering off VM
function PowerOffVM{
         #Shutdown Guest OS / Power off VM
         Get-VM $VM.Name | Shutdown-VMGuest -Confirm:$false

         #Wait for VM to power off before executing config cmd  
         while((Get-VM $VM.Name).PowerState -ne 'PoweredOff') {
         
         Start-Sleep -Seconds 10
         }
                 $HotAddStatus = Get-VM $VM.Name
                 $HotAddCPUStatus = [System.Convert]::ToBoolean($($HotAddStatus.ExtensionData.Config.CpuHotAddEnabled))
                 $HotAddMEMStatus = [System.Convert]::ToBoolean($($HotAddStatus.ExtensionData.Config.MemoryHotAddEnabled))

                         If ((Get-VM $VM.Name).PowerState -eq 'PoweredOff') {

                             write-log("[SUCCESS] $($VM.Name) was powered off")

                         }else{

                             write-log("[FAIL] $($VM.Name) was not powered off")
                         }
}

#Function for Powering on VM
function PowerOnVM{
Get-VM $VM.Name | Start-VM

                If ((Get-VM $VM.Name).PowerState -eq 'PoweredOn') {

                    write-log("[SUCCESS] $($VM.Name) was powered on")

                }else{

                    write-log("[FAIL] $($VM.Name) was not powered on")
                }
}

#Variables
$vcenter = Read-Host -Prompt 'Enter vCenter name'
$cred = Get-Credential
$CSVPath = Read-Host -Prompt 'Enter CSV Path'
$HotAddVMs = Import-CSV $CSVPath\vms.csv
$logfile = New-Item $CSVPath\hotadd-script-log.txt -Force
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmConfigSpec.CpuHotAddEnabled = "True"
$vmConfigSpec.MemoryHotAddEnabled = "True"

Connect-VIServer $vcenter -Credential $cred

        Foreach ($VM in ($HotAddVMs)) {

            $VMTools = Get-VM $VM.Name
            $VMToolsStatus = $VMTools.ExtensionData.Guest.ToolsVersionStatus

            if ($VMToolsStatus -eq 'guestToolsNotInstalled') {

                write-log("[PASS] $($VM.Name) has no VMTools installed")

            }else{    

                $HotAddStatus = Get-VM $VM.Name
                $HotAddCPUStatus = [System.Convert]::ToBoolean($($HotAddStatus.ExtensionData.Config.CpuHotAddEnabled))
                $HotAddMEMStatus = [System.Convert]::ToBoolean($($HotAddStatus.ExtensionData.Config.MemoryHotAddEnabled))

                If ($HotAddCPUStatus -eq $False -OR $HotAddMEMStatus -eq $False) {

                            If ((Get-VM $VM.Name).PowerState -eq 'PoweredOff') {

                                write-log("[PASS] $($VM.Name) was already powered off")

                                EnableHotAdd

                                write-log("[PASS] $($VM.Name) has been left powered off")

                            }else{

                                PowerOffVM
                                EnableHotAdd
                                PowerOnVM
                            }
                    }else{

                        write-log("[PASS] HotAdd for $($VM.Name) was already enabled")
                }
            }
        }

One thought on “Enable Hot Add vCPU and Memory on VMs using PowerShell (V2)

  1. Pingback: Enable Hot Add vCPU and Memory on VMs using PowerShell - myitblog

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.