Created
June 1, 2017 14:21
-
-
Save NamedJason/661201ed46afb8855f32acb4bd4d529d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.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 { | |
[CmdletBinding()] | |
Param ( | |
[Parameter(ValueFromPipeline=$true)] | |
$Datastore | |
) | |
#Roll back up an unrolled array from a pipeline | |
Begin{ | |
$allDatastores = @() | |
} | |
Process { | |
$allDatastores += $Datastore | |
} | |
End { | |
$AllInfo = @() | |
#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?" | |
} | |
$allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname} | |
#Build the array of custom Host Objects | |
$allHosts = Get-HostViews -datastore $allDatastores | |
$output = @() | |
$i = 1 | |
foreach ($dsHost in $allHosts){ | |
write-progress -activity "Checking Datastore access" -status "Checking $($dshost.hostview.name)..." -percentComplete ($i++ / $allHosts.count * 100) | |
#Get all devices on the host that match the list of $allDatastoreNAAs | |
$devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun | |
foreach ($device in $devices){ | |
if ($allDatastoreNAAs -contains $device.canonicalName){ | |
#Record information about this device/host combo | |
$thisDatastore = $alldatastores | ? {$_.ExtensionData.Info.vmfs.extent[0].diskname -eq $device.canonicalName} | |
$hostviewDSAttachState = "" | |
if ($device.operationalState[0] -eq "ok") { | |
$hostviewDSAttachState = "Attached" | |
} elseif ($device.operationalState[0] -eq "off") { | |
$hostviewDSAttachState = "Detached" | |
} else { | |
$hostviewDSAttachState = $device.operationalstate[0] | |
} | |
$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 | |
} | |
} | |
} | |
write-progress -activity "Checking Datastore access" -completed | |
$output | |
} | |
} | |
Function Detach-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?" | |
} | |
$allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname} | |
$allHosts = Get-HostViews -datastore $allDatastores | |
$j = 1 | |
foreach ($dsHost in $allHosts){ | |
#Get all devices on the host that match the list of $allDatastoreNAAs | |
write-progress -id 1 -activity "Detaching Datastores" -status "Removing device(s) from $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100) | |
$devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun | ? {$allDatastoreNAAs -contains $_.canonicalName} | |
$i = 1 | |
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 | |
} | |
} | |
Function Attach-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?" | |
} | |
$allDatastoreNAAs = foreach ($ds in $allDatastores) {$ds.ExtensionData.Info.vmfs.extent[0].diskname} | |
$allHosts = Get-HostViews -datastore $allDatastores | |
$j = 1 | |
foreach ($dsHost in $allHosts){ | |
#Get all devices on the host that match the list of $allDatastoreNAAs | |
write-progress -id 1 -activity "Attaching Datastores" -status "Attaching devices to $($dsHost.hostview.name)" -percentComplete ($j++ / $allHosts.count * 100) | |
$devices = $dsHost.storagesys.StorageDeviceInfo.ScsiLun | |
$i = 1 | |
foreach ($device in $devices){ | |
write-progress -parentid 1 -activity "Attaching Datastores" -status "Attaching device: $($Device.Uuid)" -percentComplete ($i++ / $devices.count * 100) | |
if ($allDatastoreNAAs -contains $device.canonicalName){ | |
$LunUUID = $Device.Uuid | |
$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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment