Running VMFS Unmap via PowerCLI

Starting in vSphere 5.5, VMware introduced a new command in the esxcli namespace that allows deleted blocks to be reclaimed on thin provisioned LUNs that support the VAAI UNMAP primitive.

You can run the command without any maintenance window, and the reclaim mechanism has been enhanced:

  • Reclaim disk space size can be specified in blocks instead of a percentage value to make it more intuitive to calculate.
  • Dead disk space is reclaimed in increments instead of all at once to avoid possible performance issues.

With the introduction of 62 TB VMDKs, UNMAP can now handle much larger dead space areas. However, UNMAP operations are still manual. This means Storage vMotion or Snapshot Consolidation tasks on VMFS do not automatically reclaim disk space on the array LUN.

Until now, we’ve run this command manually, by connecting to the a host in each vCenter/Cluster via SSH and running:
esxcli storage vmfs unmap –volume-label=LAB01-Cluster_Datastore01 –reclaim-unit=4000

We had each of these stored in a notepad document and would copy/paste them into Putty and do one datastore at a time. This was a very manual and time consuming process.

Below is the PowerCLI Script I wrote to automate this process.

###########################################################
#
# PowerCLI Script to run esxcli storage vmfs unmap
# Created by BLiebowitz on 3/14/2022
#
###########################################################


# Connect to each vCenter using supplied credentials
$creds = get-credental
connect-viserver LABVC01, LABVC02, LABVC03, LABVC04 -Credential $creds

# Build an Array for each Cluster
$array = "LAB01-Cluster", "LAB02-Cluster", "LAB03-Cluster", "lab04-Cluster"
for($count=0;$count -lt $array.length; $count++)
{ 
# Assign a host to run the unmap script against
	$vmhost = get-cluster $array[$count] | Get-VMHost | Select -First 1

# Set ESXCli to the host above
	$esxcli2 = get-esxcli -vmhost $VMHost -v2

# Get a list of the datastores
	$Datastores = Get-vmhost $vmhost | get-datastore
	foreach ($datastore in $datastores) {
		Write-Host " -------------------------------------------- " -ForegroundColor 'yellow'
		Write-Host " -- Starting Unmap on DataStore $datastore -- " -ForegroundColor 'yellow' 
		Write-Host " -------------------------------------------- " -ForegroundColor 'yellow'
		# Assign arguments for the unmap command
		$arguments = $esxcli2.storage.vmfs.unmap.CreateArgs()
				$arguments.volumelabel = $DataStore.Name
				$arguments.reclaimunit = "4000"
						# Perform the unmap command
						Write-Output "Starting UNMAP for $DataStore on $VMHost..."
						$esxcli2.storage.vmfs.unmap.Invoke($arguments)
						# start-sleep -seconds 10
		Write-Host " ------------------------------------------------- " -ForegroundColor 'green'
		Write-Host " -- Unmap has completed on DataStore $datastore -- " -ForegroundColor 'green'
		Write-Host " ------------------------------------------------- " -ForegroundColor 'green'
	}
}
# Disconnect from vCenter
	disconnect-viserver LABVC01, LABVC02, LABVC03, LABVC04 -confirm:$false

This allows us to schedule this script to be run on a regular basis and free up time for our engineers to work on other tasks!

Ben Liebowitz, VCP, vExpert
NJ VMUG Leader

Share This:

Leave a Reply

Your email address will not be published.

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