### SECTION HEADER ############################################################# # TYPE : Function. # # DESCRIPTION : Enumerates the given host's fibre based storage. Gives # # similar information to that found in the vSphere Client, # # under ...Configuration...Storage and ... # # Configuration...Storage Adapters. # # PARMS PASSED : ESX host name (FQDN). # # RESULT : -1 = No host name specified. # # -2 = Failed to get handle for host. # # -3 = Failed to get .NET view for host. # # -4 = Failed to get .NET view for host storage system. # # -5 = Failed to enumerate datastores on disk. # # VERSIONS : 1.0 03/11/2009 SC First version. # ################################################################################ function enumerateHostFibreStorage() { param( [String] $vihost = "" ) [String] $Local:strHost = $vihost; [VMware.VimAutomation.Types.VMHost] $Local:objHost = $null; [VMware.Vim.HostSystem] $Local:objHostView = $null; [VMware.Vim.HostStorageSystem] $Local:objHostStorageSystemView = $null; [String] $Local:strCurrentAdapter = ""; [Int] $Local:intLunCount = 0; [Int] $Local:intLunIndex = 0; [Int] $Local:intPathCount = 0; [Int] $Local:intPathIndex = 0; [VMware.Vim.HostMultipathInfoLogicalUnit] $Local:objScsiLun = $null; [VMware.Vim.HostMultipathInfoPath] $Local:objScsiPath = $null; [VMware.Vim.HostFibreChannelHba] $Local:objHBA = $null; [VMware.Vim.HostScsiDisk] $Local:objScsiDisk = $null; [Int64] $Local:intNumBlocks = 0; [Int32] $Local:intBlockSize = 0; [Int] $Local:intRc = 0; # # Check we have a host name. # if ( $strHost -eq "" ) { Write-Host "ERROR : Please specify a VI host server using the /HOST: parameter." $intRc = -1; } #if # # Get a handle for the host. # if ( $intRc -eq 0 ) { $objHost = Get-VMHost -Name $strHost if ( ! $? ) { Write-Host "ERROR : Failed to get host object (please ensure you have supplied a FQDN)." $intRc = -2; } #if } #if # # Get a .NET view for the host. # if ( $intRc -eq 0 ) { $objHostView = Get-View -id $objHost.id if ( ! $? ) { Write-Host "ERROR : Failed to get .NET host view." $intRc = -3; } else { #logLine -line "Got .NET view for host..." } #else-if } #if # # Get a .NET view for the host storage system. # if ( $intRc -eq 0 ) { $objHostStorageSystemView = Get-View -id $objHostView.ConfigManager.StorageSystem if ( ! $? ) { Write-Host "ERROR : Failed to get .NET host storage system view." $intRc = -4; break; } else { Write-Host "Got .NET view for host storage..." } #else-if } #if # # Enumerate the Fibre Channel HBAs. # if ( $intRc -eq 0 ) { # # Look for FC/AL HBAs. # $objHostStorageSystemView.StorageDeviceInfo.HostBusAdapter | Where-Object{ $_.Key -like "*FibreChannelHba*" } | ForEach-Object { $objHBA = $_; $strCurrentAdapter = $objHBA.Key Write-Host ( "Processing Adapter [" + $objHBA.Device + "]..." ) # # Now enumerate the SCSI paths, looking for active paths involving the current adapter. # # # Enumerate the LUNs. # $intLunCount = $objHostStorageSystemView.StorageDeviceInfo.MultiPathInfo.Lun.Length; for ( $intLunIndex = 0; $intLunIndex -lt $intLunCount; $intLunIndex++ ) { $objScsiLun = $objHostStorageSystemView.StorageDeviceInfo.MultiPathInfo.Lun[$intLunIndex]; # # Now enumerate the paths for the current LUN. # $intPathCount = $objScsiLun.Path.Length for ( $intPathIndex = 0; $intPathIndex -lt $intPathCount; $intPathIndex++ ) { $objScsiPath = $objHostStorageSystemView.StorageDeviceInfo.MultiPathInfo.Lun[$intLunIndex].Path[$intPathIndex]; # # Are we looking at an active path?... and is it on the current adapter? # if ( ($objScsiPath.PathState -eq "active") -and ($objScsiPath.Adapter -eq $strCurrentAdapter) ) { # # Now pull some info from StorageDeviceInfo.ScsiLun. # $objScsiDisk = $objHostStorageSystemView.StorageDeviceInfo.ScsiLun | Where-Object{ ($_.Uuid -eq $objScsiLun.Id) -and ($_.DeviceType -eq "disk") } if ( $objScsiDisk -ne $null ) { # # Calculate the LUN size using the LBA data. # $intNumBlocks = $objScsiDisk.Capacity.Block; $intBlockSize = $objScsiDisk.Capacity.BlockSize; Write-Host ( "LUN Key : " + $objScsiLun.Key ) Write-Host ( "LUN ID : " + $objScsiLun.Id ) Write-Host ( "LUN Number : " + [Convert]::ToString( "0x" + $objScsiLun.Id.SubString(4,2), 10) ); Write-Host ( "LUN : " + $objScsiLun.Lun ) Write-Host ( "Device Path : " + $objScsiDisk.DevicePath ) Write-Host ( "Vendor : " + $objScsiDisk.Vendor ) Write-Host ( "Model : " + $objScsiDisk.Model ) Write-Host ( "Canonical Name : " + $objScsiDisk.CanonicalName ) Write-Host ( "Display Name : " + $objScsiDisk.DisplayName ) Write-Host ( "Number of Blocks : " + $intNumBlocks ) Write-Host ( "Block Size (B) : " + $intBlockSize ) Write-Host ( "Capacity (GB) : " + (($intNumBlocks * $intBlockSize) / (1024*1024*1024)) ) #$objScsiDisk.Capacity | Get-Member | fl ) # # Now look for datastores on this disk. # if ( (enumerateDataStoresOnScsiDisk -vihost $objHost -disk $objScsiDisk.CanonicalName) -ne 0 ) { Write-Host "ERROR : Failed to enumerate datastores for disk." logLine -line "" $intRc = -5; break; } #if logLine -line "" } #if-scsi-disk-not-null } #if-active-path-for-hba # # # if ( $intRc -ne 0 ) { break; } } #for (path) # # # if ( $intRc -ne 0 ) { break; } } #for (lun) } #ForEach HBA } #if Write-Host ( "intRc is " + $intRc ) return $intRc; } ### END OF SECTION ############################################################# ### SECTION HEADER ############################################################# # TYPE : Function. # # DESCRIPTION : # # PARMS PASSED : # # RESULT : # # VERSIONS : 1.0 03/11/2009 SC First version. # ################################################################################ function enumerateDataStoresOnScsiDisk() { param( [VMware.VimAutomation.Types.VMHost] $vihost = $null, [String] $disk = "" ) [VMware.VimAutomation.Types.VMHost] $Local:objHost = $vihost; [String] $Local:strDiskName = $disk; [Int] $Local:intRc = 0; [VMware.Vim.HostSystem] $Local:objHostView = $null; [VMware.Vim.HostStorageSystem] $Local:objHostStorageSystemView = $null; [VMware.Vim.HostVmfsVolume] $Local:objVolume = $null; [VMware.Vim.HostScsiDiskPartition] $Local:objExtent = $null; [Int] $Local:intMountCount = 0; [Int] $Local:intMountIndex = 0; [Int] $Local:intExtentCount = 0; [Int] $Local:intExtentIndex = 0; if ( $strDiskName -eq "" ) { $intRc = -1; } else { #Write-Host ( "enumerateDataStoresOnScsiDisk( """ + $strDiskName + """ );" ) } #else-if # # Get a .NET view for the host. # if ( $intRc -eq 0 ) { $objHostView = Get-View -id $objHost.id if ( ! $? ) { Write-Host "ERROR : Failed to get .NET host view." $intRc = -2; break; } else { Write-Host "Got .NET view for host..." } #else-if } #if # # Get a .NET view for the host storage system. # if ( $intRc -eq 0 ) { $objHostStorageSystemView = Get-View -id $objHostView.ConfigManager.StorageSystem if ( ! $? ) { Write-Host "ERROR : Failed to get .NET host storage system view." $intRc = -3; break; } else { #logLine -line "Got .NET view for host storage..." } #else-if } #if # # Now need to enumerate file system mounts (AKA datastores) and the extents thereof # (a datastore can have multiple extents, which can be on separate disks (LUNs)). # if ( $intRc -eq 0 ) { $intMountCount = $objHostStorageSystemView.FileSystemVolumeInfo.MountInfo.Length; #Write-Host ( $intMountCount.toString() + " volume(s) found..." ) for ( $intMountIndex = 0; $intMountIndex -lt $intMountCount; $intMountIndex++ ) { if ( $objHostStorageSystemView.FileSystemVolumeInfo.MountInfo[ $intMountIndex ].Volume.Type -eq "VMFS" ) { $objVolume = $objHostStorageSystemView.FileSystemVolumeInfo.MountInfo[ $intMountIndex ].Volume; #Write-Host ( "Mount #" + ($intMountIndex + 1).toString() + "..." ) # # See how many extents we have. # $intExtentCount = $objVolume.Extent.Length #Write-Host ( " " + $intExtentCount.toString() + " extent(s) found..." ) # # Enumerate the extents (partitions) for this datastore. # for ( $intExtentIndex = 0; $intExtentIndex -lt $intExtentCount; $intExtentIndex++ ) { $objExtent = $objVolume.Extent[ $intExtentIndex ]; # # Is the current extent (partition) on the disk that was specified by the user? # if ( $objExtent.DiskName -eq $strDiskName ) { Write-Host ( " Extent #" + ($intExtentIndex + 1).toString() + " of #" + $intExtentCount.toString() + " of datastore """ + $objVolume.Name + """ resides on this disk:" ) Write-Host ( " Capacity (GB) : " + ($objVolume.Capacity / (1024*1024*1024)) ); Write-Host ( " UUID : " + $objVolume.UUID ); Write-Host ( " Type : " + $objVolume.Type ); Write-Host ( " Version : " + $objVolume.Version ); Write-Host ( " Block Size (MB) : " + $objVolume.BlockSizeMB ); } #if } #for (extent) } #if-vmfs } #for (mount) } #if return $intRc; } ### END OF SECTION #############################################################