List HBA WWPNs and LUNs using Powershell

Lately I’m moving around my VMs and storage luns between my ESX clusters a lot to accomplish a complete redesign of my Virtual Infrastructure. At some point I got lost and didn’t had the complete overview anymore. Which luns were attached to which cluster? To remove(unpresent) a lun from an ESX host/cluster on the storage box the only identifier that I could count on was the lun serialnumber, which is part of the lun UUID.To help myself out I created two Powershell scripts, that I want to share with you.

Powershell Script 1

This script creates an overview of the luns attached to each ESX cluster. The script assumes that all ESX hosts in the cluster are equally configured on the san and lists only the luns attached to the first ESX host in each cluster. The script lists the lunname/scsi_id, the lunUUID, its size in GB and the datastore partition it contains. If the lun is an RDM, it will show the VM name and harddisk label.

#Initialize variables
$VCServer = "vcserver.yourdomain.local"
$objLuns = @()
$objRDMs = @()

#Connect to vCenter Server
Connect-VIServer $VCServer

$clusters = Get-cluster

foreach ($cl in $clusters) {
    $clv = $cl | Get-View
    if ($clv.Host.count -gt 0) {
        #assume that all ESX hosts see the same luns
        $vmhost = get-view $[0]
        #Get ScsiLuns except local storage
        $ScsiLuns = $vmhost.Config.StorageDevice.ScsiLun  | ? {$_.canonicalname -notmatch "vmhba0"}
        #Get Datastore volumes
        $Datastores = $vmhost.Config.FileSystemVolume.MountInfo
        foreach ($Lun in $ScsiLuns) {
            #Define Custom object
            $objVolume = "" | Select ClusterName,LunName,LunUuid,Lunsize,VolumeName

            #Add porperties to the newly created object
            $objVolume.ClusterName = $clv.Name
            $objVolume.LunName = $Lun.CanonicalName
            $objVolume.LunUuid = $Lun.Uuid
            $objVolume.LunSize = $Lun.Capacity.Block * $Lun.Capacity.BlockSize / 1GB

            foreach ($vol in $Datastores | % {$_.volume}) {
                if ($vol.extent | % {$_.diskname -eq $Lun.CanonicalName}) {
                    $objVolume.VolumeName = $vol.Name
            $objLuns += $objVolume

    #RDM information
    $vms = $cl | Get-VM  | Get-View
    if ($null -ne $vms) {
        foreach($vm in $vms){
            foreach($dev in $vm.Config.Hardware.Device){
                if(($dev.gettype()).Name -eq "VirtualDisk"){
                    if(($dev.Backing.CompatibilityMode -eq "physicalMode") -or
                        ($dev.Backing.CompatibilityMode -eq "virtualMode")){
                        $rdm = "" | select VMName, LunUuid, DiskLabel
                        $rdm.VMName = $vm.Name
                        $rdm.LunUuid = $dev.Backing.LunUuid
                        $rdm.DiskLabel = $dev.DeviceInfo.Label
                        $objRDMs += $rdm

foreach ($rdm in $objRDMs) {
    foreach ($disk in $objLuns) {
         if ($disk.LunUuid -eq $rdm.LunUuid) {$disk.VolumeName = $rdm.VMName + "/" + $rdm.DiskLabel}

$objLuns | Export-Csv ScsiLunSN.csv

Disconnect-VIServer -Confirm:$false


Powershell Script 2

This script creates a simple overview of all HBA WWPNs for each cluster. This way you can check your storagebox / SAN configuration if it matches the ESX cluster configuration.

#Initialize variables
$VCServer = "vcserver.yourdomain.local"
$objHba = @()

#Connect to vCenter Server
Connect-VIServer $VCServer

$clusters = Get-cluster

foreach ($cluster in $clusters) {
    $vmhosts = $cluster | Get-vmhost
    if ($null -ne $vmhosts) {
        foreach ($vmhost in $vmhosts) {
            $vmhostview = $vmhost | Get-View
            foreach ($hba in $vmhostview.config.storagedevice.hostbusadapter) {
                if ($hba.PortWorldWideName) {
                    #Define Custom object
                    $objWwpn = "" | Select Clustername,Hostname,Hba,Wwpn
                    #Add porperties to the newly created object
                    $objWwpn.ClusterName = $cluster.Name
                    $objWwpn.HostName = $vmhost.Name
                    $objWwpn.Hba = $hba.Device
                    $objWwpn.Wwpn = "{0:x}" -f $hba.PortWorldWideName
                    $objHba += $ObjWwpn

$objHba | Export-Csv Get-Hba.csv

Disconnect-VIServer -Confirm:$false

Remember to test the scripts thoroughly before using it in your production environment, as I can take no responsibility for whatever happens to your environment using these scripts.

Related posts:

  1. Reconnect ESX hosts using PowerShell Tweet This week I ran into problems with vCenter server and almost all of my VMs were orphaned in vCenter. To resolve this issue I needed to disconnect/connect each ESX...
  2. Export and import customization profiles using Powershell Tweet One great thing in the automation of VM deployments is the use of customization profiles. These profiles are stored inside the vCenter Server database. However, when you loose the...
  3. New version of the Powershell Healthcheck script released Tweet Ivo Beerens published a new version of his Powershell Healthcheck script. Features: - VMware ESX server Hardware and version          - VMware vCenter version     - Cluster information (Updated)    ...
  4. Bulk change your ESX root password Tweet Have you ever been facing your security department demanding you to change your ESX root password? Well I did. At the current site there’s a strict security policy where...
  5. VMware Storage Sudoku Tweet Last Friday I was brainstorming with Gabrie van Zanten about the optimal placement of the VMDKs across our LUNs. We tried to come up with an algorithm that could...

8 Comments on “List HBA WWPNs and LUNs using Powershell”

  1. #1 Mark
    on Oct 27th, 2009 at 7:54 pm

    Script 1 is very helpful as I have a similar project I am working on too.

    Any idea how I can add the HOST LUN ID to this list? ie LUN0, LUN1, etc…

  2. #2 Sandra B.
    on Jan 19th, 2010 at 3:28 pm

    Great Help ! Thanks a lot !

  3. #3 Ty Lopes
    on Mar 8th, 2010 at 11:45 pm

    This is exactly what I was looking for, thank you for posting it!!!

  4. #4 Oscar C.
    on Mar 8th, 2011 at 6:10 pm

    Excellent script, very useful, the storage people will be pleased!! thanks

  5. #5 Osama
    on Mar 18th, 2011 at 11:51 pm

    Great script, Thanks for your VMware PS insight. I was looking to collect similar information, but I have not been able to get the LUN extension. We have some LUN that were extended several times, I want to identify any of these LUN using PS, but I have not been able to.

    Do you know how to retrieve the LUN extension info?

  6. #6 John
    on Aug 24th, 2011 at 3:35 pm

    script 2 worked great, thanks
    can you go thru each line and defipher it?
    Also saving it as a ps1 file it would not run correctly, I had to copy it line by line

  7. #7 Parvez Kasmani
    on Oct 7th, 2011 at 6:07 pm

    What modifications I would have to make to the above script to work on hyper-V cluster. its giving me error message on not recognized.

    If you can modify your script for hyper-V cluster and send it to me that would be appreciated.


  8. #8 CB
    on Jun 22nd, 2012 at 3:47 pm

    Yes, I too would like to see a variation to run in a Hyper-V environment.

Leave a Comment