PS DS-LUN-v4.ps1

From vwiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
# ======================================================
# Datastore and LUN Enumerator
# ======================================================
# Simon Strutt        Nov 2010
# ======================================================
#
# ESX v3 
# Thieved and adapted from the good work by catman...
# http://communities.vmware.com/thread/240466
#
# ESX v4
# Thieved and adapted from the good work by notorious_bdg...
# http://communities.vmware.com/thread/171214
#
# Version 3 - Nov 2010
# - Enumerate for a VC (rather than just an ESX)
#
# Version 4 - Nov 2010
# - Added handling for ESX v4
#
# TO DO...
# - Get-DS-LUNs assumes all ESX's connected to a VC are same version, resolve
#
# ======================================================

function Get-DS-LUNs ($objESXs) {
    $esx = $objESXs | Select -First 1
    if (($esx.Version) -ge 4) {
        Get-DS-LUNs-v4
    } else {
        Get-DS-LUNs-v3 ($objESXs)
    }
}

function Get-DS-LUNs-v3 ($objESXs) {
    $results = @()
    foreach ($objESX in $objESXs) {
        #Write-Host "Checking datastores on " $objESX.Name

        # Get .NET views for host and storage system
        $objViewESX = Get-View -id $objESX.id
        $objViewESXstorageSys = Get-View -id $objViewESX.ConfigManager.StorageSystem

        # Get FC HBAs
        $HBAs = $objViewESXstorageSys.StorageDeviceInfo.HostBusAdapter | Where-Object {$_.Key -like "*FibreChannelHba*"}
        #$HBAs

        foreach ($hba in $HBAs) {
            # Enumerate LUNs
            $LUNcount = $objViewESXstorageSys.StorageDeviceInfo.MultiPathInfo.Lun.Length
            #Write-Host ("Enumerating $LUNcount LUNs on " + $hba.Device)
            
            for ($LUNidx = 0; $LUNidx -lt $LUNcount; $LUNidx++ ) {
                $objScsiLUN = $objViewESXstorageSys.StorageDeviceInfo.MultiPathInfo.Lun[$LUNidx]
                #$objScsiLUN
                
                # Enumerate paths on LUN
                $PathCount = $objScsiLUN.Path.Length
                #Write-Host ("Enumerating $PathCount paths on " + $objScsiLUN.Id)
                
                for ($PathIdx = 0; $PathIdx -lt $PathCount; $PathIdx++) {
                    $objSCSIpath = $objViewESXstorageSys.StorageDeviceInfo.MultiPathInfo.Lun[$LUNidx].Path[$PathIdx]
                    #Write-Host ($objSCSIpath.Name + " - " + $objSCSIpath.PathState)
                    
                    # Only care about one path, active on current HBA
                    if (($objSCSIpath.PathState -eq "active") -and ($objSCSIpath.Adapter -eq $hba.Key)) {
                        # Now get the disk that we want
                        $objSCSIdisk = $objViewESXstorageSys.StorageDeviceInfo.ScsiLun | Where-Object{ ($_.CanonicalName -eq $objScsiLUN.Id) -and ($_.DeviceType -eq "disk") }
                        #$objSCSIdisk
                        
                        # Now get the datastore info for disk
                        $MountCount = $objViewESXstorageSys.FileSystemVolumeInfo.MountInfo.Length
                        #Write-Host ("Enumerating $MountCount mounts on " + $objSCSIdisk.CanonicalName)
                        
                        for ($MountIdx = 0; $MountIdx -lt $MountCount; $MountIdx++ ) {
                            if ($objViewESXstorageSys.FileSystemVolumeInfo.MountInfo[$MountIdx].Volume.Type -eq "VMFS" ) {
                                $objVolume = $objViewESXstorageSys.FileSystemVolumeInfo.MountInfo[$MountIdx].Volume
                                #$objVolume
                                
                                $ExtentCount = $objVolume.Extent.Length
                                #Write-Host ("Enumerating $ExtentCount mounts on " + $objVolume.Name)
                                
                                for ($ExtentIdx = 0; $ExtentIdx -lt $ExtentCount; $ExtentIdx++ ) {
                                    $objExtent = $objVolume.Extent[$ExtentIdx]
                                    
                                    # Match extent name to disk name
                                    if ($objExtent.DiskName -eq $objSCSIdisk.CanonicalName) {
                                        #Write-Host($objSCSIdisk.Vendor + " " + $objSCSIdisk.Model + " " + $objSCSIdisk.CanonicalName + "`t" + $objVolume.Name)
                                        
                                        $row = "" | Select Datastore, Make, Model, LUN
                                        $row.Datastore = $objVolume.Name
                                        $row.Make = ($objSCSIdisk.Vendor).TrimEnd()
                                        $row.Model = ($objSCSIdisk.Model).TrimEnd()
                                        $row.LUN = ([regex]::matches($objSCSIdisk.CanonicalName, "(?<=:)([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$")).Item(0).Value
                                        
                                        # Only add datastore to array if it doesn't already exist
                                        if ( ! ($results | ?{$_.Datastore -eq $row.Datastore}) ) {$results = $results + $row}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    $results
}

function Get-DS-LUNs-v4 {
    foreach ($cluster in (Get-View -ViewType "ClusterComputeResource")) {
      $vmhostsview = $cluster.host | % { Get-View $_ }
      $vmhostview  = $vmhostsview | Select -first 1
      $ScsiLuns    = $vmhostsview | % { $_.Config.StorageDevice.ScsiLun } | Select -unique *
      $UUIDs       = $ScsiLuns | Select -unique UUID
      $Datastores  = $vmhostsview | % { $_.Config.FileSystemVolume.MountInfo } | % { $_.Volume } | Select -Unique *
      $HostLUN     = $vmhostsview | % { $_.Config.StorageDevice.ScsiTopology.Adapter } | % { $_.Target | % { $_.LUN } } | Select -unique *
      foreach ($UUID in $UUIDs) {
        $Lun = $ScsiLuns | ? { $_.UUID -eq $UUID.UUID } | Select -first 1
        $objVolume               = "" | Select Datastore, Make, Model, LUN

        $objVolume.LUN       = ($HostLUN | ? { $_.ScsiLun -eq $Lun.Key } | select -unique LUN).LUN
        $objVolume.Make        = $Lun.Vendor
        $objVolume.Model         = $Lun.Model
        foreach ($vol in $Datastores) {
          if ($vol.extent | % { $_.diskname -eq $Lun.CanonicalName}) {
            $objVolume.Datastore  = $vol.Name
          }
        }
        $objVolume
      }
    }
}