VMware Cloud Community
mlgurav
Contributor
Contributor
Jump to solution

Get lunpath information for specific number of LUNs input via text file

I am looking for a script which can take a list naa ids via text file as input and provide lun path information such as below in  an excel.

NameScsiLunIdScsiLunLunPathSanIdStatePreferredScsiCanonicalName

 

I have tried to modify multiple scripts, but somehow can't get getcontent to work with Get-ScsiLunPath command.

I have found Get-ScsiLunPath command to be very slow, is there any alternate way of doing it?

 

Also for path state, when checked from vSphere html client I could see it showing as Active (I/O), but none of the scripts I tried that output it like this. May be it's not possible to get it via powercli I guess. Any thoughts?

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try something like this

#Connect to vCenter Server
Connect-VIServer vcenter01
$scsiluns = Get-Content -Path "d:\script\lun.txt"

#Get list of ESXi Hosts
$esxihosts = Get-VMHost
$i = 0

$data = ForEach ($esxi in $esxihosts) {
    $i++
    Write-Progress -Activity "Scanning hosts" -Status ("Host: {0}" -f $esxi.Name) -PercentComplete ($i / $esxihosts.count * 100) -Id 0
    $k = 0
    ForEach ($scsilun in (Get-ScsiLun -CanonicalName $scsiluns -VmHost $esxi)) {
        $k++
        Write-Progress -Activity "Scanning Luns" -Status ("Lun: {0}" -f $scsilun.CanonicalName) -PercentComplete ($k / $scsiluns.count * 100) -Id 2
        $scsipaths = Get-ScsiLun -CanonicalName $scsilun -VmHost $esxi | Get-ScsiLunPath
        $l = 0
        ForEach ($scsipath in $scsipaths) {
            $l++
            Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}" -f $scsipath.Name) -PercentComplete ($l / $scsipaths.count * 100) -Id 3
            New-Object PSObject -Property @{
                Host                = $esxi.name
                HBAName             = $scsilun.RuntimeName
                PathSelectionPolicy = $scsilun.MultiPathPolicy
                Status              = $scsipath.state
                Source              = "{0}" -f ((("{0:x}" -f $hba.PortWorldWideName) -split '([a-f0-9]{2})' | where { $_ }) -Join ":")
                Target              = $scsipath.SanId
                LUN                 = (($scsilun.RunTimeName -Split "L")[1] -as [Int])
                LUNID               = $scsipath.ScsiCanonicalName
                Path                = $scsipath.LunPath
            }
        }
    }
}

$data | Export-Csv -NoTypeInformation 'ESXiStorageInfo.csv'


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

View solution in original post

0 Kudos
10 Replies
LucD
Leadership
Leadership
Jump to solution

What do you have already, and where does it not work?


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

0 Kudos
mlgurav
Contributor
Contributor
Jump to solution

This is what I am trying: doesn't give any output. The lun.txt file contains the list of naa ids.

 

#Connect to vCenter Server
Connect-VIServer vcenter01
$scsiluns = Get-Content -path "d:\script\lun.txt"

#Get list of ESXi Hosts
$esxihosts = Get-VMHost
$i=0


$data = ForEach ($esxi in $esxihosts) {
$i++
Write-Progress -Activity "Scanning hosts" -Status ("Host: {0}" -f $esxi.Name) -PercentComplete ($i/$esxihosts.count*100) -Id 0
#$hbas = $esxi | Get-VMHostHba
#$j=0
#ForEach ($hba in $hbas) {
# $j++
# Write-Progress -Activity "Scanning HBAs" -Status ("HBA: {0}" -f $hba.Device) -PercentComplete ($j/$hbas.count*100) -Id 1
# $scsiluns = $hba | Get-ScsiLun
# $k=0
ForEach ($scsilun in $scsiluns) {
$k++
Write-Progress -Activity "Scanning Luns" -Status ("Lun: {0}" -f $scsilun.CanonicalName) -PercentComplete ($k/$scsiluns.count*100) -Id 2
$scsipaths = $scsilun | Get-Scsilunpath -scsilun
$l=0
ForEach ($scsipath in $scsipaths) {
$l++
Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}" -f $scsipath.Name) -PercentComplete ($l/$scsipaths.count*100) -Id 3
New-Object PSObject -Property @{
Host = $esxi.name
HBAName = $scsilun.RuntimeName
PathSelectionPolicy = $scsilun.MultiPathPolicy
Status = $scsipath.state
Source = "{0}" -f ((("{0:x}" -f $hba.PortWorldWideName) -split '([a-f0-9]{2})' | where {$_}) -Join ":")
Target = $scsipath.SanId
LUN = (($scsilun.RunTimeName -Split "L")[1] -as [Int])
LUNID = $scsipath.ScsiCanonicalName
Path = $scsipath.LunPath
}
}
}
}
#}

