I am migrating hosts between 3.5 and 4.0 and part of the migration requires me to vmotion the datastores to a single shared data LUN. From there I import the VM into 4.0 and use the below script to migrate the two VM disks to different datastores. The problem that I have is that the configuration file (vmx) does not get migrated and is left on the shared storage LUN. Anyone know how to get past this?
The Script:
$VMDisk = "Hard Disk 1"
$VMName = "TestVM"
$TargetDS = Get-Datastore -VMHost (Get-VMHost -Id $S.id) | Where-Object {$_.Name -like "VMOS"} | sort-object FreeSpaceMB -descending | select Name -first 1
$vm = Get-View -ViewType VirtualMachine -Filter @{"Name"=$VMName}
foreach($dev in $vm.Config.Hardware.Device) { if ($dev.DeviceInfo.Label -eq $vmDisk) { $diskId = $dev.Key } }
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$diskspec = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$diskspec.Datastore = (Get-Datastore -Name $TargetDS.Name | Get-View).MoRef
$diskspec.diskId = $diskId
$spec.Disk = @($diskspec)
$task = Get-View ($vm.RelocateVM_Task($spec, "lowpriority"))
Ok, I think I understand your problem now.
I'm afraid that in the current build of PowerCLI, the Move-VM cmdlet doesn't allow individual datastore destinations for each virtual hard disk.
With the RelocateVM_Task method it is possible.
The following script moves a guest to 3 different datastores:
- the .VMX file to DS2
- hard disk 1 to DS3
- hard disk 2 to DS4
$vmName = "MyGuest" $vmxDS = "DS2" $osDS = "DS3" $dataDS = "DS4" $vm = Get-VM -Name $vmName $vm.Extensiondata.Config.Hardware.Device | %{ if ($_.DeviceInfo.Label -eq "Hard disk 1"){ $osDiskId = $_.Key } elseif($_.DeviceInfo.Label -eq "Hard disk 2"){ $dataDiskId = $_.Key } } $spec = New-Object VMware.Vim.VirtualMachineRelocateSpec $osRelocate = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator $osRelocate.Datastore = (Get-Datastore -Name $osDS).Extensiondata.MoRef $osRelocate.diskId = $osDiskId $dataRelocate = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator $dataRelocate.Datastore = (Get-Datastore -Name $dataDS).Extensiondata.MoRef $dataRelocate.diskId = $dataDiskId $spec.Disk = @($osRelocate,$dataRelocate) $spec.Datastore = (Get-Datastore -Name $vmxDS).Extensiondata.MoRef $spec.Host = $vm.Extensiondata.Summary.Runtime.Host $task = Get-View ($vm.Extensiondata.RelocateVM_Task($spec, "lowpriority")) while("running","queued" -contains $task.Info.State){ $task.UpdateViewData("Info") sleep 5 }
Btw you can use the Set-HardDisk cmdlet to move a specific virtual disk to a datastore.
But as I understood it that is not possible in your environment.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Without turning my mind entirely to the script, a few questions come up:
-Are the 3.5 hosts managed by the same vCenter as the 4.0 hosts?
-If so, can you take one of the 3.5 hosts and install 4.0? (That puts a 4.0 host in the same cluster, connected to the same datastores)
-Then, you can pick them up either in the UI or keep going in the script direction
Feels like you are trying to a "clean handoff" from VI3 to vSphere rather than a migration.
I'd migrate!
Hi E4F,
I think you should use the "Move-VM" command to move virtual machine's configuration file to another datastore then use your script to move particular virtual disks.
Good luck.
Regards
Franck
Afaik, you can do this migration with the Move-VM cmdlet with the -Datastore parameter.
Followed by another Move-VM with the -Destination parameter
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD,
Do you have an example of what you are talking about. I am using the Move-VM cmdlet to get the VM to the shared data LUN in the first place but you can only provide one datastore.
E4F
No, the 3.5 VMs are have there own vCenter and the 4.0 VMs have thier own vCenter.
The fact that you have 2 vCenters changes the procedure.
You first move the guests to the shared datastore with the Move-VM cmdlet and the -Datastore parameter
$sharedDS = Get-Datastore <name-of-shared-datastore> Get-VM | Move-VM -Datastore $sharedDS -Confirm:$false
Then you will have to register the guests on the new vCenter.
You can use the Register-Vmx function from my Raiders of the Lost VMX post.
You would call the Register-Vmx function with the -dsNames parameter
First you have to connect to the new vCenter with Connect-VIServer.
Register-Vmx -dsNames <name-of-shared-datastore>
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I am already doing that, here is what I have scripted so far:
Power off the VM – Done
Migrate the VM to the Shared Data LUN – Done
Import the VM into vSphere – Done
Migrate the disks to the correct Datastore
I can migrate the VMDK’s to separate Datastores
I can’t find a way to migrate the vmx file, it gets left on the Shared Data LUN
It should go to the same OS Datastore
So are you saying that the only way to do this is to use Move-VM -datastore to move all disks to one LUN and then move the the single disk off after that?
Here is what I am doing
Power off the VM
Shutdown-VMGuest $VMName
Move VM to the Shared Data LUN
Get-VM $VMName | Move-VM -Datastore ( Get-Datastore $DataDisk )
get-vm $VMName | Get-Datastore
Add VM to Inventory
$Datacenter = "TestDC"
$ESXHost = get-vmhost | Sort-Object MemoryUsageMB | select name -first 1
$VMName = "TestVM"
$ResourcePool = Get-VMHost $ESXHost.Name | Get-ResourcePool | Get-View
$vmFolder = Get-View (Get-Datacenter -Name $Datacenter | Get-Folder -Name "vm").id
$vmFolder.RegisterVM_Task(" " + $VMName + "/" + $VMName + ".vmx", $VMName, $false, $ResourcePool.MoRef, $null)
Then I migrate the disks to seperate datastores
$VMDisk = "Hard Disk 1"
$TargetDS = Get-Datastore -VMHost (Get-VMHost -Id $S.id) | Where-Object {$_.Name -like "VMOS"} | sort-object FreeSpaceMB -descending | select Name -first 1
$vm = Get-View -ViewType VirtualMachine -Filter @{"Name"=$VMName}
foreach($dev in $vm.Config.Hardware.Device) { if ($dev.DeviceInfo.Label -eq $vmDisk) { $diskId = $dev.Key } }
$spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$diskspec = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator
$diskspec.Datastore = (Get-Datastore -Name $TargetDS.Name | Get-View).MoRef
$diskspec.diskId = $diskId
$spec.Disk = @($diskspec)
$task = Get-View ($vm.RelocateVM_Task($spec, "lowpriority"))
Repeat this for "Hard Disk 2"
This is where the VMX file gets left on the shared data LUN
On the new vCenter, where should the guest (or .VMX file) be located ?
Before moving the individual hard disks to separate datastores, why don't you first move the complete guest (Move-VM -Datastore) from the shared LUN to the datastore that needs to hold the .VMX file.
After that you can still move the hard disks to different datastores but with the difference that your .VMX file is not on the shared LUN anymore.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
We use multiple 600GB LUNs, one for the OS and one or more for the Data. Some VMs have very large Data disks so moving a VM that has 250GB of storage to a single LUN is not possible. This is why I need to migrate the OS to an OS LUN and the Data to a Data LUN after the VM has been imported into vSphere. You can do it via the GUI so I don't see why this can't be done in PowerCLI.
Ok, I think I understand your problem now.
I'm afraid that in the current build of PowerCLI, the Move-VM cmdlet doesn't allow individual datastore destinations for each virtual hard disk.
With the RelocateVM_Task method it is possible.
The following script moves a guest to 3 different datastores:
- the .VMX file to DS2
- hard disk 1 to DS3
- hard disk 2 to DS4
$vmName = "MyGuest" $vmxDS = "DS2" $osDS = "DS3" $dataDS = "DS4" $vm = Get-VM -Name $vmName $vm.Extensiondata.Config.Hardware.Device | %{ if ($_.DeviceInfo.Label -eq "Hard disk 1"){ $osDiskId = $_.Key } elseif($_.DeviceInfo.Label -eq "Hard disk 2"){ $dataDiskId = $_.Key } } $spec = New-Object VMware.Vim.VirtualMachineRelocateSpec $osRelocate = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator $osRelocate.Datastore = (Get-Datastore -Name $osDS).Extensiondata.MoRef $osRelocate.diskId = $osDiskId $dataRelocate = New-Object VMware.Vim.VirtualMachineRelocateSpecDiskLocator $dataRelocate.Datastore = (Get-Datastore -Name $dataDS).Extensiondata.MoRef $dataRelocate.diskId = $dataDiskId $spec.Disk = @($osRelocate,$dataRelocate) $spec.Datastore = (Get-Datastore -Name $vmxDS).Extensiondata.MoRef $spec.Host = $vm.Extensiondata.Summary.Runtime.Host $task = Get-View ($vm.Extensiondata.RelocateVM_Task($spec, "lowpriority")) while("running","queued" -contains $task.Info.State){ $task.UpdateViewData("Info") sleep 5 }
Btw you can use the Set-HardDisk cmdlet to move a specific virtual disk to a datastore.
But as I understood it that is not possible in your environment.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
If you want to relocate only vmx file. You need to use the SDK relocatevm_task.
You have to specify the current location for each disk or else the disk will be migrated too.
Arnim
Sent from my iPad