14 Replies Latest reply on Jun 9, 2009 1:56 AM by gboskin

    scripting esxcfg-mpath -l results

    steve31783 Hot Shot

       

      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? 

       

       

        • 1. Re: scripting esxcfg-mpath -l results
          halr9000 Master

          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|https://mvp.support.microsoft.com/profile=5547F213-A069-45F8-B5D1-17E5BD3F362F], 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

          1 person found this helpful
          • 2. Re: scripting esxcfg-mpath -l results
            steve31783 Hot Shot

             

            Hey Hal..

             

            Appreciate the help... I just ran that script, but the output returns as

             

             

             

             

             

            "Disk  has  paths and polict of ."

             

             

            Seems as though there's no values assigned to the variables.

             

             

             

             

             

            My PS/Vi toolkit knowledge is limited but im going to try to work on this to see if I can make something of it... if you have any suggestions, then by all means please let me know...

             

             

             

             

             

            $hostview = Get-Cluster "Tier2 (Dev)" | 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."

            }

             

             

             

             

             

            • 3. Re: scripting esxcfg-mpath -l results
              halr9000 Master

              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|https://mvp.support.microsoft.com/profile=5547F213-A069-45F8-B5D1-17E5BD3F362F], 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

              • 4. Re: scripting esxcfg-mpath -l results
                steve31783 Hot Shot

                 

                Awesome thanks, ill take a look!!!

                 

                 

                 

                 

                 

                Here's what me and a colleague have been working on..... probably not very clean looking to you, but it's getting there.

                 

                 

                 

                 

                 

                 

                 

                 

                $outfile = "C:\Inetpub\wwwroot\multipath.htm"

                 

                 

                 

                "<table border=`"1`">" > $outfile

                "<tr>" >> $outfile

                "<th bgcolor=`"#BDBDBD`">VM Host Name</th>" >> $outfile

                "<th bgcolor=`"#BDBDBD`">Lun Name</th>" >> $outfile

                "<th bgcolor=`"#BDBDBD`">Path Count</th>" >> $outfile

                "<th bgcolor=`"#BDBDBD`">Multipath Policy</th>" >>$outfile

                "</tr>" >> $outfile

                 

                 

                 

                foreach ($esx in get-cluster "Tier2 (Dev)" | get-vmhost |  sort-object -property Name ) {

                $hostview = Get-VMHost $esx.name | get-view

                $mPathLun = $hostview.Config.StorageDevice.MultipathInfo.Lun

                 

                 

                 

                "<tr><td align=`"center`" bgcolor=`"red`">" + $esx.name + "</td>" >> $outfile

                "</tr><tr>" >> $outfile

                foreach ( $lun in $mPathLun ) {

                   $lunName = $lun.Id

                   $pathCount = $lun.Path.Length

                   $mPathPolicy = $lun.Policy.Policy

                   "<td></td>" >> $outfile

                    "<td align=`"center`">" + $lunname + "</td><td align=`"center`">" + $pathCount + "</td><td align=`"center`">" + $mPathPolicy + "</td></tr>" >> $outfile

                   #"Disk $lunName has $pathCount paths and policy of $mPathPolicy." >> $outfile

                 

                 

                }

                }

                 

                 

                "<tr><td COLSPAN=2 bgcolor=`"#BDBDBD`">" + $date + "</td><td COLSPAN=2 bgcolor=`"#BDBDBD`"></td></tr>" >> $outfile

                "</table>" >> $outfile

                 

                 

                • 5. Re: scripting esxcfg-mpath -l results
                  steve31783 Hot Shot

                  Hey Hal..

                   

                  If I also wanted to display the disks name (\dev\sdi) and size, what would I use to put into those variables?

                   

                   

                  ie.

                   

                   

                  $diskname = needyourhelphere

                   

                   

                  $disksize = needyourhelphere

                   

                   

                   

                   

                   

                   

                   

                   

                  If it's easy to explain to me how I can look at these properties to see what attributed I can use, please let me know so I can stop bugging you!! There's a few things I might want to add like WWN of the SP/port on the active path, so once I know where this all is I should be able to figure it out. Thanks for the help.

                  • 6. Re: scripting esxcfg-mpath -l results
                    LucD Guru
                    User ModeratorsvExpertCommunity Warriors

                    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.

                    • 7. Re: scripting esxcfg-mpath -l results
                      steve31783 Hot Shot

                       

                      Forgive me for asking a stupid question, but what do you mean by it can be converted to a filter?

                       

                       

                      Thanks for your effort in looking into this... I appreciate the help.

                       

                       

                      • 8. Re: scripting esxcfg-mpath -l results
                        LucD Guru
                        Community WarriorsvExpertUser Moderators

                        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
                        

                         

                        1 person found this helpful
                        • 9. Re: scripting esxcfg-mpath -l results
                          datta123 Lurker

                           

                          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 .............

                           

                           

                           

                           

                           

                          • 10. Re: scripting esxcfg-mpath -l results
                            justin.emerson Enthusiast

                             

                            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.

                             

                             

                             

                             

                             

                            • 11. Re: scripting esxcfg-mpath -l results
                              LucD Guru
                              Community WarriorsvExpertUser Moderators

                              Did you have a look at  Alternate multi-pathing ?

                              It points to Carter's blog entry that shows how to set the preferred path.

                              • 12. Re: scripting esxcfg-mpath -l results
                                halr9000 Master
                                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|https://mvp.support.microsoft.com/profile=5547F213-A069-45F8-B5D1-17E5BD3F362F], 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

                                • 13. Re: scripting esxcfg-mpath -l results
                                  LucD Guru
                                  User ModeratorsCommunity WarriorsvExpert

                                  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
                                            }
                                       }
                                  }
                                  

                                   

                                  • 14. Re: scripting esxcfg-mpath -l results
                                    gboskin Hot Shot

                                     

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