Enable / Disable VAAI with PowerCLI

If you don’t know what “vStorage APIs for Array Intergration” (VAAI ) is already then I suggest you look it up or at least talk to your storage vendor or VMware about VAAI as this is a great feature added by VMware in vSphere 4.1.

This basically offloads some of the features back to your storage array enabling your vSphere hosts to have more resources and time put aside for what there primary purpose in life is…. “Hosting VMs” and lets face it, the storage array is going to know how to do storage type functions more efficiently than the hosts.  I would suggest reading this post from “Virtual Geek” to get a better understanding of these 3 features which are part of VAAI.

In order to test this we recently needed a way to enable and disable VAAI, this is an easy task on a host, each of the three features have a setting in the “Advanced Settings” configuration tab of the host, these are:

DataMover.HardwareAcceleratedMove
DataMover.HardwareAcceleratedInit
VMFS3.HardwareAcceleratedLocking

These are set to 1 by default which means they are enabled, to disable them simply set them to 0.

So with a simple piece of PowerCLI we can easily see their current configuration status:

Get-VMHost MyESXHost | Get-VMHostAdvancedConfiguration -Name DataMover*, VMFS3.HardwareAcc*

We can also easily disable these features for our host:

$VMHost = Get-VMHost MyESXHost
Set-VMHostAdvancedConfiguration -VMHost $VMHost -Name DataMover.HardwareAcceleratedMove -Value 0
Set-VMHostAdvancedConfiguration -VMHost $VMHost -Name DataMover.HardwareAcceleratedInit -Value 0
Set-VMHostAdvancedConfiguration -VMHost $VMHost -Name VMFS3.HardwareAcceleratedLocking -Value 0

Or easily enable them by changing the values to 1 in the above script.

These settings for VAAI can be enabled or disabled dynamically, even during operations that take advantage of them. There will be no disruption to an ongoing operation as it switches between either using the API or software seamlessly. No reboot of the ESX host is required.

When testing we also wanted a nice GUI to enable people to do this without delving into PowerCLI – Apparently some people find this stuff hard (I know I didn’t understand that statement either).  Below you can find the script which allows us to easily select a host and enable or disable VAAI at the click of a button, I have even created a nice video of it running…

########################################################################
# Code Generated By: SAPIEN Technologies, Inc., PrimalForms 2009 v1.1.11.0
# Generated By: Alan Renouf - http://virtu-al.net
########################################################################

#----------------------------------------------
#region Application Functions
#----------------------------------------------

function OnApplicationLoad {
	return $true #return true for success or false for failure
}

function OnApplicationExit {

	$script:ExitCode = 0 #Set the exit code for the Packager
}

#endregion

