New 🔧 DevOps CI/CD VMware

Automate VMware CPU & Memory Resize
with Jenkins Parameterised Build

✍️ Ravindrakumar Narayanan 📅 21 May 2026 ⏱️ 12 min read 🏷️ PowerShell · PowerCLI · Jenkins · vSphere

📋 Overview

Manually resizing VMs in VMware vSphere is a common but time-consuming operational task — especially when it involves coordinating across multiple datacentres, shutting down VMs safely, verifying changes, and notifying teams. One mistake can mean downtime or an incorrectly sized machine nobody notices for weeks.

This guide walks through a production-ready PowerShell + PowerCLI solution integrated with Jenkins Parameterised Build, giving your infrastructure team a simple, auditable, self-service interface to resize VMs in both the PROD and DR vCenter environments — with zero need to touch a script or a vCenter console directly.

Script Language
PowerShell + PowerCLI
CI/CD Tool
Jenkins (Parameterised)
Environments
PROD vCenter · DR vCenter
Actions Supported
CPU · Memory · Both

🚀 Why Jenkins Parameterised Build?

Jenkins Parameterised Builds turn any script into a governed, self-service interface. Engineers fill in a simple form and Jenkins handles the rest — no SSH sessions, no shared credentials in chat, no ad-hoc PowerShell runs.

🔐
Centralised Credential Management
Secrets stored in Jenkins Credentials store — never exposed in chat or emails.
📋
Full Audit Trail
Every build logged with who ran it, when, which VM, and what changed.
🔄
Repeatable & Consistent
Same script, same flow every time — no human variation or copy-paste errors.
🧑‍💻
Self-Service for Engineers
Engineers trigger via Jenkins UI — no vCenter or PowerShell knowledge needed.
📧
Automatic Alerting
Email notifications on success and failure without manual intervention.
🛡️
Validation Gates
Post-change verification confirms the resource was actually applied before the VM is powered on.

✅ Prerequisites

⚙️ Jenkins Job Setup — Step by Step

1. Create a New Freestyle Job

Go to Jenkins Dashboard → New Item. Name it VMware-CPU-Memory-Resize, select Freestyle Project, then click OK.

2. Enable "This project is parameterised"

Tick This project is parameterised under the General section. Add the following parameters:

Parameter Name Type Description Required
PROD_Vcenter_Name String PROD vCenter FQDN (e.g. prod-vcenter...) Required
DR_Vcenter_Name String DR vCenter FQDN (e.g. dr-vcenter...) Required
Username Credentials vCenter service account (via Jenkins Credentials) Required
Password Password vCenter service account password (masked) Required
VM_Name String Exact VM name to resize Required
CPU Choice Set to yes to resize CPU, no to skip Boolean
Memory Choice Set to yes to resize Memory, no to skip Boolean
CPU_Increase String Number of vCPUs to set (e.g. 4) Conditional
Memory_Increase String Memory in GB to set (e.g. 16) Conditional
💡
Tip: Use Choice Parameters for CPU and Memory flags In Jenkins, use a Choice Parameter with options no and yes (in that order so no is the safe default). This prevents engineers from accidentally triggering both when only one was intended.

3. Bind Credentials as Environment Variables

Under Build Environment, tick Use secret text(s) or file(s). Add bindings for your vCenter credentials stored in Jenkins Credentials store. Map them to environment variables Username and Password so the script picks them up via $Env:Username and $Env:Password.

4. Add Build Step — Execute PowerShell

Add a Build Step → Execute Windows PowerShell step. In the script field enter:

Jenkins Build Step — PowerShell
& "C:\Scripts\VMware-CPU-Memory-Resize.ps1"

The script file should be placed on the Jenkins agent at the above path, or pulled from Git SCM (see optional step below).

5. (Optional) Source from Git Repository

Under Source Code Management, select Git and point to:

Repository URL
https://github.com/automatewithravi/VMware.git

Set the script path to the file in the repo. This ensures every build pulls the latest approved version of the script.

6. Configure Post-Build Email Notifications

Under Post-build Actions → Editable Email Notification, configure recipients and triggers. The script already handles failure emails inline, but Jenkins-level notifications provide an additional safety net for pipeline failures.

⚠️
Security Best Practice Never store vCenter passwords as plain-text string parameters in Jenkins. Always use the Jenkins Credentials store and bind them using the Credentials Binding Plugin. This ensures credentials are masked in console logs.

7. Save and Test

Click Save. Then click Build with Parameters and test with a non-critical VM first. Review the Console Output in Jenkins and the transcript log file generated on the agent.

🔀 Script Logic Flow

The script follows a deterministic flow on every run — connect, validate, shutdown, modify, verify, start, alert.

▶ Jenkins Parameterised Build Triggered
Validate & Connect to PROD / DR vCenter
↓ on failure → Email alert → Exit
Check VM Power State
↓ if PoweredOn → Graceful Guest Shutdown (180s) → Force Stop if needed
Apply Changes: Set-VMCPU and/or Set-VMMemory
Verify: Confirm actual CPU/Memory matches requested values
↓ on verified → Power On VM
✅ Complete — Transcript logged

