VMware Cloud Community
jessem
Enthusiast
Enthusiast
Jump to solution

Command or script needed to get Datastore, NAA identifier and multipath

The following script/command gets me the multipath policy on a csv file, however, I need it to also identify the 'Datastore' name with the naa number.

get-cluster 'windows 01' | get-vmhost | get-scsilun -luntype disk | Export-csv c:\lun_multipath.csv

any help would be appreciated.

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try something like this

$datastore = get-datastore

$disks = get-cluster 'windows 01' | get-vmhost | get-scsilun -luntype disk
$entry = @()
$output = @()
ForEach ($disk in $disks){
 
$entry = "" | Select DataStorename, HostName, Canonicalname, Multipathing
 
$entry.datastorename= $datastore | Where-Object {($_.extensiondata.info.vmfs.extent | %{$_.diskname}) -contains $disk.canonicalname}|select -expand name
 
$entry.HostName = $disk.VMHost.Name
 
$entry.canonicalname=$disk.canonicalname
 
$entry.multipathing=$disk.multipathpolicy
 
$output += $entry
}
$output | Export-csv c:\lun_multipath.csv


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

View solution in original post

Reply
0 Kudos
29 Replies
LucD
Leadership
Leadership
Jump to solution

Have a look at LUN report – datastore, RDM and node visibility


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

Reply
0 Kudos
CRad14
Hot Shot
Hot Shot
Jump to solution

I just quickly threw this together....it's not pretty but I think it should work for you

$datastore=get-datastore

$disks=get-cluster 'windows 01' | get-vmhost | get-scsilun -luntype disk

$entry=@()

$output=@()

ForEach ($disk in $disks)


{

$entry="" | Select DataStorename, Canonicalname, Multipathing

$entry.datastorename= $datastore | Where-Object { $_.extensiondata.info.vmfs.extent.diskname -like $disk.canonicalname}|select -expand name

$entry.canonicalname=$disk.canonicalname

$entry.multipathing=$disk.multipathpolicy

$output+=$entry

}

$output | Export-csv c:\lun_multipath.csv

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

I tried this but the datastore name column does not have anything in it?...

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you try the script in the post I linked to ?


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

Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

I'm trying to read thru it but it's a little confusing for me Smiley Sad

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

What is confusing ? How to run it ?


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

Reply
0 Kudos
CRad14
Hot Shot
Hot Shot
Jump to solution

Make sure you are running the whole thing...Including the first line I listed

"$datastore=get-datastore"

I just tried it again for my stuff and it looks fine

Also I am sure LucD's stuff would work as well

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

I ran it but it opens up the csv with 0 data in it.  I copied and pasted this code, just replaced the cluster name with my cluster.

---------

