Problem: Unmount and Detach VMware Datastores

 

If you are working in project where need to unmount multiple datastores and detach from each esxi hosts is very tedious job to unmount and detach from each ESXi host.

To Make automated to reduce the time. Below are the automated powercli script to do this job faster without any manually work.

 

To modify this script only you need two thing to change in this script.  One is vCenter Server Name and another one is to specify the datastores name (which is marked in RED color to change as per your environment.) which you want to unmount and detach from ESXi hosts.

 

Solutions:

 

#############################################################################################################

##script:           Unmount_Detach-Datastore.ps1

##

##Description:      Unmounts and detaches a given datastore from all its connected hosts.

#+                  Before running make sure that the datastore doesn't have any live VMs or templates on it.

#Additional info:   http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2004605

#Additional info:   http://blogs.vmware.com/vsphere/2012/01/automating-datastore-storage-device-detachment-in-vsphere-5.html

#Additional info:   https://communities.vmware.com/docs/DOC-18008

 

 

##############################################################################################################

function Connect-Vcenter {

    #############################################################################################

    ##Function:         Connect-Vcenter

    ##

    ##Description:      Loads the VMWare snap-in for powershell and connects to vcenter.

    ##

    ##Created by:      

    ##############################################################################################

    param(

        $vcenter

    )

    #Load snap-in

    if (-not (Get-PSSnapin -Name VMware.VimAutomation.Core -erroraction "silentlycontinue" )) {

        Write-Host "Importing VMWare Snap-in VMware.VimAutomation.Core..."  

        Add-PSSnapin VMware.VimAutomation.Core

    }

    Set-PowerCLIConfiguration -DefaultVIServerMode Single -invalidCertificateAction "ignore" -confirm:$false | out-null

    #Connect to vCenter

    if ($global:DefaultVIServers.Count -lt 1) {

        Write-Host "Connecting to vcenter server $vcenter..."     

        Connect-VIServer $vCenter

    }

}

Function Get-DatastoreMountInfo {

    #function copied from https://communities.vmware.com/docs/DOC-18008

    [CmdletBinding()]

    Param (

        [Parameter(ValueFromPipeline=$true)]

        $Datastore

    )

    Process {

        $AllInfo = @()

        if (-not $Datastore) {

            $Datastore = Get-Datastore

        }

        Foreach ($ds in $Datastore) { 

            if ($ds.ExtensionData.info.Vmfs) {

                $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

                        $hostviewDSState = $VMHost.MountInfo.Mounted

                        $StorageSys = Get-View $HostView.ConfigManager.StorageSystem

                        $devices = $StorageSys.StorageDeviceInfo.ScsiLun

                        Foreach ($device in $devices) {

                            $Info = '' | Select Datastore, VMHost, Lun, Mounted, State

                            if ($device.canonicalName -eq $hostviewDSDiskName) {

                                $hostviewDSAttachState = ''

                                if ($device.operationalState[0] -eq "ok") {

                                    $hostviewDSAttachState = "Attached"                       

                                } elseif ($device.operationalState[0] -eq "off") {

                                    $hostviewDSAttachState = "Detached"                       

                                } else {

                                    $hostviewDSAttachState = $device.operationalstate[0]

                                }

                                $Info.Datastore = $ds.Name

                                $Info.Lun = $hostviewDSDiskName

                                $Info.VMHost = $hostview.Name

                                $Info.Mounted = $HostViewDSState

                                $Info.State = $hostviewDSAttachState

                                $AllInfo += $Info

                            }

                        }

                        

                    }

                }

            }

        }

        $AllInfo

    }

}

Function Detach-Datastore {

    #function based on code found here https://communities.vmware.com/docs/DOC-18008

    [CmdletBinding()]

    Param (

        [Parameter(ValueFromPipeline=$true)]

        $Datastore

    )

    Process {

        if (-not $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

                    $devices = $StorageSys.StorageDeviceInfo.ScsiLun

                    Foreach ($device in $devices) {

                        if ($device.canonicalName -eq $hostviewDSDiskName) {

                            #If the device is attached then detach it (I added this to the function to prevent error messages in vcenter when running the script)

                            if ($device.operationalState[0] -eq "ok") {

                                $LunUUID = $Device.Uuid

                                Write-Host "Detaching LUN $($Device.CanonicalName) from host $($hostview.Name)..."

                                $StorageSys.DetachScsiLun($LunUUID);

                            }

                            #If the device isn't attached then skip it (I added this to the function to prevent error messages in vcenter when running the script)

                            else {

                                Write-Host "LUN $($Device.CanonicalName) is not attached on host $($hostview.Name)..."

                            }

                        }

                    }

                }

            }

        }

    }

}

Function Unmount-Datastore {

    #function based on code found here https://communities.vmware.com/docs/DOC-18008

    [CmdletBinding()]

    Param (

        [Parameter(ValueFromPipeline=$true)]

        $Datastore

    )

    Process {

        if (-not $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

                    $mounted = $VMHost.MountInfo.Mounted

                    #If the device is mounted then unmount it (I added this to the function to prevent error messages in vcenter when running the script)

                    if ($mounted -eq $true) {

                        $StorageSys = Get-View $HostView.ConfigManager.StorageSystem

                        Write-Host "Unmounting VMFS Datastore $($DS.Name) from host $($hostview.Name)..."

                        $StorageSys.UnmountVmfsVolume($DS.ExtensionData.Info.vmfs.uuid);

                    }

                    #If the device isn't mounted then skip it (I added this to the function to prevent error messages in vcenter when running the script)

                    else {

                        Write-Host "VMFS Datastore $($DS.Name) is already unmounted on host $($hostview.Name)..."

                    }

                }

            }

        }

    }

}

#VARIABLES

#Parameters

$vcenter = "VCS01.domain.local"

$DSName = "VMFS_DS_01","VMFS_DS_02","VMFS_DS_03","VMFS_DS_04","VMFS_DS_05","VMFS_DS_06","VMFS_DS_07","VMFS_DS_08","VMFS_DS_09","VMFS_DS_10"

#SCRIPT MAIN

clear

Connect-Vcenter $vcenter

$datastore = Get-Datastore -Name $DSName

$CanonicalName = $datastore.ExtensionData.Info.Vmfs.Extent[0].DiskName

$GoAhead = Read-Host "Are you sure that you want to unmount and detach: `n$DSName `n$CanonicalName`nfrom all its connected hosts?"

if ($GoAhead -eq "yes" -or $GoAhead -eq "y" -or $GoAhead -eq "Y") {

    Write-Host "Unmounting datastore $DSName..."  

    $datastore | Unmount-Datastore

    Write-Host "Detaching datastore $DSName from hosts..."

    $datastore | Detach-Datastore

}

$DSName

$CanonicalName