PowerShell: Move Virtual Machine Storage Using VMM

# moveVmStorageUsingVmm.ps1
# Version 0.01

$vmNames=@(
  'TESTVM0001',  
  'TESTVM0002',
  'TESTVM0003'
)
$storageLocations=@(
  'C:\ClusterStorage\BLOB001',
  'C:\ClusterStorage\BLOB002',
  'C:\ClusterStorage\BLOB003'
)
$storageMaxPercent=79
$confirmation=$true

function moveVmStorageUsingVmm($vmName,$newStorage,$storageMaxPercent=80){  
  try{
    $vmHosts=Get-SCVMHost
    $vm=Get-SCVirtualMachine -Name $vmName
    if($vm.count -eq 1){
      $currentHost=$vm.Hostname
      $storage=Get-SCStorageVolume -VMHost $currentHost|?{$_.Name -eq $newStorage}
      $capacity=$storage.Capacity
      $freespace=$storage.FreeSpace
      $storageUtilizedPercent=[math]::round(($capacity-$freespace)/$capacity*100,2)
      $totalSize=0
      $disks = Get-SCVirtualDiskDrive -VM $vmname
      $disks.VirtualHardDisk.Size|%{$totalSize+=$_}      
      $projectedPercent=[math]::round(($capacity-$freespace+$totalSize)/$capacity*100,2)
      write-host "$newStorage current utilization percentage: $storageUtilizedPercent`% and projected: $projectedPercent`% after adding $([math]::round($totalSize/1GB,2))GB's"
      $storageFeasible=if($projectedPercent -lt $storageMaxPercent){$true}else{$false}
      if($storageFeasible){
        $vmHost=$vmHosts|?{$_.Name -eq $currentHost}
        Move-SCVirtualMachine -VM $vm -VMHost $vmHost -Path $newStorage -UseLAN -UseDiffDiskOptimization # -RunAsynchronously
        return $true
      }else{
        write-warning "Infeasible storage location: Available storage volume is $storageMaxPercent`% and projected is $projectedPercent`%"
        return $false
      }
    }else{
      write-warning "$vmName matches more than 1 guest VM's; hence, this item is skipped."
      return $null
    }
  }catch{
    write-warning $_
    return $false
  }
}

function moveStorage($vmNames,$storageLocations,$storageMaxPercent,$confirmation){
  $storageIndex=0
  $useSameStorage=$true
  if($vmNames.count -gt 1){
    for($i=0;$i -lt $vmNames.count;$i++){
      $vmName=if($useSameStorage){$vmNames[$i]}else{$vmNames[--$i]}
      try{
        $null=Get-SCVirtualMachine -Name $vmName|Read-SCVirtualMachine -ea Stop
        $storageLocation=if($useSameStorage){$storageLocations[$storageIndex]}else{$storageLocations[++$storageIndex]}
        if($storageLocation){
          if($confirmation){
            write-host "Move $vmName storage to $storageLocation`?"
            pause
          }else{
            write-host "Moving $vmName storage to $storageLocation ..."
          }
          $useSameStorage=moveVmStorageUsingVmm $vmName $storageLocation $storageMaxPercent
        }else{
          write-warning "Exhausted storage locations to move VM's"
          return $false
        }
      }catch{
        write-warning $_
        # Get-SCVirtualMachine -Name $vmName|Repair-SCVirtualMachine -force # I haven't tested this
        return $false
      }
    }
  }else{
    [string]$vmname=$vmNames
    try{
      $null=Get-SCVirtualMachine -Name $vmname|Read-SCVirtualMachine -ea Stop
      foreach($storageLocation in $storageLocations){
        if($storageLocation){
          if($confirmation){
            write-host "Move $vmname storage to $storageLocation`?"
            pause
          }else{
            write-host "Moving $vmname storage to $storageLocation ..."
          }
          $success=moveVmStorageUsingVmm $vmName $storageLocation $storageMaxPercent
          if($true -eq $success){
            return $true
          }else{
            write-warning "$vmname cannot be moved to $storageLocation"
          }
        }else{
          write-warning "Exhausted storage locations to move VM's"
          return $false
        }
      }      
    }catch{
      write-warning $_
      return $false
    }
  }
}

moveStorage $vmNames $storageLocations $storageMaxPercent $confirmation

Leave a Reply

Your email address will not be published. Required fields are marked *