VMware

This Question is Answered

14 Replies Last post: Jun 9, 2009 1:56 AM by gboskin  

scripting esxcfg-mpath -l results posted: Nov 20, 2008 4:47 PM

Click to view steve31783's profile Hot Shot 178 posts since
Nov 8, 2006

Hello all...

I recently had an issue with a few of my ESX hosts, where particular HBA ports on the host were not seeing all of the paths to our SAN that I expect them to.

What I would like to do is have a script that could gather results similar to the esxcfg-mpath -l command for each host in a particular cluster, and then export that to csv so I can have a weekly check to ensure there aren't any SAN issues related to this particular problem...

I really have no idea where to start, or if a similar output is available using commands in the vi toolkit. I had done a little reading about using plink to do similar things, but id prefer to not go down that road if i dont have to.

Anyone have any ideas?

Re: scripting esxcfg-mpath -l results

1. Nov 20, 2008 6:41 PM in response to: steve31783
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
This should get you going:

$hostview = Get-VMHost | Get-View
$mPathLun = $hostview.Config.StorageDevice.MultipathInfo.Lun
foreach ( $lun in $mPathLun ) {
	$lunName = $lun.Id
	$pathCount = $lun.Path.Length
	$mPathPolicy = $lun.Policy.Policy
	Write-Host "Disk $lunName has $pathCount paths and policy of $mPathPolicy."
}


Output:
Disk vmhba0:0:0 has 1 paths and policy of mru.






PowerShell MVP, VI Toolkit forum moderator
Author of the upcoming book: Managing VMware Infrastructure with PowerShell
Co-Host, PowerScripting Podcast (http://powerscripting.net)
Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org

Re: scripting esxcfg-mpath -l results

3. Nov 21, 2008 6:00 AM in response to: steve31783
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
My bad. The previous script didn't account for multiple ESX servers because at the time I was only hooked up to one and I didn't get a lot of sleep the night before. :) Here is a version which accepts VMhost info on the pipeline. However, there needs to be some filtering for inapplicable disks.

filter Get-VMHostMpath {
	$hostview = $_ | Get-View
	$VMHostName = $_.Name
	$mPathLun = $hostview.Config.StorageDevice.MultipathInfo.Lun
	foreach ( $lun in $mPathLun ) {
		$lunName = $lun.Id
		$pathCount = $lun.Path.Length
		$mPathPolicy = $lun.Policy.Policy
		Write-Host -foregroundcolor Yellow "Host server: $VMHostName"
		Write-Host "Disk $lunName has $pathCount paths and policy of $mPathPolicy."
	}
}


Usage:
PS > . .\filename.ps1 # you have to dot-source to make the function available in the current scope
PS > Get-VMHost | Get-VMHostMpath
Host server: phatlesx02.qatest.iss.net
Disk 02001f0000600a0b800026f1c20000000000000000556e69766572 has 2 paths and policy of PSP_MRU.






