VM Junkie

January 29, 2009

Balancing LUN Paths on your ESX Hosts with PowerShell

Filed under: esx, powershell, vmware — ermac318 @ 4:28 pm

After watching this video that was posted by the VI Toolkit team, I immediately thought of this script that was posted quite a while back on Yellow Bricks. I decided to try to recreate this script in PowerShell, and while I was at it expand it so it would modify all nodes in a cluster at once. As such I wrote the following script. Please feel free to give feedback or make modifications! You can download it from my Sky Drive or check it out below:

# Cluster-wide LUN Path Load Balancing Script
# Written by Justin Emerson, https://vmjunkie.wordpress.com
# Idea originally from a PERL script I saw here:
#    http://www.yellow-bricks.com/2008/04/01/load-balancing-activeactive-sans/
# This script requires the VI Toolkit version 1.5
# NOTE: This script assumes that every LUN has the same number of paths.
#       If you have multiple storage arrays, and they have different numbers of paths,
#		I make no guarentees that this will work!
# If you have an improvement to this script, please feel free to leave a comment on my blog!
Write-Host "This script will modify the policy of all your shared LUNs on all ESX Servers" -ForegroundColor Cyan
Write-Host "in a Cluster to Fixed and select a preferred path in a round-robin fashion." -ForegroundColor Cyan
if ($args.Length -eq 0) {$clusterName = Read-Host "Please enter the Cluster name"} else {$clusterName = $args[0]}
$VMHosts = Get-Cluster $clusterName | Get-VMHost
# Run through this loop for each host in the cluster
foreach ($VMHost in $VMHosts)
{
	# Keep only disks of luntype "disk" to avoid any storageArrayController devices.
	# Filter to only objects where the ConsoleDeviceName starts with vml to avoid any DAS disks.
	# Note: I have tested both HP EVA and Xiotech storage and SAN LUNs always appear this way.
	# Please check if this is the same on your storage before running.
	$luns = $VMHost|get-scsilun -luntype disk|
	where-object {$_.ConsoleDeviceName -like "/vmfs/devices/disks/vml*"}|Sort-Object CanonicalName
	$firstLUNPaths = Get-ScsiLunPath $luns[0]
	$numPaths = $firstLUNPaths.Length
	$count = 0
	foreach ($lun in $luns)
	{
		if ($count -ge $numPaths) { $count = 0 }
		$paths = Get-ScsiLunPath -ScsiLun $lun
		$lun|Set-ScsiLun -MultipathPolicy Fixed -PreferredPath $paths[$count]
		$count += 1
		# Sleep for 30 seconds as I've heard some arrays dont like doing this too fast.
		Start-Sleep -Seconds 30
	}
}

Note that after running the script, my ESX servers had esxcfg-mpath -l an output of:

[root@tb20 root]# esxcfg-mpath -l
Disk vmhba1:0:3 /dev/sdc (307200MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:3 On
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:3 On
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:3 On active preferred
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:3 On

Disk vmhba1:0:4 /dev/sdd (1048576MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:4 On
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:4 On
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:4 On
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:4 On active preferred

Disk vmhba1:0:6 /dev/sdf (358400MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:6 On
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:6 On active preferred
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:6 On
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:6 On

Disk vmhba1:0:1 /dev/sda (204800MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:1 On active preferred
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:1 On
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:1 On
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:1 On

Disk vmhba0:0:0 /dev/cciss/c0d0 (139979MB) has 1 paths and policy of Fixed
 Local 6:0.0 vmhba0:0:0 On active preferred

Disk vmhba1:0:2 /dev/sdb (153600MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:2 On
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:2 On active preferred
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:2 On
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:2 On

Disk vmhba1:0:5 /dev/sde (307200MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:5 On active preferred
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:5 On
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:5 On
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:5 On

Disk vmhba1:0:7 /dev/sdg (102400MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:7 On
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:7 On
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:7 On active preferred
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:7 On

Disk vmhba1:0:8 /dev/sdh (102400MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:8 On
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:8 On
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:8 On
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:8 On active preferred

RAID Controller (SCSI-3) vmhba1:1:0  (0MB) has 4 paths and policy of Fixed
 FC 14:0.0 500110a00016013e<->50001fe1500ef59d vmhba1:1:0 On active preferred
 FC 14:0.0 500110a00016013e<->50001fe1500ef599 vmhba1:0:0 On
 FC 23:0.0 500110a000160152<->50001fe1500ef598 vmhba2:0:0 On
 FC 23:0.0 500110a000160152<->50001fe1500ef59c vmhba2:1:0 On

Yay, it worked!

Advertisements

18 Comments

  1. […] in Management & Automation, Server Just noticed this pingback. The topic title “Balancing LUN paths on your ESX hosts with powershell” sounded promising so I headed over. Justin Emerson is the owner of the blog and he wrote a […]

    Pingback by Balancing LUN paths with powershell » Yellow Bricks — January 29, 2009 @ 9:34 pm

  2. Great script.
    Why bother to enter the cluster name?
    Why not just retrieve all clusters from vCenter and loadbalace all cluster?

    Nice to run this at a regular interval.

    Comment by Arnim van Lieshout — February 5, 2009 @ 8:46 am

  3. I chose to only do it to a single cluster at a time because some customers may have some clusters running iSCSI and others running Fiberchannel, and I was unable to test it against any iSCSI LUNs at the time. Plus, someone may want to run it just against their development or VDI cluster or something first. And I figure it’s trivial to adapt my script to do every cluster for someone so inclined.
    Thanks for the feedback!

    Comment by ermac318 — February 5, 2009 @ 8:49 am

  4. […] in the VMware community. First of all, there is nothing wrong with those scripts. For example, Justin Emerson wrote an excellent script that changes the active paths on an active/active SAN. But running an […]

    Pingback by HP CA and the use of LUN balancing scripts « Frank Denneman — February 9, 2009 @ 11:28 pm

  5. Thanks for the script.

    I tweaked it a bit and posted a question in the forums.

    Id like to see it work on systems connected to different array models.

    Maybe an If statement if this array run it this way if this array run it that way.

    Thanks again

    http://communities.vmware.com/message/1169352

    Comment by cititechs — February 11, 2009 @ 2:23 pm

  6. […] in the VMware community. First of all, there is nothing wrong with those scripts. For example, Justin Emerson wrote an excellent script that changes the active paths on an active/active SAN. But running an […]

    Pingback by Frank Denneman » Blog Archive » HP CA and the use of LUN balancing scripts — May 1, 2009 @ 8:09 am

  7. To use the script with non cluster server, you may change the script a little bit.
    Remove the following two lines and add my code.
    if ($args.Length -eq 0) {$clusterName = Read-Host “Please enter the Cluster name”} else {$clusterName = $args[0]}
    $VMHosts = Get-Cluster $clusterName | Get-VMHost

    if ($args.Length -lt 2) {
    Write-Host “usage: -c or -s ”
    exit 1
    } else {
    if ($args[0] -eq “-c”) { $VMHosts = Get-Cluster $args[1] | Get-VMHost }
    if ($args[0] -eq “-s”) { $VMHosts = Get-VMHost $args[1] }
    }
    Write-Host “Modifiying ESX hosts:” $VMHosts

    Comment by Ulf — June 3, 2009 @ 1:10 am

  8. I’m having some issues with your script in a Hitachi SAN. It worked flawless on an EMC SAN. I took a screenshot:

    It is actually making changes in virtual center, but it is just keeping the primary path the same. It isn’t actually changing them to load balance. Any ideas?

    Thanks!

    Comment by Mike — January 16, 2010 @ 10:43 am

  9. When i run this script i get the following error:

    ScsiLunPathImpl.
    At :line:35 char:64
    + $lun|Set-ScsiLun -MultipathPolicy Fixed -PreferredPath $paths[ <<<< $count]

    any solutions or anwsers ?

    thnx

    Comment by Bart van Benthem — January 27, 2010 @ 4:44 am

  10. i forgot a line:

    Unable to index into an object of type VMware.VimAutomation.Client20.Host.ScsiLunPathImpl.
    At :line:35 char:64
    + $lun|Set-ScsiLun -MultipathPolicy Fixed -PreferredPath $paths[ <<<< $count]

    thnx,

    Comment by Bart van Benthem — January 27, 2010 @ 4:46 am

  11. […] in the VMware community. First of all, there is nothing wrong with those scripts. For example, Justin Emerson wrote an excellent script that changes the active paths on an active/active SAN. But running an […]

    Pingback by HP CA and the use of LUN balancing scripts | — March 9, 2010 @ 1:48 am

  12. I have the same problem after four path,
    $lun|Set-ScsiLun -MultipathPolicy Fixed -PreferredPath $paths[ <<<< $count]
    any solutions?
    thanks

    Comment by cerro — March 9, 2010 @ 9:52 am

  13. Has anyone gotten this to work with vsphere4? It works great for my 3.01 and 3.5 hosts, but not with vsphere4. It appears the canonicalname now comes up as naa… instead of vmhba*. This looks to be the issue, was wondering if anyone has had any luck with it and if so what did they have to change.

    Thanks
    Dan

    Comment by Dan Shapiro — March 10, 2010 @ 8:54 am

  14. You are correct – the issue with the script is related to vSphere 4.
    I know there are several responses to this thread which involve people having issues. I haven’t responded to them because honestly, in vSphere 4 this script is unnecessary. Instead of manually balancing paths using this script, you should instead set your path policies to Round Robin. This is best practice according to HP and my employer.
    Because vSphere4 is ALUA aware, it will round robin across the paths to the primary controller, thus improving throughput without the guesswork or babysitting that manual path balancing would require.
    Lookup the Set-SCSILun CMDlet in the PowerCLI documentation – you can use this cmdlet to set all paths to an EVA on all your hosts to RoundRobin in a single line of code.

    Comment by ermac318 — March 10, 2010 @ 11:25 am

  15. Thanks for the reply ermac318. Actually, we’re not necessarily using this script to balance, but more so to do path checks and to force paths from red to blue and vice-versa before SAN maintance events. We have over 4000 paths to move, so this script has been great.

    Thanks

    Comment by Dan Shapiro — March 11, 2010 @ 7:53 am

  16. If you want to make this work on vSphere, replace lines 21 and 22 with the following:
    $luns = $VMHost | get-scsilun -luntype disk -CanonicalName naa* | Sort-Object CanonicalName

    Comment by ermac318 — March 11, 2010 @ 9:58 am

  17. Thanks for Replay,
    my issue
    $lun|Set-ScsiLun -MultipathPolicy Fixed -PreferredPath $paths[ <<<< $count]
    is related to ESX 3.5 Update 4
    I have 2 hba and 4 path but without the counter the preferred remaining the same.
    Thanks for all.

    Comment by cerro — March 11, 2010 @ 10:39 am


RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Create a free website or blog at WordPress.com.

%d bloggers like this: