Just something I wanted to share with the community…
One of our VMWare Administrators was working with VMWare vendor support in looking at some SAN connection issues and was requesting a report showing the following information: Host, Name, HBAName, Source, Target, LUN, Status, Path, PathSelectionPolicy
They could then use this information to further review the data and make some recommendations on our infrastructure. While you can view the data by looking at vSphere and going through a couple of different areas to pull the data, hand copying this data would be just painfully slow.
Here is where PowerShell and PowerCLI come into play. I was asked if I could put a script together that could pull all of the information and put it into a report of some sort. Putting the data into a report is very simple using Export-CSV, but gathering the data would be a little trickier as the required data requested was not in one place to just pull from.
Fortunately, after a little exploring I was able to locate all of the data and put together a short 41 line script that would pull this data and put it into a CSV file for the vendor to use.
A couple of things I added to the script was the use of Write-Progress to allow you to see where the script was at in its processing. Otherwise, you could be left wondering for an hour or so trying to figure out if the script was still running of was stuck somewhere.
In my case, the script took about an hour to run in one of my environments and produced a 11000+ row CSV file with the information seen below.
While I am by no means an expert with PowerCLI and am sure that there may be a better way of pulling this data, this still worked out like a champ and provided the vendor the useful information to decide where some changes could be made at. I would not call it a “finished” script as it lacks inline help and verbose logging, but feel free to take it and make any additions to it that you see fit. Hopefully you will find this script just as useful in your environment.
Remember to update the vCenter Server in the script to point to your server so the script works correctly!
Download (remove .doc from file)
Source Code
#Connect to vCenter Server Connect-VIServer vCenterServer #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]) Path = $scsipath.LunPath } } } } } $data | Export-Csv -NoTypeInformation 'ESXiStorageInfo.csv'
Excellent script!!
I dont always download random scripts from the internet, but when i do, they are from Boe 😉
YES!! 😀
Would be great to see this same process for Windows!
Hey Boe.. thanks for this one.. I would like to know as to how do I check for dual path availability check (to SAN/storage arrays) for windows server through powershell.
thanks
Hi Boe
Another great script, thanks for sharing. tested in my env and got the “Attempted to divide by zero” errors;
Added to the line that gets the hbas to get online the online ones and all errors gone.
$hbas = $esxi | Get-VMHostHba | where-object {$_.Status -eq “online”}
write-progress is great as one can see it and go for a cuppa come back and be rest it is doing the job
I ran it using Powercli5.1 Release 2 & continuously getting below errors
+ Write-Progress -Activity “Scanning Luns” -Status (“Lun: {0}” -f $
scsilun.CanonicalName) -PercentComplete ($k/ <<<< $scsiluns.count*100) -Id 2
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At E:\Scripts\VMware\Storage\get-esxistorageinformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
I see the output is wrong. as I tried in my infra where on each HBA port where I’ve
Targets – 2
Devices – 11
Paths -22
Connected HBA Ports to server- 2
So that makes it entirely 44 paths i.e. 22 paths on each port
while the output I see shows me 88 paths i.e. it counts all the paths with each HBA port & in the HBAName section it just shows me only one HBA for the entire 88 paths for the entire column though the source shows me 2 WWN’s of my HBA.
one wwn for first 44 paths & 2nd wwn for next 44 paths.
Hi Boe, I would like to have this script working on 3.5/4.0/4.1 and 5.0 either separate or in a single script. would that be possible?
Great script Boe, Can you show how to modify it to except a single host as input? Like this:
connect-viserver -Server “myserver” -protocol https
$VMHostname = Read-Host “Please enter a hostname”
Then have the script run against just that 1 host?
Thanks MUCH in advance!
Just to follow up I get NO output and some errors as per this:
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity “Scanning Paths” -Status (“Path: {0}
” -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:20 char:122
+ Write-Progress -Activity "Scanning Luns" -Status ("Lun: {0}" -f $
scsilun.CanonicalName) -PercentComplete ($k/ <<<< $scsiluns.count*100) -Id 2
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Attempted to divide by zero.
At C:\Scripts\Get-ESXiStorageInformation.ps1:25 char:120
+ Write-Progress -Activity "Scanning Paths" -Status ("Path: {0}
" -f $scsipath.Name) -PercentComplete ($l/ <<<< $scsipaths.count*100) -Id 3
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Export-Csv : Access to the path 'C:\ESXiStorageInfo.csv' is denied.
At C:\Scripts\Get-ESXiStorageInformation.ps1:41 char:19
+ $data | Export-Csv <<<
did you get a fix for this??
I have come across the same issue. What is the proper way to runt he script. I believe I am connecting to the vcenter server incorrectly.
Thank you for this great script!!!, please could you update it for PowerCLi version 5??? I’m getting quite a bit of errors (and I’m not a script guru by a long shot)
– Thanks in advance!!!!!
Glad you like the script! It will probably be a few months before I can update this to V5. I will keep everyone posted on when I update the script for V5. Your comment also has reminded me to add some error handling on the Write-Progress portion to handle the Divide by Zero error that sometimes happens. 🙂
Is there any way to show the DataStore names too ? (properties name of “get-datastore -vmhost $esxi”)
Possibly, I will have to go back to the script and see what I can do with it.
Wow great script ! Thanks for sharing !
Boe – you miss typed the line. “While the you can view the data by looking at vSphere and going through a couple of different areas to pull the data, hand copying this data would be just painfully slow.” You need to remove the word “the” after the word While. Good article though! Definitely helpful! 🙂
Thanks,Charlie! Thought I fixed all of the typos, but I guess that one somehow go through. 🙂
Nice one, love the way you used the progress bars.
Thanks, Luc! I figured the progress bars made sense in this case.