$data | Export-Csv -NoTypeInformation 'ESXiStorageInfo.csv'

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can't just copy a script (that is not working btw) from a thread (see Path Status for Storage - VMware Technology Network VMTN).
I asked what YOU already have?


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

0 Kudos
mlgurav
Contributor
Contributor
Jump to solution

that script works but gives me details for all the luns in the estate and runs for four hours.  Hence I wanted to modify it to take some NAA ids as inputs using Get-Content if you compare the two iterations.

When I run the script against vcenter it gives me below error.

 

Get-ScsiLunPath : Missing an argument for parameter 'ScsiLun'. Specify a parameter of type 'VMware.VimAutomation.ViCore.Types.V1.Host.Storage.Scsi.ScsiLun[]' and try again.
At C:\Users\mgvml\Downloads\get-esxistorageinformation1.ps1:23 char:53
+ $scsipaths = $scsilun | Get-Scsilunpath -scsilun
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ScsiLunPath], ParameterBindingException
+ FullyQualifiedErrorId : MissingArgument,VMware.VimAutomation.ViCore.Cmdlets.Commands.Host.GetScsiLunPath

Get-ScsiLunPath : Missing an argument for parameter 'ScsiLun'. Specify a parameter of type 'VMware.VimAutomation.ViCore.Types.V1.Host.Storage.Scsi.ScsiLun[]' and try again.
At C:\Users\mgvml\Downloads\get-esxistorageinformation1.ps1:23 char:53
+ $scsipaths = $scsilun | Get-Scsilunpath -scsilun

Get-ScsiLunPath : Missing an argument for parameter 'ScsiLun'. Specify a parameter of type 'VMware.VimAutomation.ViCore.Types.V1.Host.Storage.Scsi.ScsiLun[]' and try again.
At C:\Users\mgvml\Downloads\get-esxistorageinformation1.ps1:23 char:53
+ $scsipaths = $scsilun | Get-Scsilunpath -scsilun
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ScsiLunPath], ParameterBindingException
+ FullyQualifiedErrorId : MissingArgument,VMware.VimAutomation.ViCore.Cmdlets.Commands.Host.GetScsiLunPath

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That script does NOT work!!!

One error is the line $scsilun | Get-Scsilunpath -scsilun
Another error is the fact that you commented out the HBA part.


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

0 Kudos
mlgurav
Contributor
Contributor
Jump to solution

this is the working iteration that gives details for all the luns. Had been modifying the script to work with getconten hence had commented the hba part.  If you could help point me in right direction to make it work for specific set of naa ids.

 

#Connect to vCenter Server
Connect-VIServer vcenter01
#$scsiluns = Get-Content -path "d:\script\lun.txt"

#Get list of ESXi Hosts
$esxihosts = Get-VMHost
$i=0


