VMware Cloud Community
CannibalDuck
Contributor
Contributor
Jump to solution

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

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

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

            }

        }

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

10 Replies
LucD
Leadership
Leadership
Jump to solution

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?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

CannibalDuck
Contributor
Contributor
Jump to solution

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 Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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 :smileygrin:


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
CannibalDuck
Contributor
Contributor
Jump to solution

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 Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

        }

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
CannibalDuck
Contributor
Contributor
Jump to solution

Got the plan. LOTS OF HASH TABLES Smiley Happy

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? Smiley Happy

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 Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

            }

        }

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

CannibalDuck
Contributor
Contributor
Jump to solution

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 Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Is it working now?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
CannibalDuck
Contributor
Contributor
Jump to solution

Yes. Thank you very much for your help Smiley Happy

Reply
0 Kudos