PowerShell MVP, VI Toolkit forum moderator
Author of the upcoming book: Managing VMware Infrastructure with PowerShell
Co-Host, PowerScripting Podcast (http://powerscripting.net)
Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org

Re: scripting esxcfg-mpath -l results

6. Nov 21, 2008 5:09 PM in response to: steve31783
Click to view LucD's profile Champion 2,443 posts since
Oct 31, 2005
I was intrigued by the challenge.
Attached my attempt at emulating the esxcfg-mpath -l command.

There are some points that are not the there:
1) the PCI address of the HBA for a local disk is apparently stored in hex but displayed in decimal (I think).
My script displays the PCI address as it is stored (hex)
2) the diskname (/dev) is a name that is apparently not present in any of the SDK properties.
My script doesn't display this.
$esx = Get-VMHost -Name <esx-hostname> | Get-View
foreach($disk in $esx.Config.StorageDevice.ScsiLun){
  foreach($lun in $esx.Config.StorageDevice.MultipathInfo.Lun){
    if($disk.CanonicalName -eq $lun.Id){
	  $pathNumber = $lun.Path.Count
	  $policyName = $lun.Policy.Policy
	  $capacityMb = ($disk.Capacity.Block * $disk.Capacity.BlockSize) / 1Mb
# Disk line
	  $line = "Disk " + $disk.CanonicalName + " (" + $capacityMb + "MB) has " + $pathNumber + " paths and policy of " + $policyName
        Write-Host $line
# Path line(s)
      $preferredPath = $lun.Policy.Prefer
	  foreach($path in $lun.Path){
	    $device = $disk.CanonicalName.Substring(0,$disk.CanonicalName.IndexOf(":"))
		foreach($hba in $esx.Config.StorageDevice.HostBusAdapter){
		  if($hba.Device -eq $device){break}
		}
		if($path.Name -eq $preferredPath){$preferred = "preferred"}
		else{$preferred = ""} 
		switch($path.PathState){
		  "active" {$pathStatus = "On active"}
		  "disabled" {$pathStatus = "Off"}
		  "standby" {$pathStatus = "On"}
                 default {$pathStatus = "unknown"}
		}
		switch($path.Transport.gettype().Name){
	          "HostParallelScsiTargetTransport" {
	            $line = " Local " + $hba.Pci + " " + $path.Name + " " + $pathStatus + " " + $preferred
	          }
	          "HostInternetScsiTargetTransport" {
		    $line = " iScsi sw " + $hba.IScsiName + " <-> " + $path.Transport.IScsiName + " " + $pathStatus + " " + $preferred
		  }
	        }
		Write-Host $line
	    }
	    break
	}
  }

The script, in this format, only handles 1 ESX server at the time but it can easily be converted to a filter.
Attachments:

Re: scripting esxcfg-mpath -l results

8. Nov 21, 2008 5:24 PM in response to: steve31783
Click to view LucD's profile Champion 2,443 posts since
Oct 31, 2005
Same thing Hal did with his script.
Instead of a standalone script you create a filter.
That way you can "pipe" objects to it.
The filter will be called for each object you place in the pipe.
The object can be accessed in the filter through the $_ variable.

Something like this
filter MyEsxcfgMpath {
  $esx = Get-VMHost -Name $_.Name | Get-View
  foreach($disk in $esx.Config.StorageDevice.ScsiLun){
  ....
}
# Call the filter for all your ESX servers
Get-VMHost | MyEsxcfgMpath

Re: scripting esxcfg-mpath -l results

9. Nov 29, 2008 12:02 AM in response to: LucD
Click to view datta123's profile Lurker 1 posts since
Nov 28, 2008

Is it possible to collect the information (in a single file) vcms point of view for all esx servers as below...I am using esx 3.5

How many vm machines are laying in the lun (lun wise information with vm machine names / ip & notes)

A lun mapped on multilple esx servers or not? what are they? (lun id and esx server ip / hostname)

What is the source and manufacturer of the lun (full storage partition info)

Thanks .............


Re: scripting esxcfg-mpath -l results

10. Dec 4, 2008 1:29 PM in response to: LucD
Click to view justin.emerson's profile Enthusiast 78 posts since
Jan 4, 2008

Hi guys,

One of the most useful scripts I've found is the following script to automatically Load Balance paths on an ESX server:
http://www.yellow-bricks.com/2008/04/01/load-balancing-activeactive-sans/

Is there a way to replicate this script in PowerShell that will apply to all servers in a cluster, and have it also keep the same path for LUNs across servers (i.e. If server 1 uses Path 2 to access LUN 3, Server 2 will also use Path 2 to get to LUN3)? This is important for arrays which have to transfer ownership (such as active/passive ones).

Thanks a bunch.


Re: scripting esxcfg-mpath -l results

11. Dec 4, 2008 3:08 PM in response to: justin.emerson
Click to view LucD's profile Champion 2,443 posts since
Oct 31, 2005
Did you have a look at Alternate multi-pathing ?
It points to Carter's blog entry that shows how to set the preferred path.

Re: scripting esxcfg-mpath -l results

12. Dec 4, 2008 3:52 PM in response to: datta123
Click to view halr9000's profile Master 814 posts since
Jun 7, 2007
datta123 wrote:
Is it possible to collect the information (in a single file) vcms point of view for all esx servers as below...I am using esx 3.5

It's very easy to do this sort of thing with powershell. Run your script or command and pipe it to set-content and give it a filename. Or, the old redirection symbol works too, e.g. "> lun.txt".

How many vm machines are laying in the lun (lun wise information with vm machine names / ip & notes)

Actually this one is hard to do because a datastore can have multiple LUNs. There is no direct relationship of VM to LUN. You can however, do VM to Datastore, and Datastore to LUN.

A lun mapped on multilple esx servers or not? what are they? (lun id and esx server ip / hostname)

Mess with Get-Datastore.







PowerShell MVP, VI Toolkit forum moderator
Author of the upcoming book: Managing VMware Infrastructure with PowerShell
Co-Host, PowerScripting Podcast (http://powerscripting.net)
Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org

Re: scripting esxcfg-mpath -l results

13. Jun 6, 2009 12:53 PM in response to: LucD
Click to view LucD's profile Champion 2,443 posts since
Oct 31, 2005
The first version of the script was missing FC paths.
It is now included.
The script still misses the instructions to handle block adapters but since I don't have access to that type of adapter I leave this open for now.
$esx = Get-VMHost -Name <ESX-hostname> | Get-View
foreach($disk in $esx.Config.StorageDevice.ScsiLun){
	foreach($lun in $esx.Config.StorageDevice.MultipathInfo.Lun){
		if($disk.CanonicalName -eq $lun.Id){
			$pathNumber = $lun.Path.Count
			$policyName = $lun.Policy.Policy
			$capacityMb = ($disk.Capacity.Block * $disk.Capacity.BlockSize) / 1Mb
			# Disk line
			$line = "Disk " + $disk.CanonicalName + " (" + $capacityMb + "MB) has " + $pathNumber + " paths and policy of " + $policyName
			Write-Host $line
			# Path line(s)
			$preferredPath = $lun.Policy.Prefer
			foreach($path in $lun.Path){
				$device = $disk.CanonicalName.Substring(0,$disk.CanonicalName.IndexOf(":"))
				foreach($hba in $esx.Config.StorageDevice.HostBusAdapter){
					if($hba.Device -eq $device){break}
				}
				if($path.Name -eq $preferredPath){$preferred = "preferred"}
				else{$preferred = ""} 
				switch($path.PathState){
					"active" {$pathStatus = "On active"}
					"disabled" {$pathStatus = "Off"}
					"standby" {$pathStatus = "On"}
					default {$pathStatus = "unknown"}
				}
				switch($path.Transport.gettype().Name){
				    "HostFibreChannelTargetTransport" {
						$line = " FC " + $hba.Pci + " " + [convert]::ToString($hba.PortWorldWideName,16) + " <-> " + [convert]::ToString($path.Transport.PortWorldWideName,16) + " " + $path.Name + " " + $pathStatus + " " + $preferred
					}
					"HostParallelScsiTargetTransport" {
						$line = " Local " + $hba.Pci + " " + $path.Name + " " + $pathStatus + " " + $preferred
					}
					"HostInternetScsiTargetTransport" {
						$line = " iScsi sw " + $hba.IScsiName + " <-> " + $path.Transport.IScsiName + " " + $pathStatus + " " + $preferred
					}
				}
				Write-Host $line
			}
			break
		}
	}
}
Attachments:

Re: scripting esxcfg-mpath -l results

14. Jun 9, 2009 1:56 AM in response to: LucD
Click to view gboskin's profile Hot Shot 206 posts since
Nov 19, 2008

As usual nice work LuCd ..any chance of exporting into HTML file ..

:8}

VMware Developer

SDKs, APIs, Videos, Learn and much more in the Developer community.

Learn More

Developer Sample Code

Increase your developer productivity with VMware API sample code.

Learn More

VMworld Sessions & Labs

Online access to the latest VMworld Sessions & Labs and online services.

Learn more

Purchase PSO Credits Online

Purchase credits to redeem training and consulting services online.

Buy Now

Community Hardware Software

View reported configurations or report your own.

Learn More

VMware vSphere

Come witness the next giant leap in virtualization.

Register Today

Communities