After deploying my VMware Cloud Foundation 9.1.1 workload domain, the next step was to enable vSAN Express Storage Architecture (ESA) on its three-host cluster. This article follows the complete process I used, including the prerequisite change to vSphere HA, the vSAN configuration choices, disk claiming, post-deployment health checks, remediation of a 10 GbE compliance warning, and the final step of restoring HA protection.
The screenshots captured during the build also exposed an important lesson: do not treat clicking Finish as the end of the job. Confirm that every configuration task completes, review vSAN Health, address any findings, and then restore any cluster services that were temporarily disabled.
Environment and configuration goals
The workload domain consists of three ESXi hosts connected with 10 GbE networking. Each host contributes one NVMe device to a single-site vSAN ESA storage pool. The goal was to create a 5.46 TB raw-capacity datastore while keeping the initial configuration straightforward.
The resulting vSAN configuration uses:
- vSAN Express Storage Architecture
- One NVMe device per host
- Three devices and 5.46 TB of total raw capacity
- A single-site cluster without custom fault domains or a witness
- Compression enabled
- Data-at-rest encryption disabled
- Data-in-transit encryption disabled
- RDMA disabled
- Automatic policy management enabled
- Automatic RAID policy application enabled
Step 1: Temporarily disable vSphere HA
Before starting the vSAN configuration, I temporarily disabled vSphere HA. In the vSphere Client, select the workload cluster and navigate to Configure > Services > vSphere Availability. Select Edit, turn off vSphere HA, and apply the change.
After the change is applied, the vSphere Availability page shows that HA is off and that host failure, host isolation, datastore failure, and guest heartbeat responses are disabled. Record the existing HA response settings before making the change so they can be verified when HA is restored later.
Step 2: Start the vSAN configuration wizard
From the same cluster, navigate to Configure > vSAN > Services and start the vSAN configuration workflow. I selected a single-site vSAN cluster and enabled vSAN ESA.
The wizard performs compatibility checks for the storage devices and physical network adapters. Review these checks carefully. ESA has specific hardware and networking expectations, and a warning at this stage should not simply be ignored.
Step 3: Configure vSAN services
On the Services page, I used the following settings:
- Data-at-rest encryption: Off
- Data-in-transit encryption: Off
- Allow reduced redundancy: Not selected
- RDMA support: Off
- vSAN Auto-Policy Management: On
- Apply Auto-RAID to all objects: On
These selections were appropriate for this lab, but production environments should evaluate encryption, RDMA, availability, and policy requirements against their security and design standards.
Step 4: Claim the storage devices
The first pass through the disk-claiming page used manual selection. The wizard identified one Samsung NVMe device in each host, providing 5.46 TB of total raw capacity, but initially displayed an ESA compatibility warning.
Rather than forcing the configuration through, I returned to the disk selection step and allowed vSAN to manage the disks. The wizard automatically selected one 1.82 TB device from each host and reported the resulting three-device, 5.46 TB storage pool as ESA compatible. I then reviewed the manual view again to confirm that the same devices appeared as compatible before continuing.
This validation is especially important when using lab hardware. Confirm the exact devices, host placement, capacity, and compatibility state before proceeding.
Step 5: Review fault domains
The fault-domain page listed all three hosts. I did not create custom fault domains because this is a compact, single-site lab cluster. With three hosts, the wizard indicated that the configuration could tolerate one failure.
Larger or production deployments may require explicit fault-domain design based on rack, room, chassis, or site placement.
Step 6: Review and finish the configuration
The final review page confirmed:
- Single-site cluster
- vSAN ESA enabled
- No encryption
- Three claimed disks
- 5.46 TB of raw capacity
- No witness host
- No custom fault domains
- RDMA disabled
- Auto-policy and Auto-RAID enabled
After selecting Finish, I monitored Cluster > Monitor > Tasks. vCenter started the required services, reconfigured the cluster, updated the vSAN configuration on each host, refreshed host storage, updated disk partitions, added the disks to the storage pool, and remediated the vSAN cluster.
Do not move on until the cluster-level and per-host tasks show a green Completed status. In my environment, all three hosts completed their disk-add and vSAN configuration tasks successfully.
Step 7: Validate vSAN Health
Next, I opened Cluster > Monitor > vSAN > vSAN Health. The initial post-deployment check produced a health score of 97. Of 53 checks, three were unhealthy and two were informational.
One visible finding was vSAN cluster compliance. Its detail explained that resync traffic optimization was not enabled. This check is relevant when vSAN ESA runs on 10 GbE networking because the network scheduler setting helps optimize resynchronization traffic.
Resolve the resync traffic optimization warning
The finding can be remediated on an individual ESXi host with the following command:
esxcli system settings advanced set -i 1 -o /VSAN/DOMNetworkSchedulerThrottleComponentBecause every host in the cluster needs the same setting, I created a reusable PowerCLI script. It prompts for vCenter credentials, finds every ESXi host in the specified cluster, applies the setting through the vSphere API, and reads it back for verification. SSH does not need to be enabled on the hosts.
#requires -Version 7.0
#requires -Modules VMware.VimAutomation.Core
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$Server,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$ClusterName,
[Parameter()]
[PSCredential]$Credential
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$settingPath = '/VSAN/DOMNetworkSchedulerThrottleComponent'
$desiredValue = 1
$viConnection = $null
try {
$connectParameters = @{
Server = $Server
ErrorAction = 'Stop'
}
if ($Credential) {
$connectParameters.Credential = $Credential
}
$viConnection = Connect-VIServer @connectParameters
$cluster = Get-Cluster -Name $ClusterName -Server $viConnection -ErrorAction Stop
$vmHosts = @(Get-VMHost -Location $cluster -Server $viConnection | Sort-Object Name)
if ($vmHosts.Count -eq 0) {
throw "No ESXi hosts were found in cluster '$ClusterName'."
}
$results = foreach ($vmHost in $vmHosts) {
try {
if ($PSCmdlet.ShouldProcess($vmHost.Name, "Set $settingPath to $desiredValue")) {
$esxcli = Get-EsxCli -VMHost $vmHost -V2 -ErrorAction Stop
$setArguments = $esxcli.system.settings.advanced.set.CreateArgs()
$setArguments.option = $settingPath
$setArguments.intvalue = [long]$desiredValue
$setResult = $esxcli.system.settings.advanced.set.Invoke($setArguments)
if (-not $setResult) {
throw 'ESXCLI reported that the setting was not changed.'
}
$listArguments = $esxcli.system.settings.advanced.list.CreateArgs()
$listArguments.option = $settingPath
$setting = $esxcli.system.settings.advanced.list.Invoke($listArguments)
$verifiedValue = [int]$setting.IntValue
if ($verifiedValue -ne $desiredValue) {
throw "Verification returned '$verifiedValue' instead of '$desiredValue'."
}
[PSCustomObject]@{
Host = $vmHost.Name
Status = 'Success'
Value = $verifiedValue
Detail = 'Setting applied and verified.'
}
}
}
catch {
[PSCustomObject]@{
Host = $vmHost.Name
Status = 'Failed'
Value = $null
Detail = $_.Exception.Message
}
}
}
$results | Format-Table -AutoSize
$failedHosts = @($results | Where-Object Status -eq 'Failed')
if ($failedHosts.Count -gt 0) {
throw "$($failedHosts.Count) host configuration changes failed."
}
}
finally {
if ($viConnection) {
Disconnect-VIServer -Server $viConnection -Confirm:$false | Out-Null
}
}PowerCLI prerequisites
- PowerShell 7 or later
- VMware PowerCLI
- A vCenter account permitted to query the cluster and change ESXi advanced settings
- The exact vCenter Server and cluster names
If PowerCLI is not installed, run:
Install-Module VMware.PowerCLI -Scope CurrentUserSave the script as Set-VsanEsaResyncTrafficOptimization.ps1. First use -WhatIf to confirm the targeted hosts:
./Set-VsanEsaResyncTrafficOptimization.ps1 `
-Server 'vcenter.example.com' `
-ClusterName 'workload-cluster' `
-Credential (Get-Credential) `
-WhatIfWhen the preview lists the correct hosts, run the same command without -WhatIf:
./Set-VsanEsaResyncTrafficOptimization.ps1 `
-Server 'vcenter.example.com' `
-ClusterName 'workload-cluster' `
-Credential (Get-Credential)A host is complete when the script reports Success and a verified value of 1. Always review and test automation in a non-production environment before using it in production.
Step 8: Retest and confirm a healthy cluster
After applying the setting to all three hosts, I returned to vSAN Health and selected Retest. The cluster health score increased from 97 to 99, and the number of unhealthy findings dropped from three to zero. The refreshed result contained 56 total checks, two informational findings, and one silenced finding, with no active unhealthy checks.
This before-and-after result confirmed that the remediation worked and that the newly configured vSAN cluster was healthy.
Step 9: Re-enable vSphere HA
The final task is easy to overlook: the vSAN workflow does not automatically restore vSphere HA. Return to Cluster > Configure > Services > vSphere Availability, select Edit, turn vSphere HA back on, and apply the change.
I verified that Host Monitoring was enabled and that the cluster again had active responses for host failure, host isolation, permanent device loss, all paths down, and guest heartbeat failures. The final vSphere Availability page showed vSphere HA is Turned ON, with the expected failure responses restored. Proactive HA remained disabled by design.
Final thoughts
Enabling vSAN ESA involved more than selecting disks and completing a wizard. The complete workflow included preparing cluster services, validating hardware selection, monitoring every background task, reviewing health findings, applying a host-level networking optimization, retesting the cluster, and restoring vSphere HA.
The most useful takeaways from this build were to stop when a compatibility state looks wrong, verify every claimed device, treat health findings as part of the deployment, automate repeatable host changes, and always restore temporarily disabled protection services. At the end of the process, the three-host workload cluster had an operational 5.46 TB vSAN ESA storage pool, no active unhealthy vSAN findings, and full vSphere HA protection restored.
