Check Paths on FC-HBA’s

Check Paths on FC-HBA’s

Often you have to check the paths on your hosts.

At least if you upgrade your UCS or SAN infrastructure 😉 Do it with PowerCLI!

I spent a big amount of time last week doing research on this topic, doing these checks with PowerCLI.

I just wanted to see (per host) which HBA has it’s paths to his storage (like in the vSphere Client):

There are lots of approaches for this.

jfrmilner: Check for “Dead” paths on HBAs with PowerCLI

or this performance optimized version practical-admin.com: PowerCLI: Show HBA Path Status

But every script I found was displaying incorrect path numbers. They all made the same mistake, counting the paths from datastore side. If you want to get the same result as in vSphere client, you should have a look on my script.

So I had to find my way …

At this point there goes a big thank you to “PowerCLI God” LucD 😉

Finally I came up with a script that does exactly what I have imagined:

 

function Get-FCPaths
{
  <#
      .SYNOPSIS
      It shows the HBA's with it's Paths (Active,Dead,Standby)
      .DESCRIPTION
      You can check a single Host, a Cluster or even a DataCenter to show it's HBA's and their paths.
      It's tested with Cisco UCS Blades including VIC Cards and QLogic FC HBA's in Dell Hosts.
      Check the Driver Name (and edit in Line 75) in case of trouble.
      .EXAMPLE

      Get-FCPaths -vHost myHost-01

      Get-FCPaths -vHost myHost-*

      Get-FCPaths -Cluster myCluster

      Get-FCPaths -DataCenter myDataCenter

     .EXAMPLE Output

      VMHost  Device Active Standby Dead
      ------  ------ ------ ------- ----
      Host-01 vmhba1      0       0    4
      Host-01 vmhba2      4       0    0

   #>
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory=$false, Position=0)]
    [System.String]
    $vHost = "",
    
    [Parameter(Mandatory=$false, Position=1)]
    [System.String]
    $Cluster = "",
    
    [Parameter(Mandatory=$false, Position=2)]
    [System.String]
    $DataCenter = ""
  )
  
  #Check which Variable is filled
  if([string]::IsNullOrEmpty($vHost)) {            
    #Write-Host "Given string is NULL or EMPTY"
    
  } else {            
    #Write-Host "Set vobject" 
    $vobject = (Get-VMHost $vHost)  | Sort-Object -Property Name              
  }
  
  if([string]::IsNullOrEmpty($Cluster)) {            
    #Write-Host "Given string is NULL or EMPTY"  
  } else {            
    #Write-Host "Set vobject" 
    $vobject = (Get-Cluster $Cluster| Get-VMHost)  | Sort-Object -Property Name            
  }
  
  if([string]::IsNullOrEmpty($DataCenter)) {            
    #Write-Host "Given string is NULL or EMPTY"
    
  } else {            
    #Write-Host "Set vobject"
    $vobject = (Get-DataCenter $DataCenter| Get-VMHost)  | Sort-Object -Property Parent,Name              
  }
  
  
  
  foreach($vmhost in ($vobject)){
    
    $esx = Get-VMHost -Name $vmhost
    $report = @()
    # fc or fnic for UCS VIC-Cards
    foreach($hba in ($esx.ExtensionData.Config.StorageDevice.HostBusAdapter | where{$_.Driver -match 'fc' -or  $_.Driver -match 'fnic'})){
      $paths = @()
      foreach($lun in $esx.ExtensionData.Config.StorageDevice.MultipathInfo.Lun){
        $paths += $lun.Path | where{$_.Adapter -match "$($hba.Device)" -and $_.Adapter -match 'FibreChannel'}
      }
      $groups = $paths | Group-Object -Property PathState
      $report += $hba | Select @{N='VMHost';E={$esx.Name}},Device,
      @{N='Active';E={($groups | where{$_.Name -eq 'active'}).Count}},
      @{N='Standby';E={($groups | where{$_.Name -eq 'standby'}).Count}},
      @{N='Dead';E={($groups | where{$_.Name -eq 'dead'}).Count}}
    }
    Write-Host "Cluster: "$vmhost.Parent
    $report | ft -AutoSize
    
  }
}

The output should look like this:

PS C:\Users\myuser> Get-FCPaths -Cluster MyCluster-0*
Cluster:  MyCluster-01

VMHost  Device Active Standby Dead
------  ------ ------ ------- ----
Host-01 vmhba3      2       1    0
Host-01 vmhba4      3       0    0


Cluster:  MyCluster-01

VMHost  Device Active Standby Dead
------  ------ ------ ------- ----
Host-02 vmhba3      2       1    0
Host-02 vmhba4      3       0    0


Cluster:  MyCluster-02

VMHost  Device Active Standby Dead
------  ------ ------ ------- ----
Host-03 vmhba1      2       0    0
Host-03 vmhba2      2       0    0


Cluster:  MyCluster-02

VMHost  Device Active Standby Dead
------  ------ ------ ------- ----
Host-04 vmhba1      2       0    0
Host-04 vmhba2      2       0    0

UPDATE:

There is a cosmetic issue in ESXi 6.0 U3! See VMware KB 2149992

This causes a wrong number of active paths shown.

UPDATE2:

It works correctly again with ESXi 6.5 U1 🙂

14 thoughts on “Check Paths on FC-HBA’s

    1. Check Line 75, there is a where condition that maybe does not fit to your environment. You can troubleshoot if you check the output of: $esx.ExtensionData.Config.StorageDevice.HostBusAdapter

      1. Tried that too….still blank output….moreover it start and ends withing a second, so probably script is not even triggering

        1. Did you execute the function and call it afterwards? Like
          Get-FCPaths -vHost myHost-*
          If still empty, just query the two lines:
          $esx = Get-VMHost -Name yourESXiHost
          $esx.ExtensionData.Config.StorageDevice.HostBusAdapter

          The output is maybe huge(depends on your adapter counts), you have to search your FC- HBA and look what is beside “Drivers”

          In my case it’s a Qlogic HBA -> “qlnativefc”

          1. For me getting blank output. Please help

            .\Get-FCPaths.ps1 -DataCenter “mydc”

  1. Hello Chris , there is a cosmetic problem as per kb 2149992 as ur aware which i think may not have any resolution sooner ,
    i figured out an alternative while i was testing VMware powercli vs esxcli , i found esxcli output are fine , that is when i researched to find to esxcli in powercli
    here’s what i did ..
    $AllHosts = Get-VMHost
    $esxcli = Get-EsxCli -VMhost $AllHosts -V2
    $esxcli.storage.core.path.list.invoke()| select DeviceDisplayName,Adapter , State

    Out put simillar to
    output simillar to
    XX Fibre Channel Disk (naa.6012334892749287487290934098.. vmhba4 active
    XX Fibre Channel Disk (naa.6883482740872472742797297948… vmhba64 active

    now that am able to the state info , how can i use in your script and get the resultant output , please help .. thank you

    1. Hey, did you really get the correct information about the standby and active paths? As I mentioned, it works again with 6.5. I see no reasons to change that script.

    1. Sure, you add “| ConvertTo-Csv”

      Maybe something like:
      Get-FCPaths -DataCenter [myDatacenter] | ConvertTo-Csv

Leave a Reply

Your email address will not be published. Required fields are marked *

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