$data = ForEach ($esxi in $esxihosts) {
$i++
Write-Progress -Activity "Scanning hosts" -Status ("Host: {0}" -f $esxi.Name) -PercentComplete ($i/$esxihosts.count*100) -Id 0
$hbas = $esxi | Get-VMHostHba
$j=0
ForEach ($hba in $hbas) {
$j++
Write-Progress -Activity "Scanning HBAs" -Status ("HBA: {0}" -f $hba.Device) -PercentComplete ($j/$hbas.count*100) -Id 1
$scsiluns = $hba | Get-ScsiLun
$k=0
ForEach ($scsilun in $scsiluns) {
$k++
Write-Progress -Activity "Scanning Luns" -Status ("Lun: {0}" -f $scsilun.CanonicalName) -PercentComplete ($k/$scsiluns.count*100) -Id 2
$scsipaths = $scsilun | Get-Scsilunpath
$l=0
ForEach ($scsipath in $scsipaths) {
$l++
Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}" -f $scsipath.Name) -PercentComplete ($l/$scsipaths.count*100) -Id 3
New-Object PSObject -Property @{
Host = $esxi.name
HBAName = $scsilun.RuntimeName
PathSelectionPolicy = $scsilun.MultiPathPolicy
Status = $scsipath.state
Source = "{0}" -f ((("{0:x}" -f $hba.PortWorldWideName) -split '([a-f0-9]{2})' | where {$_}) -Join ":")
Target = $scsipath.SanId
LUN = (($scsilun.RunTimeName -Split "L")[1] -as [Int])
LUNID = $scsipath.ScsiCanonicalName
Path = $scsipath.LunPath
}
}
}
}
}

$data | Export-Csv -NoTypeInformation 'ESXiStorageInfo.csv'

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try something like this

#Connect to vCenter Server
Connect-VIServer vcenter01
$scsiluns = Get-Content -Path "d:\script\lun.txt"

#Get list of ESXi Hosts
$esxihosts = Get-VMHost
$i = 0

$data = ForEach ($esxi in $esxihosts) {
    $i++
    Write-Progress -Activity "Scanning hosts" -Status ("Host: {0}" -f $esxi.Name) -PercentComplete ($i / $esxihosts.count * 100) -Id 0
    $k = 0
    ForEach ($scsilun in (Get-ScsiLun -CanonicalName $scsiluns -VmHost $esxi)) {
        $k++
        Write-Progress -Activity "Scanning Luns" -Status ("Lun: {0}" -f $scsilun.CanonicalName) -PercentComplete ($k / $scsiluns.count * 100) -Id 2
        $scsipaths = Get-ScsiLun -CanonicalName $scsilun -VmHost $esxi | Get-ScsiLunPath
        $l = 0
        ForEach ($scsipath in $scsipaths) {
            $l++
            Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}" -f $scsipath.Name) -PercentComplete ($l / $scsipaths.count * 100) -Id 3
            New-Object PSObject -Property @{
                Host                = $esxi.name
                HBAName             = $scsilun.RuntimeName
                PathSelectionPolicy = $scsilun.MultiPathPolicy
                Status              = $scsipath.state
                Source              = "{0}" -f ((("{0:x}" -f $hba.PortWorldWideName) -split '([a-f0-9]{2})' | where { $_ }) -Join ":")
                Target              = $scsipath.SanId
                LUN                 = (($scsilun.RunTimeName -Split "L")[1] -as [Int])
                LUNID               = $scsipath.ScsiCanonicalName
                Path                = $scsipath.LunPath
            }
        }
    }
}

$data | Export-Csv -NoTypeInformation 'ESXiStorageInfo.csv'


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

0 Kudos
mlgurav
Contributor
Contributor
Jump to solution

Getting below error when running the script.

 

Get-ScsiLun : Cannot validate argument on parameter 'CanonicalName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At D:\Cloud_Sync\gDrive\SYNC\scripts\Get-Lunpath-info.ps1:13 char:54
+ ... ForEach ($scsilun in (Get-ScsiLun -CanonicalName $scsiluns -VmHost ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-ScsiLun], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.Host.GetScsiLun

Get-ScsiLun : Cannot validate argument on parameter 'CanonicalName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At D:\Cloud_Sync\gDrive\SYNC\scripts\Get-Lunpath-info.ps1:13 char:54
+ ... ForEach ($scsilun in (Get-ScsiLun -CanonicalName $scsiluns -VmHost ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-ScsiLun], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.Host.GetScsiLun

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Looks like you might have empty lines in the TXT file


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

0 Kudos
mlgurav
Contributor
Contributor
Jump to solution

Bravo,

Thanks Luc,

That indeed was the case. It's working now.

0 Kudos