10 Replies Latest reply on Nov 9, 2017 7:16 AM by CannibalDuck

    Find a datastore, canonical name and runtime having just a LUN Id

    CannibalDuck Lurker

      I need help. I'm trying to make a "translator script" for our network engineers, so they can find most wanted LUN details for them.

      Plan is simple: we know LUN Id (simple digits in the LUN column), and by knowing this, we must find NAA (canonical name), runtime name (ldev is kinda important), RDM (what virtual machine have this LUN) and datastore.

      ATM im trying to use this script (thank you, LucD):

       

      foreach ($clusterName in Get-Cluster) {

      $report += Get-Cluster -Name $clusterName | Get-VMHost | %{

          $esxcli = Get-EsxCli -VMHost $_

          $esxcli.storage.core.device.list() |

          Select @{N='ESX';E={$esxcli.VMHost.Name}},Device,

            @{N='lunID'; E={

              $d = $_

              if(([Version]$esxcli.VMHost.Version).Major -lt 6){

                $lun = Get-ScsiLun -VmHost $esxcli.VMhost | Where {$_.CanonicalName -eq $d.Device}

                $runtime = $lun.RuntimeName

              }

              else{

                $lun = $esxcli.VMHost.ExtensionData.Config.StorageDevice.ScsiLun | Where-Object{$_.CanonicalName -eq $d.Device}

                $lunUuid = $lun.Uuid

                $runtime = ($esxcli.VMHost.ExtensionData.Config.StorageDevice.MultipathInfo.Lun | Where-Object{$_.Id -eq $lunUuid}).Path[0].Name

              }

              $runtime.Split('L')[1]

              }}      

      }

      }

      $report

       

      But it's rly slow, because it's trying to do with every host.. And if i'll try to search the datastores, it will take forever.. But anyway. I need help with this task. How can I find all I want, knowing just LUN Id? This task is hard for me.

      P.S. Powercli version 6.5

        • 1. Re: Find a datastore, canonical name and runtime having just a LUN Id
          LucD Guru
          Community WarriorsUser ModeratorsvExpert

          You can use a hash table to lookup datastorenames via the canonicalname.

          Something like this

           

          $report = @()

           

          $dsTab = @{}

          foreach($ds in (Get-Datastore | where{$_.ExtensionData.Summary.MultipleHostAccess})){

              $ds.ExtensionData.Info.Vmfs.Extent | %{

                  if($_.DiskName){

                      $dsTab.Add($_.DiskName,$ds.Name)

                  }

              }

          }

           

          foreach ($clusterName in Get-Cluster) {

          $report += Get-Cluster -Name $clusterName | Get-VMHost | %{

              $esxcli = Get-EsxCli -VMHost $_

              $esxcli.storage.core.device.list() |

              Select @{N='ESX';E={$esxcli.VMHost.Name}},Device,

                @{N='lunID'; E={

                  $d = $_

                  if(([Version]$esxcli.VMHost.Version).Major -lt 6){

                    $lun = Get-ScsiLun -VmHost $esxcli.VMhost | Where {$_.CanonicalName -eq $d.Device}

                    $runtime = $lun.RuntimeName

                  }

                  else{

                    $lun = $esxcli.VMHost.ExtensionData.Config.StorageDevice.ScsiLun | Where-Object{$_.CanonicalName -eq $d.Device}

                    $lunUuid = $lun.Uuid

                    $runtime = ($esxcli.VMHost.ExtensionData.Config.StorageDevice.MultipathInfo.Lun | Where-Object{$_.Id -eq $lunUuid}).Path[0].Name

                  }

                  $runtime.Split('L')[1]

                  }},

                @{N='Datastore';E={$dsTab[$_.Device]}}       

          }

          }

           

          $report

           

          But note that this will only cover datastores, not RDMs.

          Perhaps you could have a look at my LUN Report – Datastore, RDM And Node Visibility post?

          • 2. Re: Find a datastore, canonical name and runtime having just a LUN Id
            CannibalDuck Lurker

            For RDM I can use a oneliner to make another hash table.

            get-datacenter | Get-VM | Get-HardDisk -DiskType "RawPhysical","RawVirtual"

            is it fine or there's a better way?

            And finally via CNAME I can find runtimename by get-scsilunpath..

            Will try it

            • 3. Re: Find a datastore, canonical name and runtime having just a LUN Id
              LucD Guru
              Community WarriorsUser ModeratorsvExpert

              No, hash table is fine.

               

              Not quite sure what you mean by the CNAME, that is a DNS concept for me, but I'm probably missing something there

              • 4. Re: Find a datastore, canonical name and runtime having just a LUN Id
                CannibalDuck Lurker

                Ok, I think I can make a huge table with all data I need and then just select.

                 

                But I want to know one more thing. Luc, is there a way to get LUN info, if you have only ID or RuntimeName like vmhba2:C0:T0:L58?

                 

                *CNAME - just short canonical name

                • 5. Re: Find a datastore, canonical name and runtime having just a LUN Id
                  LucD Guru
                  Community WarriorsvExpertUser Moderators

                  That info is available and can be stored in a couple of hash tables.

                  Something like this for example.
                  Note that this needs to be expanded (the $pathTab hash table), when a LUN has multiple paths.

                  Now the script only takes the first available path

                   

                  $esxName = 'MyEsx'

                  $esx = Get-VMHost -Name $esxName

                   

                  $adapterTab = @{}

                  $esx.ExtensionData.Config.StorageDevice.HostBusAdapter | %{

                      $adapterTab.Add($_.Key,$_.Device)

                  }

                   

                  $pathTab = @{}

                  $esx.ExtensionData.Config.StorageDevice.MultipathInfo.Lun | %{

                      $pathTab.Add($_.Lun,$_.Path[0].Name)

                  }

                   

                  $lunTab = @{}

                  $esx.ExtensionData.Config.StorageDevice.ScsiLun | %{

                      $lunTab.Add($_.Key,$_.CanonicalName)

                  }

                   

                  foreach($adapter in $esx.ExtensionData.Config.StorageDevice.ScsiTopology.Adapter){

                      foreach($target in $adapter.Target){

                          foreach($lun in $target.Lun){

                              $lun | Select @{N='Adapter';E={$adapterTab[$adapter.Adapter]}},

                                          @{N='Canonical';E={$lunTab[$lun.ScsiLun]}},

                                          @{N='Path';E={$pathTab[$lun.ScsiLun]}},

                                          Lun

                          }

                      }

                  }

                   

                  • 6. Re: Find a datastore, canonical name and runtime having just a LUN Id
                    CannibalDuck Lurker

                    Got the plan. LOTS OF HASH TABLES

                    Big thanks for help.

                    *UPD. Need more help, please.

                    So with this script

                     

                    $adapterTab = @{}

                    $pathTab = @{}

                    $lunTab = @{}

                    $dsTab = @{}

                    foreach($ds in (Get-Datastore | where{$_.ExtensionData.Summary.MultipleHostAccess})){

                        $ds.ExtensionData.Info.Vmfs.Extent | %{

                            if($_.DiskName){

                                $dsTab.Add($_.DiskName,$ds.Name)

                            }

                        }

                    }

                     

                     

                    foreach ($esx in Get-VMHost){

                     

                     

                     

                     

                    $esx.ExtensionData.Config.StorageDevice.HostBusAdapter | %{

                        $adapterTab.Add($_.Key,$_.Device)

                    }

                     

                     

                     

                    $esx.ExtensionData.Config.StorageDevice.MultipathInfo.Lun | %{

                        $pathTab.Add($_.Lun,$_.Path.Name)

                    }

                     

                     

                     

                    $esx.ExtensionData.Config.StorageDevice.ScsiLun | %{

                        $lunTab.Add($_.Key,$_.CanonicalName)

                    }

                     

                    foreach($adapter in $esx.ExtensionData.Config.StorageDevice.ScsiTopology.Adapter){

                        foreach($target in $adapter.Target){

                            foreach($lun in $target.Lun){

                                $lun | Select @{N='ESX';E={$esx.Name}},

                                            @{N='Adapter';E={$adapterTab[$adapter.Adapter]}},

                                            @{N='Canonical';E={$lunTab[$lun.ScsiLun]}},

                                            @{N='Path';E={$pathTab[$lun.ScsiLun]}},

                                            Lun,

                                            @{N='Datastore';E={$dsTab[$lunTab[$lun.ScsiLun]]}}

                            }

                        }

                    }

                    }

                     

                    I get information I need. It search every host, and write expanded paths. Am I going right way, or I'm breaking gravity?

                    And one more question. How can I add RDMs in hash table?

                    $RDMS = get-datacenter | Get-VM | Get-HardDisk -DiskType "RawPhysical","RawVirtual"

                    $RDMS | %{$rdmTable.add($_.parent, $_.scsicanonicalname)}

                    isnt work, because I need pairs... It makes me mad

                    • 7. Re: Find a datastore, canonical name and runtime having just a LUN Id
                      LucD Guru
                      vExpertCommunity WarriorsUser Moderators

                      Try like this

                       

                      $dsTab = @{}

                       

                      foreach($ds in (Get-Datastore | where{$_.ExtensionData.Summary.MultipleHostAccess})){

                          $ds.ExtensionData.Info.Vmfs.Extent | %{

                              if($_.DiskName){

                                  $dsTab.Add($_.DiskName,$ds.Name)

                              }

                          }

                      }

                       

                      foreach ($esx in Get-VMHost){

                          $adapterTab = @{}

                          $pathTab = @{}

                          $lunTab = @{}

                          $rdmTab = @{}

                       

                          $esx.ExtensionData.Config.StorageDevice.HostBusAdapter | %{

                              $adapterTab.Add($_.Key,$_.Device)

                          }

                       

                          $esx.ExtensionData.Config.StorageDevice.MultipathInfo.Lun | %{

                              $pathTab.Add($_.Lun,$_.Path.Name)

                          }

                       

                          $esx.ExtensionData.Config.StorageDevice.ScsiLun | %{

                              $lunTab.Add($_.Key,$_.CanonicalName)

                          }

                       

                          foreach($rdm in (Get-VM -Location $esx | Get-HardDisk -DiskType RawPhysical,RawVirtual)){

                              if($rdm){

                                  $rdmTab.Add($rdm.ScsiCanonicalName,@{

                                                                  VM = $rdm.Parent.Name

                                                                  HD = $rdm.Name

                                                                })

                               }

                          }

                       

                          foreach($adapter in $esx.ExtensionData.Config.StorageDevice.ScsiTopology.Adapter){

                              foreach($target in $adapter.Target){

                                  foreach($lun in $target.Lun){

                                      $lun | Select @{N='ESX';E={$esx.Name}},

                                                  @{N='Adapter';E={$adapterTab[$adapter.Adapter]}},

                                                  @{N='Canonical';E={$lunTab[$lun.ScsiLun]}},

                                                  @{N='Path';E={$pathTab[$lun.ScsiLun]}},

                                                  Lun,

                                                  @{N='Datastore';E={$dsTab[$lunTab[$lun.ScsiLun]]}},

                                                  @{N='RDM';E={"$($rdmTab[$lunTab[$lun.ScsiLun]].VM) $($rdmTab[$lunTab[$lun.ScsiLun]].HD)"}}

                                  }

                              }

                          }

                      }

                       

                      • 8. Re: Find a datastore, canonical name and runtime having just a LUN Id
                        CannibalDuck Lurker

                        About

                        $RDMS = get-datacenter | Get-VM | Get-HardDisk -DiskType "RawPhysical","RawVirtual"

                        $RDMS | %{$rdmTable.add($_.parent, $_.scsicanonicalname)}

                        I just forgot, that the $_.key parameter must be equal. So

                        $RDMS | %{$rdmtab.add($_.scsicanonicalname, $_.parent)}

                        version is working.

                        More than 24h without sleeping is really bad. You can forgot all basics

                        • 10. Re: Find a datastore, canonical name and runtime having just a LUN Id
                          CannibalDuck Lurker

                          Yes. Thank you very much for your help