Powercli Script to Unmount and Detach Datastores

A storage migration is eventually going to get to a phase where the old datastores need to be unmounted and detached from hosts. I found a script showing how to do this via PowerCLI, but I wanted to expand on it to better serve my use case.

What I came up with is below and also on my github.

When running the script you must specify the vCenter name and the folder containing the datastores that will be unmounted. A regular expression is used to specify the names of the datastores you want to unmount. For example, “Datastore\d\d” would unmount datastores named DATASTORE01 and DATASTORE99, but not DMZ_STORAGE01 (the PowerShell -match operator is not case sensitive). Also, the script will only work on datastores that have been put into maintenance mode.

Prerequisites

The Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<#
.SYNOPSIS
A script to unmount and detach datastores from VMWare vCenter.

.DESCRIPTION
This script unmounts datastores from vCenter if they are in maintenance mode, reside in the specified folder, and the name matches the specified regular expression.

The VMware PowerCLI module is required and a connection to vCenter (Connect-VIServer) must be established before running the script.

.EXAMPLE
Unmount-Datastores.ps1 -VIServer vcenter.domain.local -NameRegex "Datastore\d\d" -Folder "Unmount"
This command will unmount and detach datastores in the vcenter.domain.local vCenter that reside in the datastore folder named Unmount with names that -match the regular expression "Datastore\d\d".

.NOTES
Author: Luke Arntz
Date:   May 13, 2019

.Link
https://blue42.net

.Link
https://github.com/larntz/PowerCLI
#>

Param(
    # Specifies a vCenter server name.
        [Parameter(Position=0,mandatory=$true)]
    [string]$VIServer,
    # Specifies a datastore folder name.
        [Parameter(Position=1,mandatory=$true)]
    [string]$Folder,
    # Specifies a regular expression to -match datastore names.
        [Parameter(Position=2,mandatory=$true)]
    [string]$NameRegex
)

$MaintenanceModeDatastores = Get-Datastore -Location (Get-Folder -Name $Folder) -Server $ViServer | where {$_.State -eq "Maintenance" -And $_.Name -match $NameRegex}

$UnMounted = @()
foreach ($MaintenanceModeDatastore in $MaintenanceModeDatastores)
{
        $datastoreHostInfo = Get-VmHost -Server $viserver -Id ($MaintenanceModeDatastore.ExtensionData.Host.Key)
        $CanonicalName = $MaintenanceModeDatastore.ExtensionData.Info.Vmfs.Extent[0].Diskname
        Write-Host "Processing $($MaintenanceModeDatastore)..."
        foreach ($vmHost in $datastoreHostInfo)
        {
                $unmount = [PSCustomObject]@{
                        Datastore = $MaintenanceModeDatastore.Name
                        DsUuid = $MaintenanceModeDatastore.ExtensionData.info.Vmfs.uuid
                        LunUuid = (Get-ScsiLun -Server $viserver -VmHost $vmHost | where {$_.CanonicalName -eq $CanonicalName}).ExtensionData.Uuid
                        Host = $vmHost.name
                        CanonicalName = $CanonicalName
                        UnmountTime = $null             
                        }

                $hostMountInfo = $MaintenanceModeDatastore.ExtensionData.Host | Where {$_.Key -eq $VMHost.Id}
                if($hostMountInfo.MountInfo.Mounted -eq "True")
                {
                        Write-Host "Unmounting $($unmount.Datastore) from host $($VMHost.Name)"
                        $hostStorageSystem = Get-View $VMHost.Extensiondata.ConfigManager.StorageSystem
                        $hostSTorageSystem.UnmountVmfsVolume($unmount.DsUuid)
                        $hostStorageSystem.DetachScsiLun($unmount.LunUuid)
                } else {
                        write-host "$($unmount.Datastore) not mounted on $($VMhost.Name)"
                        }


                $unmount.UnmountTime = Get-Date -Format "s"
                $UnMounted += $unmount
        }
}

$UnMounted

Related Content