VMware Cloud Community
BjornJohansson
Enthusiast
Enthusiast
Jump to solution

Storage vMotion between clusters from CSV mapping file

Hi,

We need to move quite a few VM's off old hardware. The plan is to use a PowerCLI script that reads from a CSV to serialize move the VM's to the new cluster. The move is done online storage vMotion for all Windows VM's. All VM's must end up on correct site, datastore, vlan and DRS group. So I'm thinking using the csv as a mapping file to specify correct destination for each VM.

The Plan in overview

  1. Get all VM's that will migrated into a csv (done)
  2. Add new columns i csv where we manually map following information (done)
    1. Destination Portgroup (we are migrating from Standard to Distributed vSwitch)
    2. Destination VMhost (we are running a Metro configuration and VM's must end up at correct site)
    3. Destination Datastore (same reason as above, some VM's are replicated, some resides on local datastores)
    4. Destination DRS group (pin VM to site because of Metro)
  3. Import-csv and loop move-vm foreach VM

So even if we only move one VM at the time, it will work 24/7 serialized and minimizing overloading production hardware. 

Any hole in the plan so far? Please let me know!

The csv file

Some manual stuff, but CSV is not too time consuming to map site, portgroups etc. in Excel. VMhost is only included to help site mapping.

Name, PortGroup, DestinationPG,VMhost, DestinationVMhost, Datastore, DestinationDS, DrsGroup

migrationVM1,vlan_214, dpg_214 esxi-02, esxi-prod-01,nfs_03, nfs_prod_01, vm-affinity-site1

migrationVM2,vlan_210, dpg_210 esxi-14, esxi-prod-06,nfs_02, nfs_prod_11, vm-affinity-site2

The script

Here I need some help. Think the plan is OK, but my script is not approaching it correctly. Got it to work as a one-liner for one VM.

$csvinput = Import-Csv -Path "C:\Powershell\CSV\Migrate.csv" -Header Name,PortGroup,DestinationPG,VMhost,DestinationVMhost,Datastore,DestinationDS,DrsGroup

$vm = Get-VM -Name $csvinput.Name

$destinationEsx = Get-VMHost $csvinput.DestinationVMhost

$networkAdapter = Get-NetworkAdapter -VM $vm

$destinationPortGroup = Get-VDPortgroup -VDSwitch 'vDS-Prod-01' -Name $csvinput.DestinationPG

$destinationDatastore = Get-Datastore $csvinput.Datastore

Foreach ($VM in $csvinput)

$vm | Move-VM -Destination $_.$destinationEsx -NetworkAdapter $networkAdapter -PortGroup $destinationPortGroup -Datastore $destinationDatastore -DiskStorageFormat Thin

I can see that this approach is very faulty, but not sure how to fix it?

Any tips?

Thank you!

Tags (1)
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

That is currently the latest PowerCLI version, so you should be ok there.

Could it be that the NFS datastore is not known on the target ESXi node.

Can you try changing that line to

   $destinationDatastore = Get-Datastore $row.Datastore -RelatedObject  $destinationEsx


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

6 Replies
LucD
Leadership
Leadership
Jump to solution

You want the ForEach loop to go through all the rows in the array (that you imported from the CSV file).

Try like this

$csvinput = Import-Csv -Path "C:\Powershell\CSV\Migrate.csv" -Header Name,PortGroup,DestinationPG,VMhost,DestinationVMhost,Datastore,DestinationDS,DrsGroup 

Foreach ($row in $csvinput){

   $vm = Get-VM -Name $row.Name

   $destinationEsx = Get-VMHost $row.DestinationVMhost

   $networkAdapter = Get-NetworkAdapter -VM $vm

   $detinationPortGroup = Get-VDPortgroup -VDSwitch 'vDS-Prod-01' -Name $row.DestinationPG

   $destinationDatastore = Get-Datastore $row.Datastore

   Move-VM -VM $VM -Destination $row.$destinationEsx -NetworkAdapter $networkAdapter -PortGroup $destinationPortGroup -Datastore $destinationDatastore -DiskStorageFormat Thin

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

BjornJohansson
Enthusiast
Enthusiast
Jump to solution

Thank you, that was exactly what I was looking for! Really appreciate that you took the time. Beer on me if we ever meet!

I believe that the script is working correctly now. Did edit some issues, so I posted it below if someone want to use it.

The problem now is possibly something with Move-VM command. On all VM's (both powered on and off) there is "Unable to access the virtual machine configuration: Unable to access file"

Even though the vMotion is between two clusters without shared storage, I can indeed vMotion both storage and compute online with vSphere Client. Using vCenter 6.7 U1.

Found in another thread where LucD​ helped out with a similar issue. There the solution was to specify cluster, using -Location $cluster, which I did but I still get the same error.

Any suggestions?

Thanks again! Smiley Happy

Move-VM : 2019-06-02 23:30:04   Move-VM         The operation for the entity "migrationtest1" failed with the following message: "Unable to access the virtual machine configuration: Unable to access file [nfs_04]"

At C:\Powershell\VMware\Migrate-VM-Storage.ps1:38 char:4

+    Move-VM -VM $vm -Destination $destinationEsx -Datastore $destinati ...

+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [Move-VM], CannotAccessVmConfig

    + FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM

Here is my edited script! Note I had to comment out -header

$csvinput = Import-Csv -Path "C:\Powershell\CSV\migtest.csv" -Delimiter ";" # -Header Name,PortGroup,DestinationPG,VMhost,DestinationVMhost,Datastore,DestinationDS,DrsGroup

$targetCluster = "metro-1"

ForEach ($row in $csvinput){

   $vm = Get-VM -Name $row.Name

   $cluster = Get-Cluster -Name $targetCluster

   $destinationEsx = Get-VMHost -Name $row.DestinationVMhost -Location $cluster

   $networkAdapter = Get-NetworkAdapter -VM $vm

   $destinationPortGroup = Get-VDPortgroup -VDSwitch 'vDS-Prod-01' -Name $row.DestinationPG

   $destinationDatastore = Get-Datastore $row.Datastore

   Move-VM -VM $vm -Destination $destinationEsx -Datastore $destinationDatastore -NetworkAdapter $networkAdapter -PortGroup $destinationPortGroup -DiskStorageFormat Thin

}

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Which PowerCLI version are you using?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
BjornJohansson
Enthusiast
Enthusiast
Jump to solution

PS C:\Powershell\VMware> get-module | select name, version

Name                                                Version

----                                                     -------

Microsoft.PowerShell.Management       3.1.0.0

Microsoft.PowerShell.Utility                   3.1.0.0

PSReadline                                           1.2

VMware.Vim                                          6.7.0.12483609

VMware.VimAutomation.Cis.Core        11.2.0.12483642

VMware.VimAutomation.Common        1.2.0.12483627

VMware.VimAutomation.Core              11.2.0.12483638

VMware.VimAutomation.Sdk                11.2.0.12483635

VMware.VimAutomation.Vds                11.2.0.12483615

Thanks!

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That is currently the latest PowerCLI version, so you should be ok there.

Could it be that the NFS datastore is not known on the target ESXi node.

Can you try changing that line to

   $destinationDatastore = Get-Datastore $row.Datastore -RelatedObject  $destinationEsx


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

BjornJohansson
Enthusiast
Enthusiast
Jump to solution

That was it! Smiley Happy

I had to make a small adjustment, replacing Datastore to DestinationDs and it works as expected!

$destinationDatastore = Get-Datastore $row.DestinationDs -RelatedObject  $destinationEsx

Thanks again, really appreciate your help. Saved me a lot of time! Cheers!

Reply
0 Kudos