Hey all, I'm looking for a way to storage migrate the largest VMs but check to see if the destination datastore free percentage is over 20% before doing the move. I have something written up but it just isn't working. I want it to move one VM at a time, then check the free space to make sure we're still good, then move another one.
Testing it with higher free percentages, it works to break out and essentially not start the move, but if it actually has free space available it tries to move a ton of VMs all at once and throws an error.
$sourcedatastore = "devstgvm001"
$destinationdatastore = "devstgvm08"
$destinationfree = Get-Datastore $destinationdatastore
$free = ($destinationfree.ExtensionData.Summary.FreeSpace/$destinationfree.ExtensionData.Summary.Capacity)*100
$vms = Get-VM -Datastore $sourcedatastore | Sort-Object UsedSpaceGB -Descending
foreach($vm in $vms){
If ($free -le 20) {
Write-Host 'Datastore hit' $free '% free, stopping.'
break
} else {
Move-VM -VM (Get-VM -Name $vm) -Datastore $destinationdatastore -DiskStorageFormat thin
}
}
Getting this error after it keeps kicking off VMs:
Move-VM : 5/29/2018 10:50:24 AM Move-VM Operation is not valid due to the current state of the object.
+ Move-VM -VM (Get-VM -Name $vm) -Datastore $destinationdatastore -Di ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Does a manual triggered storage vMotion work?
Or same error there?
Yup a manual svmotion works just fine.
function Move-VMs{
param($vm)
Write-Host $vm
$dsNameHDD1 = 0
$HDDs = Get-HardDisk -VM $vm
# a foreach loop to move vmdk
$HDDs | %{
# Get the datastore name of the old
$oldDS = $_.Filename.Split(']')[0].TrimStart('[')
$sourceDS = "datastore1"
# as @pfuhli said the new lun has a preceding letter that differs from the old.
$newDS = "datastore2"
# Here i check which is the first hdd to later move the config there
if ($_.Name -eq "Festplatte 1" -and $oldDS -eq $sourceDS){
$dsNameHDD1 = $newDS
}
$newDS = Get-Datastore $newDS
if ($SourceDS -eq $oldDS)
{
Set-HardDisk -HardDisk $_ -Datastore $newDS -Confirm:$false -StorageFormat Thin
}
}
# This part is for moving the config file
$HDDs = Get-HardDisk -VM $vm
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.datastore = (Get-Datastore -Name $dsNameHDD1).Extensiondata.MoRef
$HDDs | %{
$disk = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$disk.diskId = $_.Extensiondata.Key
$disk.datastore = $_.Extensiondata.Backing.Datastore
$spec.disk += $disk
}
$vm.Extensiondata.RelocateVM_Task($spec, "defaultPriority")
}
Get-VM -Datastore "datastore1" | %{
Move-VMs $_
Just had a look how I moved VMs the last time.
Maybe this code-sniplet would help you 🙂
In short: try "RelocateVM" instead of "Move-VM"
You have to update the free storage percentage after each svMotion.
Try like this
$destinationdatastore = "devstgvm08"
$destinationfree = Get-Datastore $destinationdatastore
$free = ($destinationfree.FreeSpaceGB/$destinationfree.CapacityGB)*100
$vms = Get-VM -Datastore $sourcedatastore | Sort-Object -Property UsedSpaceGB -Descending
foreach($vm in $vms){
If ($free -le 20) {
Write-Host 'Datastore hit' $free '% free, stopping.'
break
}
else {
Move-VM -VM (Get-VM -Name $vm) -Datastore $destinationdatastore -DiskStorageFormat thin
$destinationfree = Get-Datastore $destinationdatastore
$free = ($destinationfree.FreeSpaceGB/$destinationfree.CapacityGB)*100
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you LucD and aleex42 . Both of your comments pointed me in the right direction to get this working!