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.