📄 The PowerShell Script

The script is structured into clean reusable functions — Connect-VCenter, Stop-VMSafely, Set-VMCPU, Set-VMMemory, Confirm-CPUChange, and Send-AlertEmail — while preserving the original logic exactly. No logic modification has been made.

🐙
Available on GitHub The full script is published at github.com/automatewithravi/VMware — repository: VMware, file: VMware-CPU-Memory-Resize.ps1
VMware-CPU-Memory-Resize.ps1 — Key Functions
# ── HELPER FUNCTIONS ───────────────────────────────────────────

function Send-AlertEmail {
    param ([string]$Subject, [string]$Body)
    Send-MailMessage -SmtpServer $SMTP_Server `
        -From $Mail_From -To $Mail_To `
        -Subject ($Subject + " - " + (Get-Date -Format "dd-MM-yyyy")) `
        -Body $Body
}

function Connect-VCenter {
    param ([string]$VCenterName, [string]$Label)
    $Connection = Connect-VIServer -Server $VCenterName -User $Username -Password $Password
    if ($Connection.IsConnected -ne $true) { Write-Host " Unable to connect to $Label"; Exit 1 }
    Write-Host " $Label vCenter connected." -ForegroundColor Green
}

function Stop-VMSafely {
    param ([string]$VMName, [int]$GraceSeconds = 180)
    Get-VM | Where-Object { $_.Name -like $VMName } | Stop-VMGuest -Confirm:$false
    Start-Sleep -Seconds $GraceSeconds
    Get-VM | Where-Object { $_.Name -like $VMName -and $_.PowerState -like "*On" } | Stop-VM -Confirm:$false
}

function Set-VMCPU {
    param ([string]$VMName, [int]$NumCPU)
    Get-VM -Name $VMName | Set-VM -NumCpu $NumCPU -Confirm:$false
}

function Set-VMMemory {
    param ([string]$VMName, [int]$MemoryGB)
    Get-VM -Name $VMName | Set-VM -MemoryGB $MemoryGB -Confirm:$false
}

function Confirm-CPUChange {
    param ([string]$VMName, [int]$Expected)
    $Actual = (Get-VM -Name $VMName).NumCpu
    return $Actual -eq $Expected
}

function Confirm-MemoryChange {
    param ([string]$VMName, [int]$Expected)
    $Actual = (Get-VM -Name $VMName).MemoryGB
    return $Actual -eq $Expected
}

# ── EXECUTION FLOW ─────────────────────────────────────────────

$VM_PowerStatus = (Get-VM -Name $VMName).PowerState

if ($CPU -eq "yes" -and $Memory -ne "yes") {
    if ($VM_PowerStatus -eq "PoweredOn") { Stop-VMSafely -VMName $VMName }
    Set-VMCPU -VMName $VMName -NumCPU $NumberofCPU_required
    if (Confirm-CPUChange -VMName $VMName -Expected $NumberofCPU_required) { Start-VMAndVerify -VMName $VMName }
}
elseif ($Memory -eq "yes" -and $CPU -ne "yes") {
    if ($VM_PowerStatus -eq "PoweredOn") { Stop-VMSafely -VMName $VMName }
    Set-VMMemory -VMName $VMName -MemoryGB $Memory_Size_required
    if (Confirm-MemoryChange -VMName $VMName -Expected $Memory_Size_required) { Start-VMAndVerify -VMName $VMName }
}
elseif ($CPU -eq "yes" -and $Memory -eq "yes") {
    if ($VM_PowerStatus -eq "PoweredOn") { Stop-VMSafely -VMName $VMName }
    Set-VMMemory -VMName $VMName -MemoryGB $Memory_Size_required
    Set-VMCPU    -VMName $VMName -NumCPU    $NumberofCPU_required
    $MemOK = Confirm-MemoryChange -VMName $VMName -Expected $Memory_Size_required
    $CPUOK = Confirm-CPUChange    -VMName $VMName -Expected $NumberofCPU_required
    if ($MemOK -and $CPUOK) { Start-VMAndVerify -VMName $VMName }
}

🛠️ Common Issues & Troubleshooting

IssueLikely CauseFix
Cannot connect to vCenter Wrong FQDN or credentials Verify FQDN resolves from Jenkins agent; test credentials manually via PowerCLI
VM still powered on after 180s Guest tools not installed / hung OS Force Stop-VM fallback handles this automatically; check VM console
CPU/Memory mismatch after Set-VM Hot-add not enabled or resource limits Verify VM hardware settings; check VM version supports hot-add
Email not sent SMTP unreachable from agent Test Test-NetConnection 172.0.2.35 -Port 25 from the agent
PowerCLI not found Not installed on agent scope Re-run install with -Scope AllUsers as Administrator

🏷️ Tags

VMware vSphere PowerCLI PowerShell Automation Jenkins Parameterised Build CI/CD vCenter CPU Resize Memory Resize Infrastructure Automation DevOps