#----------------------------------------------
# Generated Form Function
#----------------------------------------------
function GenerateForm {

	#----------------------------------------------
	#region Import Assemblies
	#----------------------------------------------
	[void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
	[void][reflection.assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
	[void][reflection.assembly]::Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
	[void][reflection.assembly]::Load("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
	#endregion

	#----------------------------------------------
	#region Generated Form Objects
	#----------------------------------------------
	[System.Windows.Forms.Application]::EnableVisualStyles()
	$VAAIForm = New-Object System.Windows.Forms.Form
	$button4 = New-Object System.Windows.Forms.Button
	$button3 = New-Object System.Windows.Forms.Button
	$button2 = New-Object System.Windows.Forms.Button
	$Output = New-Object System.Windows.Forms.ListBox
	$label1 = New-Object System.Windows.Forms.Label
	$Hosts = New-Object System.Windows.Forms.ComboBox
	$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
	#endregion Generated Form Objects

	#----------------------------------------------
	# User Generated Script
	#----------------------------------------------
function RefreshVAAI {
		If ($VAAI) {
			Remove-Variable VAAI
		}
		$HashTable = Get-VMHost ($Hosts.SelectedItem) | Get-VMHostAdvancedConfiguration -Name DataMover*, VMFS3.HardwareAcc*
		$VAAI = New-Object PSObject -Property $HashTable
		$Output.Items.Clear()
		If ($VAAI) {
			$VAAI | Sort Name | foreach {
				If ($_."DataMover.HardwareAcceleratedMove" -eq 1) {
					$Output.Items.Add("DataMover.HardwareAcceleratedMove = Enabled")|Out-Null
				} Else {
					$Output.Items.Add("DataMover.HardwareAcceleratedMove = Disabled")|Out-Null
				}
				If ($_."DataMover.HardwareAcceleratedInit" -eq 1) {
					$Output.Items.Add("DataMover.HardwareAcceleratedInit = Enabled")|Out-Null
				} Else {
					$Output.Items.Add("DataMover.HardwareAcceleratedInit = Disabled")|Out-Null
				}
				If ($_."VMFS3.HardwareAcceleratedLocking" -eq 1) {
					$Output.Items.Add("VMFS3.HardwareAcceleratedLocking = Enabled")|Out-Null
				} Else {
					$Output.Items.Add("VMFS3.HardwareAcceleratedLocking = Disabled")|Out-Null
				}
			}
		} Else {
			$Output.Items.Add("Unable to gather info from the selected host")|Out-Null
		}
	}

	$FormEvent_Load={
		if ($vcenter -eq $null) {
			$vcenter = Read-Host "Please enter the FQDN or IP of your vCenter Server"
		}
		if (Get-Pssnapin vmware.vimautomation.core) {
		} Else {
			add-pssnapin vmware.vimautomation.core
		}
		$Connected = connect-viserver -Server $vCenter
		If ($Connected) {
		} Else {
			[microsoft.visualbasic.interaction]::MsgBox("Unable to connect to $vCenter")
		}
		$VMHosts = Get-VMHost | where {$_.PowerState -eq "PoweredOn"}
		$VMHosts | Sort Name |ForEach-Object {
			$Hosts.Items.Add($($_.Name))|Out-Null
		}
		$Hosts.SelectedIndex=0
		RefreshVAAI
	}

	$handler_button1_Click={
		RefreshVAAI
	}

	$handler_button2_Click={
	Set-VMHostAdvancedConfiguration -VMHost (Get-VMHost ($Hosts.SelectedItem)) -Name DataMover.HardwareAcceleratedMove -Value 0
	Set-VMHostAdvancedConfiguration -VMHost (Get-VMHost ($Hosts.SelectedItem)) -Name DataMover.HardwareAcceleratedInit -Value 0
	Set-VMHostAdvancedConfiguration -VMHost (Get-VMHost ($Hosts.SelectedItem)) -Name VMFS3.HardwareAcceleratedLocking -Value 0
	RefreshVAAI
	}

	$handler_button3_Click={
	Set-VMHostAdvancedConfiguration -VMHost (Get-VMHost ($Hosts.SelectedItem)) -Name DataMover.HardwareAcceleratedMove -Value 1
	Set-VMHostAdvancedConfiguration -VMHost (Get-VMHost ($Hosts.SelectedItem)) -Name DataMover.HardwareAcceleratedInit -Value 1
	Set-VMHostAdvancedConfiguration -VMHost (Get-VMHost ($Hosts.SelectedItem)) -Name VMFS3.HardwareAcceleratedLocking -Value 1
	RefreshVAAI
	}

	$handler_button4_Click={
	$VAAIForm.Close()
	}

	$handler_Hosts_SelectedIndexChanged={
	RefreshVAAI

	}

	#----------------------------------------------
	# Generated Events
	#----------------------------------------------

	$Form_StateCorrection_Load=
	{
		#Correct the initial state of the form to prevent the .Net maximized form issue
		$VAAIForm.WindowState = $InitialFormWindowState
	}

	#----------------------------------------------
	#region Generated Form Code
	#----------------------------------------------
	#
	# VAAIForm
	#
	$VAAIForm.Controls.Add($button4)
	$VAAIForm.Controls.Add($button3)
	$VAAIForm.Controls.Add($button2)
	$VAAIForm.Controls.Add($Output)
	$VAAIForm.Controls.Add($label1)
	$VAAIForm.Controls.Add($Hosts)
	$VAAIForm.ClientSize = New-Object System.Drawing.Size(293,191)
	$VAAIForm.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
	$VAAIForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
	$VAAIForm.Name = "VAAIForm"
	$VAAIForm.Text = "VAAI Enable/Disable"
	$VAAIForm.add_Load($FormEvent_Load)
	#
	# button4
	#
	$button4.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
	$button4.Location = New-Object System.Drawing.Point(206,152)
	$button4.Name = "button4"
	$button4.Size = New-Object System.Drawing.Size(75,23)
	$button4.TabIndex = 11
	$button4.Text = "Exit"
	$button4.UseVisualStyleBackColor = $True
	$button4.add_Click($handler_button4_Click)
	#
	# button3
	#
	$button3.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
	$button3.Location = New-Object System.Drawing.Point(114,152)
	$button3.Name = "button3"
	$button3.Size = New-Object System.Drawing.Size(75,23)
	$button3.TabIndex = 9
	$button3.Text = "Enable"
	$button3.UseVisualStyleBackColor = $True
	$button3.add_Click($handler_button3_Click)
	#
	# button2
	#
	$button2.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
	$button2.Location = New-Object System.Drawing.Point(13,152)
	$button2.Name = "button2"
	$button2.Size = New-Object System.Drawing.Size(75,23)
	$button2.TabIndex = 7
	$button2.Text = "Disable"
	$button2.UseVisualStyleBackColor = $True
	$button2.add_Click($handler_button2_Click)
	#
	# Output
	#
	$Output.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
	$Output.FormattingEnabled = $True
	[void]$Output.Items.Add("Select a host and the refresh button ")
	[void]$Output.Items.Add("to see the current VAAI status")
	$Output.Location = New-Object System.Drawing.Point(13,68)
	$Output.Name = "Output"
	$Output.RightToLeft = [System.Windows.Forms.RightToLeft]::No
	$Output.Size = New-Object System.Drawing.Size(267,69)
	$Output.TabIndex = 4
	#
	# label1
	#
	$label1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
	$label1.Location = New-Object System.Drawing.Point(13,23)
	$label1.Name = "label1"
	$label1.Size = New-Object System.Drawing.Size(39,23)
	$label1.TabIndex = 1
	$label1.Text = "Host:"
	#
	# Hosts
	#
	$Hosts.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
	$Hosts.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
	$Hosts.FormattingEnabled = $True
	$Hosts.Location = New-Object System.Drawing.Point(58,20)
	$Hosts.Name = "Hosts"
	$Hosts.Size = New-Object System.Drawing.Size(222,21)
	$Hosts.TabIndex = 0
	$Hosts.add_SelectedIndexChanged($handler_Hosts_SelectedIndexChanged)
	#endregion Generated Form Code

	#----------------------------------------------

	#Save the initial state of the form
	$InitialFormWindowState = $VAAIForm.WindowState
	#Init the OnLoad event to correct the initial state of the form
	$VAAIForm.add_Load($Form_StateCorrection_Load)
	#Show the Form
	return $VAAIForm.ShowDialog()

} #End Function

#Call OnApplicationLoad to initialize
if(OnApplicationLoad -eq $true)
{
	#Create the form
	GenerateForm | Out-Null
	#Perform cleanup
	OnApplicationExit
}

6 thoughts on “Enable / Disable VAAI with PowerCLI”

  1. Alan,

    That helps at least I can get the LDEV number somehow in ESXi now. We have a naming standard for luns that includes the LDEV number. If I can get the LDEV once I can put it into the name.

    Regards,
    Jeff

  2. Alan,

    Great post. I was wondering if you know of a property for storage that would have the CULDEV from the storage frame included. Currently with ESX installations we can pull that information with inqraid and some scripting to match the CULDEV to the named LUN. I cannot seem to find it using ESXi

    1. I had to look this one up and came across the link below:
      http://communities.vmware.com/message/1650375?tstart=0

      Do you basically want to automate this part:

      A trick you can use in the meantime to see the CU:LDEV ID with the VM running…….in vSphere Client, open the VM “Edit Settigs” window, click on the RDM hard disk, then go to “Manage Paths”. In the top of the “Manage Paths” window, the last four digits of the ID are the CU:LDEV. You can also hover over the “Name” entry and it will pop up the entire string with the CU:LDEV as the last four digits.

Leave a Reply

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