Move VMs from an old SAN to an new using powerCLI part 2


I was informed that my script in the last post was not enough because @pfuhli has a bit more complex environment and then the Move-VM cmdlet is not sufficient because it moves the whole vm to the new datastore, no matter if the vmdk´s where located on different before.

As in some cases you have an virtual platform with different datastores for different performance levels and one VM has it´s vmdk configured to get the best throughput. So i  did this with help from a script that Luc Dekens did in a communities post, mine added some functionality as his only moved the config file.

please comment if you find something crazy, I have now started to get the hang of why I would use functions :-), yes i should add some error-checking, that will be in version 0.3

Probably it would take some time to get through 500 VM´s but instead of manual work it is worth it.

# Move VMs with sVMotion where vmdk is on different datastores and
# lastly move the config file to the same datastore as hard disk 1
# Niklas Åkerlund / RTS 20111127
# Part of code from Luc Dekens

# Here i extended Luc´s function for moving only config
function Move-VMs{
	Write-Host $vm
    $HDDs = Get-HardDisk -VM $vm    
	# a foreach loop to move vmdk
	$HDDs | %{
		# Get the datastore name of the old
		$oldDS = $_.Filename.Split(']')[0].TrimStart('[')
		# as @pfuhli said the new lun has a preceding letter that differs from the old.
		$newDS = "N" + $oldDS 
		# Here i check which is the first hdd to later move the config there
		if ($_.Name -eq "Hard disk 1"){
			$dsNameHDD1 = $newDS
		$newDS = Get-Datastore $newDS
		Set-HardDisk -HardDisk $_ -Datastore $newDS -Confirm:$false
	# 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 | %{ 
	Move-VMs $_ 


Before running it on all VM´s i would test it on a few and then when feeling comfortable, you can move all 😀


Ben Liebowitz

This seems to be exactly what I need, however it seems to be a script that is added onto another script, yes?
I have the need to migrate multiple VMs in a specific folder to new datastores. The VMs currently live on 3 datastores with the Cdrive/config files on datastore1, temp/page file on datastore2 and data files on datastore3.


@Ben Liebowitz Its a function that I call with the Move-VMs $_ so no other script, you will have to edit with the newds to fit your environment


How do you use/execute this script? Could you provide an example possibly?


Niklas Can we convert this script to read form csv and loop ?



The Datastore Names for the Customer has no consistent naming convention.


yes that should not be a problem.. as long as there is some consistency with the datastores and vm´s

Leave a comment


email* (not published)