Merge pull request #90 from NamedJason/patch-2

Improved performance and user feedback
This commit is contained in:
Kyle Ruddy
2017-07-06 15:05:30 -04:00
committed by GitHub

View File

@@ -1,50 +1,112 @@
#Created by Alan Renouf, published at https://communities.vmware.com/docs/DOC-18008 <#
.SYNOPSIS Datastore Functions
.DESCRIPTION A collection of functions to manipulate datastore Mount + Attach status
.EXAMPLE Get-Datastore | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
.EXAMPLE Get-Datastore IX2ISCSI01 | Unmount-Datastore
.EXAMPLE Get-Datastore IX2ISCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
.EXAMPLE Get-Datastore IX2iSCSI01 | Mount-Datastore
.EXAMPLE Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
.EXAMPLE Get-Datastore IX2iSCSI01 | Detach-Datastore
.EXAMPLE Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
.EXAMPLE Get-Datastore IX2iSCSI01 | Attach-datastore
.EXAMPLE Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
.NOTES Written by Alan Renouf, originally published at https://blogs.vmware.com/vsphere/2012/01/automating-datastore-storage-device-detachment-in-vsphere-5.html
.NOTES May 2017: Modified by Jason Coleman (virtuallyjason.blogspot.com), to improve performance when dealing with a large number of hosts and datastores
#>
Function Get-HostViews {
[CmdletBinding()]
Param (
$Datastore
)
Begin{
$allDatastores = @()
}
Process {
$allDatastores += $Datastore
}
End {
#Build the array of Datastore Objects
if (-not $Datastore) {
$allDatastores = Get-Datastore
}
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
if (-not $allDatastores){
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
}
$allHosts = @()
$DShostsKeys = $allDatastores.extensiondata.host.key.value | sort | get-unique -asstring
$DShosts = foreach ($thisKey in $DShostsKeys) {($allDatastores.extensiondata.host | ? {$_.key.value -eq $thisKey})[0]}
$i = 1
foreach ($DSHost in $DSHosts){
write-progress -activity "Collecting ESXi Host Views" -status "Querying $($dshost.key)..." -percentComplete ($i++/$DSHosts.count*100)
$hostObj = "" | select keyValue,hostView,storageSys
$hostObj.hostView = get-view $DSHost.key
$hostObj.keyValue = $DSHost.key.value
$hostObj.storageSys = Get-View $hostObj.hostView.ConfigManager.StorageSystem
$allHosts += $hostObj
}
write-progress -activity "Collecting ESXi Host Views" -completed
$allHosts
}
}
Function Get-DatastoreMountInfo { Function Get-DatastoreMountInfo {
[CmdletBinding()] [CmdletBinding()]
Param ( Param (
[Parameter(ValueFromPipeline=$true)] [Parameter(ValueFromPipeline=$true)]
$Datastore $Datastore
) )
#Roll back up an unrolled array from a pipeline
Begin{
$allDatastores = @()
}
Process { Process {
$allDatastores += $Datastore
}
End {
$AllInfo = @() $AllInfo = @()
#Build the array of Datastore Objects
if (-not $Datastore) { if (-not $Datastore) {
$Datastore = Get-Datastore $allDatastores = Get-Datastore
} }
Foreach ($ds in $Datastore) { $allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
if ($ds.ExtensionData.info.Vmfs) { if (-not $allDatastores){
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].diskname Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
if ($ds.ExtensionData.Host) { }
$attachedHosts = $ds.ExtensionData.Host $allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname}
Foreach ($VMHost in $attachedHosts) {
$hostview = Get-View $VMHost.Key #Build the array of custom Host Objects
$hostviewDSState = $VMHost.MountInfo.Mounted $allHosts = Get-HostViews -datastore $allDatastores
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem $output = @()
$devices = $StorageSys.StorageDeviceInfo.ScsiLun $i = 1
Foreach ($device in $devices) { foreach ($dsHost in $allHosts){
$Info = "" | Select Datastore, VMHost, Lun, Mounted, State write-progress -activity "Checking Datastore access" -status "Checking $($dshost.hostview.name)..." -percentComplete ($i++ / $allHosts.count * 100)
if ($device.canonicalName -eq $hostviewDSDiskName) { #Get all devices on the host that match the list of $allDatastoreNAAs
$hostviewDSAttachState = "" $devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun
if ($device.operationalState[0] -eq "ok") { foreach ($device in $devices){
$hostviewDSAttachState = "Attached" if ($allDatastoreNAAs -contains $device.canonicalName){
} elseif ($device.operationalState[0] -eq "off") { #Record information about this device/host combo
$hostviewDSAttachState = "Detached" $thisDatastore = $alldatastores | ? {$_.ExtensionData.Info.vmfs.extent[0].diskname -eq $device.canonicalName}
} else { $hostviewDSAttachState = ""
$hostviewDSAttachState = $device.operationalstate[0] if ($device.operationalState[0] -eq "ok") {
} $hostviewDSAttachState = "Attached"
$Info.Datastore = $ds.Name } elseif ($device.operationalState[0] -eq "off") {
$Info.Lun = $hostviewDSDiskName $hostviewDSAttachState = "Detached"
$Info.VMHost = $hostview.Name } else {
$Info.Mounted = $HostViewDSState $hostviewDSAttachState = $device.operationalstate[0]
$Info.State = $hostviewDSAttachState
$AllInfo += $Info
}
}
} }
$Info = "" | Select Datastore, VMHost, Lun, Mounted, State
$Info.VMHost = $dsHost.hostview.name
$Info.Datastore = $thisDatastore.name
$Info.Lun = $device.canonicalName
$Info.mounted = ($thisDatastore.extensiondata.host | ? {$_.key.value -eq $dshost.keyvalue}).mountinfo.mounted
$Info.state = $hostviewDSAttachState
$output += $info
} }
} }
} }
$AllInfo write-progress -activity "Checking Datastore access" -completed
$output
} }
} }
@@ -54,81 +116,32 @@ Function Detach-Datastore {
[Parameter(ValueFromPipeline=$true)] [Parameter(ValueFromPipeline=$true)]
$Datastore $Datastore
) )
Process { Begin{
if (-not $Datastore) { $allDatastores = @()
Write-Host "No Datastore defined as input"
Exit
}
Foreach ($ds in $Datastore) {
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname
if ($ds.ExtensionData.Host) {
$attachedHosts = $ds.ExtensionData.Host
Foreach ($VMHost in $attachedHosts) {
$hostview = Get-View $VMHost.Key
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem
$devices = $StorageSys.StorageDeviceInfo.ScsiLun
Foreach ($device in $devices) {
if ($device.canonicalName -eq $hostviewDSDiskName) {
$LunUUID = $Device.Uuid
Write-Host "Detaching LUN $($Device.CanonicalName) from host $($hostview.Name)..."
$StorageSys.DetachScsiLun($LunUUID);
}
}
}
}
}
} }
}
Function Unmount-Datastore {
[CmdletBinding()]
Param (
[Parameter(ValueFromPipeline=$true)]
$Datastore
)
Process { Process {
if (-not $Datastore) { $allDatastores += $Datastore
Write-Host "No Datastore defined as input"
Exit
}
Foreach ($ds in $Datastore) {
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname
if ($ds.ExtensionData.Host) {
$attachedHosts = $ds.ExtensionData.Host
Foreach ($VMHost in $attachedHosts) {
$hostview = Get-View $VMHost.Key
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem
Write-Host "Unmounting VMFS Datastore $($DS.Name) from host $($hostview.Name)..."
$StorageSys.UnmountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);
}
}
}
} }
} End {
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
Function Mount-Datastore { if (-not $allDatastores){
[CmdletBinding()] Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
Param (
[Parameter(ValueFromPipeline=$true)]
$Datastore
)
Process {
if (-not $Datastore) {
Write-Host "No Datastore defined as input"
Exit
} }
Foreach ($ds in $Datastore) { $allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname}
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname $allHosts = Get-HostViews -datastore $allDatastores
if ($ds.ExtensionData.Host) { $j = 1
$attachedHosts = $ds.ExtensionData.Host foreach ($dsHost in $allHosts){
Foreach ($VMHost in $attachedHosts) { #Get all devices on the host that match the list of $allDatastoreNAAs
$hostview = Get-View $VMHost.Key write-progress -id 1 -activity "Detaching Datastores" -status "Removing device(s) from $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem $devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun | ? {$allDatastoreNAAs -contains $_.canonicalName}
Write-Host "Mounting VMFS Datastore $($DS.Name) on host $($hostview.Name)..." $i = 1
$StorageSys.MountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid); foreach ($device in $devices){
} write-progress -parentid 1 -activity "Detaching Datastores" -status "Removing device: $(($allDatastores | ? {$_.ExtensionData.Info.vmfs.extent[0].diskname -eq $device.canonicalName}).name)" -percentComplete ($i++ / $allDatastoreNAAs.count * 100)
$LunUUID = $Device.Uuid
$dsHost.storageSys.DetachScsiLun($LunUUID);
} }
} }
write-progress -activity "Detaching Datastores" -completed
} }
} }
@@ -138,47 +151,95 @@ Function Attach-Datastore {
[Parameter(ValueFromPipeline=$true)] [Parameter(ValueFromPipeline=$true)]
$Datastore $Datastore
) )
Begin{
$allDatastores = @()
}
Process { Process {
if (-not $Datastore) { $allDatastores += $Datastore
Write-Host "No Datastore defined as input" }
Exit End {
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
if (-not $allDatastores){
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
} }
Foreach ($ds in $Datastore) { $allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname}
$hostviewDSDiskName = $ds.ExtensionData.Info.vmfs.extent[0].Diskname $allHosts = Get-HostViews -datastore $allDatastores
if ($ds.ExtensionData.Host) { $j = 1
$attachedHosts = $ds.ExtensionData.Host foreach ($dsHost in $allHosts){
Foreach ($VMHost in $attachedHosts) { #Get all devices on the host that match the list of $allDatastoreNAAs
$hostview = Get-View $VMHost.Key write-progress -id 1 -activity "Attaching Datastores" -status "Attaching devices to $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
$StorageSys = Get-View $HostView.ConfigManager.StorageSystem $devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun
$devices = $StorageSys.StorageDeviceInfo.ScsiLun $i = 1
Foreach ($device in $devices) { foreach ($device in $devices){
if ($device.canonicalName -eq $hostviewDSDiskName) { write-progress -parentid 1 -activity "Attaching Datastores" -status "Attaching device: $($Device.Uuid)" -percentComplete ($i++ / $devices.count * 100)
$LunUUID = $Device.Uuid if ($allDatastoreNAAs -contains $device.canonicalName){
Write-Host "Attaching LUN $($Device.CanonicalName) to host $($hostview.Name)..." $LunUUID = $Device.Uuid
$StorageSys.AttachScsiLun($LunUUID); $dsHost.storageSys.AttachScsiLun($LunUUID);
}
}
} }
} }
} }
write-progress -activity "Attaching Datastores" -completed
}
}
Function Unmount-Datastore {
[CmdletBinding()]
Param (
[Parameter(ValueFromPipeline=$true)]
$Datastore
)
Begin{
$allDatastores = @()
}
Process {
$allDatastores += $Datastore
}
End {
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
if (-not $allDatastores){
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
}
$allHosts = Get-HostViews -datastore $allDatastores
$j = 1
foreach ($dsHost in $allHosts){
write-progress -id 1 -activity "Unmounting Datastores" -status "Unmounting devices from $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
$i = 1
foreach ($ds in $allDatastores){
write-progress -parentid 1 -activity "Unmounting Datastores" -status "Unmounting device: $($ds.name)" -percentComplete ($i++ / $allDatastores.count * 100)
$dsHost.storageSys.UnmountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);
}
}
write-progress -activity "Unmounting Datastores" -completed
}
}
Function Mount-Datastore {
[CmdletBinding()]
Param (
[Parameter(ValueFromPipeline=$true)]
$Datastore
)
Begin{
$allDatastores = @()
}
Process {
$allDatastores += $Datastore
}
End {
$allDatastores = $allDatastores | ? {$_.pstypenames -contains "VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreImpl"}
if (-not $allDatastores){
Throw "No Datastores found.`nIs ""$Datastore"" a Datastore Object?"
}
$allHosts = Get-HostViews -datastore $allDatastores
$j = 0
foreach ($dsHost in $allHosts){
write-progress -activity "Mounting Datastores" -status "Mounting devices to $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100)
$i = 1
foreach ($ds in $allDatastores){
write-progress -activity "Mounting Datastores" -status "Mounting device: $($DS.ExtensionData.Info.vmfs.uuid)" -percentComplete ($i++ / $allDatastores.count * 100)
$dsHost.storageSys.MountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);
}
}
write-progress -activity "Mounting Datastores" -completed
} }
} }
#
#Get-Datastore | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
#
#Get-Datastore IX2ISCSI01 | Unmount-Datastore
#
#Get-Datastore IX2ISCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
#
#Get-Datastore IX2iSCSI01 | Mount-Datastore
#
#Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
#
#Get-Datastore IX2iSCSI01 | Detach-Datastore
#
#Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
#
#Get-Datastore IX2iSCSI01 | Attach-datastore
#
#Get-Datastore IX2iSCSI01 | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize
#