PowerCLI script to list VMFS,RDM and Free LUNs in a cluster

Its always a time consuming job to find out the LUN is FREE, RDM or VMFS. The following script will help to get the details of LUNs from hosts in a cluster and will tell us the LUN is VMFS, RDM or FREE.

If the LUN is an RDM, we can see on which VM RDM is mapped. And if the LUN has VMFS volume, the datastore name will be displayed. Also the script provides the details like LUN number, Capacity and naa id (Canonical Name).

The CSV file that is produced by the script looks like this. In this example cluster has four hosts (esx1,esx2,esx3 and esx4), four LUNs (0,1,2 and 13) are shared among them.

disk-details1

You can see there are four values for TYPE.

1. VMFS :- VMFS volume (datastore)

2. RDM :- Raw Device Map(RDM) LUN connected to a VM. We can see the corresponding VM in VMname column.
3. FREE :- The LUNs which are free for creating VMFS Datastores or RDMs.
4. UNKNOWN :- On two cases UNKNOWN will be shown.
a.  the LUNs which are presented as RDM on other host. In the example, LUN 13 is an RDM on virtual machine “TestVM1” running on host “esx1″. Hence LUN 13 will shown as UNKNOWN on other hosts in the cluster.
b. Script couldn’t find whether the LUN is VMFS, RDM or Free.

[crayon lang=”powershell”]

#
# .SYNOPSIS
# PowerCLI Script for collecting the details of storage connected to a cluster.
# .DESCRIPTION
# This PowerCLI scritpt will help to identify how the disks/LUNs connected to the host are presented(RDM,VMFS or None).
# .VERSION
# v1.1
# .NOTES
# File Name : Get-DiskDetails.ps1
# Author : Sreejesh Damodaran
# Requires : PowerCLI 5.1 Release 2 or above, vCenter 5.1 or above, Powershell 3.0 or above
# .LINK
# This script posted in: http://www.pingforinfo.com
# .EXAMPLE
#   Get-DiskDetails.ps1
#

#####################################
# VMware VirtualCenter server name, #
#Cluster Name and output file(csv) #
#####################################
Connect-VIServer “vCenter Name or IP”
$outputFile = “Output csv file, eg : c:\DiskRep.csv”
$cltName = “Cluster Name ”

new-variable -Name clusterName -Scope global -Value $cltName -Force
new-variable -Name LUNDetails -Scope global -Value @() -Force
new-variable -Name LUNDetTemp -Scope global -Value @() -Force
new-variable -Name LUNDetFinal -Scope global -Value @() -Force

####################################################
#Function to creeate objects and insert into array.#
####################################################
function insert-obj(){
[CmdletBinding()]
param(
[PSObject]$esxHost,
[PSObject]$vmName,
[PSObject]$dsName,
[PSObject]$cnName,
[PSObject]$rnName,
[PSObject]$Type,
[PSObject]$CapacityGB,
[PSObject]$ArrayName
)
$object = New-Object -TypeName PSObject
$object | Add-Member -Name ‘Cluster’ -MemberType Noteproperty -Value $global:clusterName
$object | Add-Member -Name ‘Host’ -MemberType Noteproperty -Value $esxHost
$object | Add-Member -Name ‘DatastoreName’ -MemberType Noteproperty -Value $dsName
$object | Add-Member -Name ‘VMName’ -MemberType Noteproperty -Value $vmName
$object | Add-Member -Name ‘CanonicalNames’ -MemberType Noteproperty -Value $cnName
$object | Add-Member -Name ‘LUN’ -MemberType Noteproperty -Value $rnName.Substring($rnName.LastIndexof(“L”)+1)
$object | Add-Member -Name ‘Type’ -MemberType Noteproperty -Value $Type
$object | Add-Member -Name ‘CapacityGB’ -MemberType Noteproperty -Value $CapacityGB
if ($ArrayName -eq “LUNDetails”){
$global:LUNDetails += $object
}
elseif($ArrayName -eq “LUNDetTemp”){
$global:LUNDetTemp += $object
}
}
######################################
#Collect the hostnames in the cluster#
######################################
$Hosts = Get-Cluster $clusterName | Get-VMHost | select -ExpandProperty Name
#############################################
#Collecting datastore, RDM and LUN Details.#
#############################################
foreach($vmHost in $Hosts) {
Write-Host “Collecting Datastore details from host $vmHost ….”
get-vmhost -Name $vmHost | Get-Datastore | % {
$naaid = $_.ExtensionData.Info.Vmfs.Extent | select -ExpandProperty DiskName
$RuntimeName = Get-ScsiLun -vmhost $vmHost -CanonicalName $naaid | Select -ExpandProperty RuntimeName
insert-obj -esxHost $vmHost -dsName $_.Name -cnName $naaid -rnName $RuntimeName -Type $_.Type -CapacityGB $_.CapacityGB -ArrayName LUNDetails
}
Write-Host “Collecting RDM Disk details from host $vmHost ….”
get-vmhost -Name $vmHost | Get-VM | Get-HardDisk -DiskType “RawPhysical”,”RawVirtual” | % {
$naaid = $_.SCSICanonicalName
$RuntimeName = Get-ScsiLun -vmhost $vmHost -CanonicalName $naaid | Select -ExpandProperty RuntimeName
insert-obj -esxHost $vmHost -vmName $_.Parent -cnName $naaid -rnName $RuntimeName -Type RDM -CapacityGB $_.CapacityGB -ArrayName LUNDetails
}
Write-Host “Collecting Free SCSI LUN(Non-RDM/VMFS) details from host $vmHost ….”
(get-view (get-vmhost -name $vmHost | Get-View ).ConfigManager.DatastoreSystem).QueryAvailableDisksForVmfs($null) | %{
$naaid = $_.CanonicalName
$DiskTemp = Get-ScsiLun -vmhost $vmHost -CanonicalName $naaid
insert-obj -esxHost $vmHost -cnName $naaid -rnName $DiskTemp.RuntimeName -Type FREE -CapacityGB $DiskTemp.CapacityGB -ArrayName LUNDetails
}
Write-Host “Collecting details of Unallocated LUNs from host $vmHost ….”
Get-ScsiLun -VmHost $vmHost | %{
$naaid = $_.CanonicalName
$naaidTemp = $LUNDetails | select -ExpandProperty CanonicalNames
If ($naaidTemp -notcontains $naaid){
insert-obj -esxHost $vmHost -cnName $naaid -rnName $_.RuntimeName -Type UNKNOWN -CapacityGB $_.CapacityGB -ArrayName LUNDetTemp
}
}
$global:LUNDetails += $global:LUNDetTemp
$global:LUNDetFinal += $global:LUNDetails
$global:LUNDetails.Clear()
$global:LUNDetTemp.Clear()
}
############################
#Export output to CSV file #
############################
$global:LUNDetFinal | Sort-Object Host,{[int]$_.LUN} |
select Cluster,Host,CanonicalNames,Type,LUN,DatastoreName,VMName,CapacityGB | Export-Csv -NoTypeInformation $outputFile
$global:LUNDetFinal.Clear()

[/crayon]

-SD