param($clusName,$csvName=("C:\Temp\" + $clusName + "-LUN.csv"))

$rndNum = Get-Random -Maximum 99999

$LunInfoDef = @"

public string ClusterName;

public string CanonicalName;

public string UsedBy;

public string SizeMB;

"@

$LunInfoDef = "public struct LunInfo" + $rndNum + "{`n" + $LunInfoDef

$esxServers = Get-Cluster $'windows 01' | Get-VMHost | Sort-Object -Property Name

$esxServers | %{

$LunInfoDef += ("`n`tpublic string " + ($_.Name.Split(".")[0]) + ";")

}

$LunInfoDef += "`n}"

Add-Type -Language CsharpVersion3 -TypeDefinition $LunInfoDef

$scsiTab = @{}

$esxServers | %{

$esxImpl = $_

# Get SCSI LUNs

$esxImpl | Get-ScsiLun | where {$_.LunType -eq "Disk"} | %{

$key = $esxImpl.Name.Split(".")[0] + "-" + $_.CanonicalName.Split(".")[1]

if(!$scsiTab.ContainsKey($key)){

$scsiTab[$key] = $_.CanonicalName,"",$_.CapacityMB

}

}

# Get the VMFS datastores

$esxImpl | Get-Datastore | where {$_.Type -eq "VMFS"} | Get-View | %{

$dsName = $_.Name

$_.Info.Vmfs.Extent | %{

$key = $esxImpl.Name.Split(".")[0] + "-" + $_.DiskName.Split(".")[1]

$scsiTab[$key] = $scsiTab[$key][0], $dsName, $scsiTab[$key][2]

}

}

}

# Get the RDM disks

Get-Cluster $clusName | Get-VM | Get-View | %{

$vm = $_

$vm.Config.Hardware.Device | where {$_.gettype().Name -eq "VirtualDisk"} | %{

if("physicalMode","virtualmode" -contains $_.Backing.CompatibilityMode){

$disk = $_.Backing.LunUuid.Substring(10,32)

$key = (Get-View $vm.Runtime.Host).Name.Split(".")[0] + "-" + $disk

$scsiTab[$key][1] = $vm.Name + "/" + $_.DeviceInfo.Label

}

}

}

$scsiTab.GetEnumerator() | Group-Object -Property {$_.Key.Split("-")[1]} | %{

$lun = New-Object ("LunInfo" + $rndNum)

$lun.ClusterName = $clusName

$_.Group | %{

$esxName = $_.Key.Split("-")[0]

$lun.$esxName = "ok"

if(!$lun.CanonicalName){$lun.CanonicalName = $_.Value[0]}

if(!$lun.UsedBy){$lun.UsedBy = $_.Value[1]}

if(!$lun.SizeMB){$lun.SizeMB = $_.Value[2]}

}

$lun

} | Export-Csv $csvName -NoTypeInformation -UseCulture

Invoke-Item $csvName

Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

hmmm, that line is definitely part of the .ps1 script and yet the csv file has nothing in there...

Capture.PNG

$datastore=get-datastore

$disks=get-cluster 'OS 01' | get-vmhost | get-scsilun -luntype disk

$entry=@()

$output=@()

ForEach ($disk in $disks)

{

$entry="" | Select DataStorename, Canonicalname, Multipathing

$entry.datastorename= $datastore | Where-Object { $_.extensiondata.info.vmfs.extent.diskname -like $disk.canonicalname}|select -expand name

$entry.canonicalname=$disk.canonicalname

$entry.multipathing=$disk.multipathpolicy

$output+=$entry

}

$output | Export-csv c:\lun_multipath.csv

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You should save the script in a .ps1 file, let's say Lun-report.ps1.

Then from the PowerCLI prompt you call it with parameters

./Lun-report.ps1 -ClusName MyCluster -CsvName "C:\report.csv"

Did you run it like that ?


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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The Extent property is an array. Try replacing that line with this

$entry.datastorename= $datastore | Where-Object {($_.extensiondata.info.vmfs.extent | %{$_.diskname}) -contains $disk.canonicalname}|select -expand name


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

Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

yes, can you show me how the code would look if my cluster name is WINDOWS 01?  Maybe I don't have it correctly listed/placed?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, it should be started like this

./Lun-report.ps1 -ClusName "WINDOWS 01" -CsvName "C:\report.csv"

Do you get any error messages ?


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

Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

yes, here is the error:

Get-Cluster : Cannot validate argument on parameter 'Name'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.

At C:\users\a\desktop\Lun-report.ps1:13 char:26

+ $esxServers = Get-Cluster <<<<  $clusName | Get-VMHost | Sort-Object -Property Name

    + CategoryInfo          : InvalidData: (:) [Get-Cluster], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetCluster

You cannot call a method on a null-valued expression.

At C:\users\a\desktop\Lun-report.ps1:15 char:55

+     $LunInfoDef += ("`n`tpublic string " + ($_.Name.Split <<<< (".")[0]) + ";")

    + CategoryInfo          : InvalidOperation: (Split:String) [], RuntimeException

    + FullyQualifiedErrorId : InvokeMethodOnNull

Get-ScsiLun : Cannot validate argument on parameter 'VmHost'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again

At C:\users\a\desktop\Lun-report.ps1:26 char:24

+     $esxImpl | Get-ScsiLun <<<<  | where {$_.LunType -eq "Disk"} | %{

    + CategoryInfo          : InvalidData: (:) [Get-ScsiLun], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.Host.GetScsiLun

Get-Datastore : Cannot validate argument on parameter 'RelatedObject'. The argument is null or empty. Supply an argument that is not null or empty and then try the comm

nd again.

At C:\users\a\desktop\Lun-report.ps1:36 char:26

+     $esxImpl | Get-Datastore <<<<  | where {$_.Type -eq "VMFS"} | Get-View | %{

    + CategoryInfo          : InvalidData: (:) [Get-Datastore], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetDatastore

Get-Cluster : Cannot validate argument on parameter 'Name'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.

At C:\users\a\desktop\Lun-report.ps1:46 char:12

+ Get-Cluster <<<<  $clusName | Get-VM | Get-View | %{

    + CategoryInfo          : InvalidData: (:) [Get-Cluster], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetCluster

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The $clusName variable seems to be empty.

That means the parameters were not passed correctly, or the param line in the script is not correct.

Could you perhaps attach a screenshot of the PowerCLI prompt where you call the function ?


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

Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

Ok, I checked it again and I fat fingered it!  It works, however....I don't see anywhere in the report/csv where it gives me the multipathing (fixed, round robin, etc.) policy?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, the multipathing is not in that report. Although it isn't too hard to include it.

But then take the other script with the change I suggested, that should give you the multipathing as well


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

Reply
0 Kudos
jessem
Enthusiast
Enthusiast
Jump to solution

so replace the line:

$_.Info.Vmfs.Extent | %{

with this?

$entry.datastorename= $datastore | Where-Object {($_.extensiondata.info.vmfs.extent | %{$_.diskname}) -contains $disk.canonicalname}|select -expand name

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, you replace this line

$entry.datastorename= $datastore | Where-Object { $_.extensiondata.info.vmfs.extent.diskname -like $disk.canonicalname}|select -expand name

with this line

$entry.datastorename= $datastore | Where-Object {($_.extensiondata.info.vmfs.extent | %{$_.diskname}) -contains $disk.canonicalname}|select -expand name


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

Reply
0 Kudos