The last piece of the puzzle is often upgrading the VM. Before you can add a vTPM, your environment needs to meet a few prerequisites:
- EFI Firmware: The virtual machine must be configured to use EFI firmware. This setting can be found in the VM settings under VM Options > Boot Options > Firmware.
- Hardware Version 14 or Higher: The virtual machine’s hardware compatibility must be at least version 14.
- vCenter Server 6.7 or Later: Your vCenter Server instance must be running version 6.7 or a more recent release.
- Virtual Machine Encryption: You need to have virtual machine encryption enabled to protect the virtual machine’s home files.
- Key Management Server (KMS): A properly configured KMS is essential for vCenter Server, as virtual machine encryption relies on it.
For the purpose of this guide, we’ll assume that you already have vCenter Server 6.7+ deployed and that virtual machine encryption and KMS are configured in your environment. These initial setup steps are outside the scope of this post, but you can find detailed information on Broadcom’s website: https://techdocs.broadcom.com/us/en/vmware-cis/vsphere/vsphere/6-7/vsphere-security-6-7/use-encryption-in-your-vsphere-environment/set-up-the-key-management-server-cluster.html
With the vSphere prerequisites in place, adding a vTPM to a virtual machine involves two primary steps:
- Upgrade the Hardware Version: Ensure the virtual machine’s hardware compatibility is version 14 or higher.
- Add the vTPM Hardware: Integrate the Trusted Platform Module into the virtual machine’s configuration.
It’s quite common in upgraded vSphere environments to overlook updating the virtual machine hardware version. Here’s how to perform the hardware upgrade.
Upgrading the Hardware Version via the vSphere Client:
- Locate the target virtual machine in the vSphere Client inventory.
- Navigate to the Update tab for that virtual machine and click on Check Status.
- Under the VM Hardware Compatibility section, select Upgrade to match host. The virtual machine will reboot and its hardware will be upgraded to the latest version supported by the ESXi host.
Adding the vTPM via the vSphere Client:
- Locate the target virtual machine in the vSphere Client inventory.
- Remove Existing Snapshots: If the virtual machine has any snapshots, you must delete them before adding a TPM. Go to Actions > Snapshots > Delete All Snapshots. (A TPM cannot be added if snapshots exist.)
- Power Off the Virtual Machine: The virtual machine must be powered off to add the TPM hardware.
- Edit Settings: Go to Actions > Edit Settings… and click on Add New Device. Choose Trusted Platform Module.
- Power On the Virtual Machine: Once the TPM has been added, you can start the virtual machine.
Both of these steps can be done via PowerShell as well.
To Upgrade the Hardware version via Powershell
# Installs the required PowerCLI module if it's not already installed
if (-not (Get-Module -Name VMware.PowerCLI -ListAvailable)) {
Install-Module VMware.PowerCLI -Scope CurrentUser -Force
}
# Connect to your vCenter Server
$vCenterServer = "your_vcenter_server_address" # Replace with your vCenter Server address
$credential = Get-Credential
try {
Connect-VIServer -Server $vCenterServer -Credential $credential -ErrorAction Stop
} catch {
Write-Error "Failed to connect to vCenter Server: $($_.Exception.Message)"
exit
}
# Specify the name of the target virtual machine
$vmName = "YourVMName" # Replace with the actual name of your VM
# Specify the desired hardware version (e.g., "v19")
$desiredHardwareVersion = "v19"
$desiredVmxVersion = "vmx-$($desiredHardwareVersion -replace '[^\d]')"
# Get the virtual machine object
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if (-not $vm) {
Write-Error "Virtual machine '$vmName' not found."
Disconnect-VIServer -Confirm:$false
exit
}
# Check the current hardware version
$currentHardwareVersion = $vm.HardwareVersion
Write-Host "Current Hardware Version for '$vmName': $currentHardwareVersion" -ForegroundColor Cyan
# Extract the numerical part of the versions for comparison
$currentVersionNumber = [int]($currentHardwareVersion -replace '[^\d]', '')
$desiredVersionNumber = [int]($desiredHardwareVersion -replace '[^\d]', '')
# Check if an upgrade is needed
if ($currentVersionNumber -lt $desiredVersionNumber) {
Write-Host "Upgrading hardware version of '$vmName' from $currentHardwareVersion to $desiredVmxVersion..." -ForegroundColor Yellow
$vmConfigSpec = New-Object -TypeName VMware.Vim.VirtualMachineConfigSpec
$vmConfigSpec.ScheduledHardwareUpgradeInfo = New-Object -TypeName VMware.Vim.ScheduledHardwareUpgradeInfo
$vmConfigSpec.ScheduledHardwareUpgradeInfo.UpgradePolicy = [VMware.Vim.ScheduledHardwareUpgradeInfoHardwareUpgradePolicy]::onSoftPowerOff
$vmConfigSpec.ScheduledHardwareUpgradeInfo.VersionKey = $desiredVmxVersion
try {
$vm.ExtensionData.ReconfigVM_Task($vmConfigSpec) | Out-Null
Write-Host "Hardware upgrade for '$vmName' scheduled for the next power cycle." -ForegroundColor Green
Write-Host "Consider performing a guest OS reboot to initiate the upgrade." -ForegroundColor Green
} catch {
Write-Error "Error upgrading hardware version for '$vmName': $($_.Exception.Message)"
}
} else {
Write-Host "No hardware upgrade needed for '$vmName' (current version: $currentHardwareVersion)." -ForegroundColor Green
}
# Disconnect from vCenter Server
Disconnect-VIServer -Confirm:$false
To add the TPM via powershell
# Installs the required PowerCLI module if it's not already installed
if (-not (Get-Module -Name VMware.PowerCLI -ListAvailable)) {
Install-Module VMware.PowerCLI -Scope CurrentUser -Force
}
# Connect to your vCenter Server
$vCenterServer = "your_vcenter_server_address" # Replace with your vCenter Server address
$credential = Get-Credential
try {
Connect-VIServer -Server $vCenterServer -Credential $credential -ErrorAction Stop
} catch {
Write-Error "Failed to connect to vCenter Server: $($_.Exception.Message)"
exit
}
# Specify the name of the target virtual machine
$vmName = "YourVMName" # Replace with the actual name of your VM
# Get the virtual machine object
$vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue
if (-not $vm) {
Write-Error "Virtual machine '$vmName' not found."
Disconnect-VIServer -Confirm:$false
exit
}
# Power off the virtual machine
if ($vm.PowerState -eq "PoweredOn") {
Write-Host "Powering off virtual machine '$vmName'..." -ForegroundColor Yellow
try {
Stop-VM -VM $vm -Confirm:$false -ErrorAction Stop
Write-Host "Virtual machine '$vmName' powered off." -ForegroundColor Green
} catch {
Write-Error "Error powering off virtual machine '$vmName': $($_.Exception.Message)"
Disconnect-VIServer -Confirm:$false
exit
}
} else {
Write-Host "Virtual machine '$vmName' is already powered off." -ForegroundColor Green
}
# Remove snapshots
$snapshots = Get-Snapshot -VM $vm
if ($snapshots) {
Write-Host "Removing snapshots for virtual machine '$vmName'..." -ForegroundColor Yellow
foreach ($snapshot in $snapshots) {
try {
Remove-Snapshot -Snapshot $snapshot -Confirm:$false -ErrorAction Stop
Write-Host "Snapshot '$($snapshot.Name)' removed." -ForegroundColor Green
} catch {
Write-Error "Error removing snapshot '$($snapshot.Name)': $($_.Exception.Message)"
Disconnect-VIServer -Confirm:$false
exit
}
}
Write-Host "All snapshots removed." -ForegroundColor Green
} else {
Write-Host "No snapshots found for virtual machine '$vmName'." -ForegroundColor Green
}
# Add the vTPM device
Write-Host "Adding vTPM to virtual machine '$vmName'..." -ForegroundColor Yellow
try {
New-VTpm -VM $vm -ErrorAction Stop
Write-Host "vTPM added to virtual machine '$vmName'." -ForegroundColor Green
} catch {
Write-Error "Error adding vTPM to virtual machine '$vmName': $($_.Exception.Message)"
}
# Power on the virtual machine
Write-Host "Powering on virtual machine '$vmName'..." -ForegroundColor Yellow
try {
Start-VM -VM $vm -ErrorAction Stop
Write-Host "Virtual machine '$vmName' powered on." -ForegroundColor Green
} catch {
Write-Error "Error powering on virtual machine '$vmName': $($_.Exception.Message)"
}
# Disconnect from vCenter Server
Disconnect-VIServer -Confirm:$fal
Now that we’ve completed the process of preparing a VM in the Horizon/vSphere environment, the next and final part of this series will explore how to integrate everything and automate some of these steps. This will enable us to provision virtual machines at scale within an enterprise.
I also want to give a shout-out to Don Horrox and his article , PowerCLI: Upgrade VM Hardware Compatibility Version from CSV which provided a PowerShell script to check and upgrade the virtual machine hardware version. His article is a fantastic resource for performing this task efficiently at scale.
Until next time.