Compilenix's Blog - Free up VMware VMFS-Datastore from specefic VM's

RSS Feed | Find Stuff

Migrate all VMware VM-Datastores, starting with a specific name, from one Datastore evenly (based on percentage usage) to multiple Datastores.

#Connect-VIServer -Server $vCenterServer

# Source datastore
$datastore = Get-Datastore -Name "VMFS0"
# Destinations
$ClientVMDatastores = "VMFS1","VMFS2","VMFS3","VMFS4","VMFS5","VMFS6","VMFS7","VMFS8"
# starting with following (ignores case)
$StartWith = "asdfg"

Function Get-DatastoreUsage {
    param([Parameter(Mandatory=$true)] [System.Array] $Datastores);

    Return ($Datastores | Foreach-Object { 
            Add-Member -InputObject $_ -MemberType NoteProperty -Name PercentageFree -Force -Value ([float](( $_.FreeSpaceMB / $_.CapacityMB ) * 100))
            $_
        } | Select-Object -Property Name,Id,CapacityGB,FreeSpaceGB,PercentageFree `
        | Sort-Object -Property PercentageFree -Descending
    )
}

$vms = Get-VM -Datastore $datastore
$Storages = Get-Datastore -Name $ClientVMDatastores
$DestinationStorageFree = 0.0
$DataToMove = 0.0

$vms | % {
    $DataToMove += $_.UsedSpaceGB
}
$Storages | % {
    $DestinationStorageFree += $_.FreeSpaceGB
}

Write-Host "VM's to migrate: $($vms.Count)"
Write-Host "Total GB to move: $([math]::round($DataToMove,2))"
Write-Host "Total GB free on all destinations: $([math]::round($DestinationStorageFree,2))"
Write-Host "Total GB free on all destinations, after moved: $([math]::round(($DestinationStorageFree - $DataToMove),2))"
If(($DestinationStorageFree - $DataToMove) -le 1) {
    Write-Warning "There would no space left on devices after this operation! exiting..."
    Exit
}

If(($cont = Read-Host "Continue? [Y/n]") -eq '') {$cont="Y"}else{$cont=$result}

If ($cont -eq 'Y') {
    $vms | % {
        $VM = $_
        If ($VM.Name.StartsWith($StartWith,"CurrentCultureIgnoreCase")) {
            $Storages = Get-Datastore -Name $ClientVMDatastores
            $StoragesUsage = Get-DatastoreUsage -Datastores $Storages
            $StorageToMoveTo = Get-Datastore -Id $StoragesUsage[0].Id
            Write-Host "Migrate VM: $VM from $datastore to $StorageToMoveTo"
            Move-VM -VM $vm -Datastore $StorageToMoveTo | Out-Null
        }
    }
}

$Storages = Get-Datastore -Name $ClientVMDatastores
$StoragesUsage = Get-DatastoreUsage -Datastores $Storages
$StoragesUsage | Format-Table
$PercentageFree = $($i = 0; $a = 0; $StoragesUsage.PercentageFree | % { $i++; $a += $_; }; $a / $i)
Write-Host "Total storage % used: $([math]::round($PercentageFree,2))"

Update: check if there is enough free space displays some info before the migrations begin.

Update: moooore stuff :)
Clean-Datastore.ps1
Get-DatastoreUsage.ps1
Init.ps1
Tests.ps1
Test-VISession.ps1