PowerCLI: Get-LunPathState
Careful preparation is a key element to success. If you restart a storage controller, or even the whole storage, you should be very sure that all ESXi hosts have enough paths to every datstore. Sure, you can use the VMware vSphere C# client or the Web Client to check every host and every datastore. But if you have a large cluster with a dozen datastores and some Raw Device Mappings (RDMs), this can take a looooong time. Checking the path state of each LUN is a task, which can be perfectly automated. Get a list of all hosts, loop through every host and every LUN, output a list of all hosts with all LUNs and all paths for each LUN. Sounds easy, right?
For a long time, I used this PowerCLI script for checking the LUN path state. But now I decided to give something back and I tweaked it a bit for my needs.
| #requires -Version 2 | |
| #requires -PSSnapin VMware.VimAutomation.Core | |
| function Get-LUNPathState { | |
| <# | |
| .SYNOPSIS | |
| No parameters needed. Just execute the script. | |
| .DESCRIPTION | |
| This script outputs the number of paths to each LUN. | |
| .EXAMPLE | |
| Get-LUNPathState -VMhosts 'esx01' | |
| Lists all LUN pats for ESXi host esx01. | |
| .EXAMPLE | |
| $esxihosts = Get-VMHost | |
| Get-LUNPathState -VMHosts $esxihosts | |
| Lists all LUN paths for all ESXi hosts in $esxihosts | |
| .NOTES | |
| Author: Patrick Terlisten, patrick@blazilla.de, Twitter @PTerlisten | |
| This script is provided "AS IS" with no warranty expressed or implied. Run at your own risk. | |
| This script is based on: http://www.vmwareadmins.com/list-the-path-and-path-state-for-every-vsphere-datastore-using-powercli/ | |
| This work is licensed under a Creative Commons Attribution NonCommercial ShareAlike 4.0 | |
| International License (https://creativecommons.org/licenses/by-nc-sa/4.0/). | |
| .LINK | |
| http://www.vcloudnine.de | |
| #> | |
| [CmdletBinding()] | |
| Param( | |
| [Parameter(Mandatory = $true,Position = 0,HelpMessage = 'ESXi Host',ValueFromPipeline = $true)] | |
| [Alias('Name')] | |
| [ValidateNotNullorEmpty()] | |
| $VMhosts | |
| ) | |
| # Create empty hash table | |
| $ReportLunPathState = @() | |
| Write-Host -Object `n | |
| Write-Host -Object "$($VMhosts.length) host(s) needs to be processed. Please wait..." | |
| # Initialize counter variable | |
| $i = 0 | |
| try | |
| { | |
| ForEach ($VMHost in $VMhosts) { | |
| # Increment counter variable | |
| $i++ | |
| # Get all datastores from the current host | |
| $VMHostDatastores = Get-Datastore | |
| # Get all disks devices from the current host | |
| $VMHostScsiLuns = $VMHost | Get-ScsiLun -LunType disk | |
| ForEach ($VMHostScsiLun in $VMHostScsiLuns) { | |
| # Get LUN paths for each disk device | |
| $VMHostScsiLunPaths = $VMHostScsiLun | Get-ScsiLunPath | |
| # Count paths per disk device | |
| $ReportLunPathState += ($VMHostScsiLunPaths | Measure-Object) | Select-Object ` | |
| -Property @{N = 'Hostname'; E = {$VMHost.Name}}, ` | |
| @{N = 'Datastore'; E = {$VMHostDatastores | Where-Object -FilterScript {($_.extensiondata.info.vmfs.extent | ForEach-Object -Process {$_.diskname}) -contains $VMHostScsiLun.CanonicalName}| Select-Object -ExpandProperty name}}, ` | |
| @{N = 'CanonicalName'; E = {$VMHostScsiLun.CanonicalName}}, ` | |
| @{N = '# of Paths'; E = {$_.Count}}, ` | |
| @{N = 'Path State'; E = {$VMHostScsiLunPaths.State}} | |
| } | |
| } | |
| } | |
| catch | |
| { | |
| "Error was $_" | |
| $line = $_.InvocationInfo.ScriptLineNumber | |
| "Error was in Line $line" | |
| } | |
| finally | |
| {$ReportLunPathState | Format-Table -AutoSize} | |
| } |
Feel free to use and/ or modify it.