Highlighted
Enthusiast
Enthusiast

Copy RDM setting to second VM

Jump to solution

Hi all,

I have been tasked with migrating a 4 digit number of VMs to new data stores. A couple of hundred of these have anywhere from 2 to 40+ RDMs shared between 2 VMs. The migration requires the RDMs to be unmapped from 1 node, migrated and then be remapped since the migration updates the pointers.

Now, as of today the admins copy the info form the vSphere client and make a text document to keep track.

I found this little gem, and run PowerCLI to extract the info:

$DiskInfo= @()

foreach ($VMview in Get-VM node01 | Get-View){

foreach ($VirtualSCSIController in ($VMView.Config.Hardware.Device | where {$_.DeviceInfo.Label -match "SCSI Controller"})) {

foreach ($VirtualDiskDevice in ($VMView.Config.Hardware.Device | where {$_.ControllerKey -eq $VirtualSCSIController.Key})) {

$VirtualDisk = "" | Select VMname, SCSIController, DiskName, SCSI_ID, DeviceName, DiskFile, DiskSize

$VirtualDisk.VMname = $VMview.Name

$VirtualDisk.SCSIController = $VirtualSCSIController.DeviceInfo.Label

$VirtualDisk.DiskName = $VirtualDiskDevice.DeviceInfo.Label

$VirtualDisk.SCSI_ID = "$($VirtualSCSIController.BusNumber) : $($VirtualDiskDevice.UnitNumber)"

$VirtualDisk.DeviceName = $VirtualDiskDevice.Backing.DeviceName

$VirtualDisk.DiskFile = $VirtualDiskDevice.Backing.FileName

$VirtualDisk.DiskSize = $VirtualDiskDevice.CapacityInKB * 1KB / 1GB

$DiskInfo += $VirtualDisk

}}}

$DiskInfo | sort VMname, Diskname | Export-Csv -Path 'd:\temp\diskinfo.csv'

Now, the next logical step would be to take this info, import the .csv and apply this info to node02?

I came across LucD's code that does some of it, but requires that you know the file path of each RDM:

$vm1 = Get-VM -Name node01

$vm2 = Get-VM -Name node02

$DeviceName = "/vmfs/devices/disks/naa.600507680180701ed00000000000124"

$hd1 = New-HardDisk -VM $vm1 -DeviceName $DeviceName -DiskType RawVirtual

$ctrl1 = New-ScsiController -HardDisk $hd -BusSharingMode Virtual -Type VirtualLsiLogicSAS

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$spec.DeviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec

$spec.deviceChange[0].device += $ctrl1.ExtensionData

$spec.deviceChange[0].device.Key = -101

$spec.deviceChange[0].operation = "add"

$spec.DeviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec

$spec.deviceChange[1].device += $hd1.ExtensionData

$spec.deviceChange[1].device.Key = -102

$spec.deviceChange[1].device.ControllerKey = -101

$spec.deviceChange[1].operation = "add"

$vm2.ExtensionData.ReconfigVM($spec)

I there an easy way to do this?

Someone has probably done this already, I just can't find it. Probably me searching skills that suck.

0 Kudos
1 Solution

Accepted Solutions
Highlighted
User Moderator
User Moderator

Assuming the SCSI controllers are present on node 2 and assuming this is for a cluster-in-a-box, can you try the following?

$node01Name = 'Node01'

$node02Name = 'Node02'


$vm1 = Get-VM -Name $node01Name

$vm2 = Get-VM -Name $node02Name


$spec = New-Object VMware.Vim.VirtualMachineConfigSpec


Get-HardDisk -VM $vm1 -DiskType RawPhysical,RawVirtual -PipelineVariable hd |

ForEach-Object -Process {

   $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec

   $disk = New-Object VMware.Vim.VirtualDisk


   $back = New-Object VMware.Vim.VirtualDiskRawDiskMappingVer1BackingInfo

   $back.FileName = $hd.ExtensionData.Backing.FileName

   $back.DiskMode =  [VMware.Vim.VirtualDiskMode]::independent_persistent

   $back.Sharing = [VMware.Vim.VirtualDiskSharing]::sharingNone

   $disk.Backing = $back


   $disk.ControllerKey = $hd.ExtensionData.ControllerKey

   $disk.UnitNumber = $hd.ExtensionData.UnitNumber

   $disk.Key = -($spec.DeviceChange.Count + 1)

   $dev.Device = $disk


   $dev.Operation = [VMware.Vim.VirtualDeviceConfigSpecOperation]::add

   $spec.DeviceChange += $dev  

}


$vm2.ExtensionData.ReconfigVM($spec)


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

View solution in original post

0 Kudos
11 Replies
Highlighted
User Moderator
User Moderator

Not too sure what the actual question is here I'm afraid.


Is it how to automate that 2nd piece of code to run automatically for all RDMs on the old datastore(s)?


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

0 Kudos
Highlighted
Enthusiast
Enthusiast

Sorry, I had to write this post multiple times.

I need to automate the second piece of code to add each RDM from node 01, using the same

  • SCSI Controller
  • SCSI ID
  • Disk Name
  • Disk File

to node 02.

Was that better? I have been wracking my brains to come up with a way, but I just keep making a mess of it Smiley Wink (to the extent that I couldn't even ask a proper question)

0 Kudos
Highlighted
User Moderator
User Moderator

Ok, clearer now.
Just one more question, what do 'node 01' and 'node 02' represent?

Clusters, collections of datastores...?


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

0 Kudos
Highlighted
Enthusiast
Enthusiast

They are 2 nodes in a Windows cluster. (most frequently SQL)

The migration process works as follows:

  1. unmap all RDMs from node02
  2. migrate node02 to a new data store
  3. shut down node01
  4. migrate node01 to new data store (this updates the RDM pointers)
  5. Power on node01
  6. Extract info on RDMs from node01
  7. Apply the same settings to node02
  8. Power on node02 and it should work.

Step 7 with 38 RDMs takes a long, long time to do, hence my automation desire.

The GUI settings looks like this:

pastedImage_1.png

0 Kudos
Highlighted
User Moderator
User Moderator

How would the script know about node01 and node02?

Do they follow a naming convention?

Are their names available in an external file (.TXT, .CSV ...)?

A script should be able to find the nodes since it would allow retrieving the canonicalname (device name) of the LUNs used for the RDMs.


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

0 Kudos
Highlighted
Enthusiast
Enthusiast

First, let me clarify that node01 and node02 are the actual VM names I gave my VMs in the lab.

node01 is part of the output in the first piece of code (I did an out-gridview just to show the output)

node01    Hard disk 2    9,99999523162841796875    [SSD] node01/node01_1.vmdk    vml.010014000031303030303030310000000000000000695343534920    naa.6589cfc000000a7b3a8f10159174c0e5  

node01    Hard disk 3    9,99999523162841796875    [SSD] node01/node01_2.vmdk    vml.010015000031303030303030310000000000000000695343534920    naa.6589cfc00000070d95dc963ed39243e8  

node01    Hard disk 4    9,99999523162841796875    [SSD] node01/node01_3.vmdk    vml.010016000031303030303030310000000000000000695343534920    naa.6589cfc000000d83a44ee6700c98d3b1  

node01    Hard disk 5    9,99999523162841796875    [SSD] node01/node01_4.vmdk    vml.010017000031303030303030310000000000000000695343534920    naa.6589cfc000000a6c3482eb9f034b8351  

And since I only do this for one cluster at a time, I thought I could ust put the VM name(s) in a Get-VM statement, and just change it when I move on to a new cluster?

$vm1 = Get-VM -Name node01

$vm2 = Get-VM -Name node02

Changing the names is doable per cluster, right?

For now I am just trying to eliminate the tedious re-mapping of RDM pointers, and very little else.

0 Kudos
Highlighted
User Moderator
User Moderator

Correct.
Let's see if I can help in automating that part then


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

0 Kudos
Highlighted
Enthusiast
Enthusiast

Thank you!

If you, The All Powerful Grand Wizard of PowerCLI can't do it, I don't think it can be done Smiley Wink

0 Kudos
Highlighted
User Moderator
User Moderator

More questions I'm afraid.

Looking at your screenshot, I deduce that the MSCS cluster is a so-called 'cluster in a box', meaning both nodes run on the same ESXi node?

Also, after the migration of node02, I assume that the SCSI controllers are gone (since you removed the RDMs before the migration)?

Meaning they should be recreated as well.


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

0 Kudos
Highlighted
User Moderator
User Moderator

Assuming the SCSI controllers are present on node 2 and assuming this is for a cluster-in-a-box, can you try the following?

$node01Name = 'Node01'

$node02Name = 'Node02'


$vm1 = Get-VM -Name $node01Name

$vm2 = Get-VM -Name $node02Name


$spec = New-Object VMware.Vim.VirtualMachineConfigSpec


Get-HardDisk -VM $vm1 -DiskType RawPhysical,RawVirtual -PipelineVariable hd |

ForEach-Object -Process {

   $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec

   $disk = New-Object VMware.Vim.VirtualDisk


   $back = New-Object VMware.Vim.VirtualDiskRawDiskMappingVer1BackingInfo

   $back.FileName = $hd.ExtensionData.Backing.FileName

   $back.DiskMode =  [VMware.Vim.VirtualDiskMode]::independent_persistent

   $back.Sharing = [VMware.Vim.VirtualDiskSharing]::sharingNone

   $disk.Backing = $back


   $disk.ControllerKey = $hd.ExtensionData.ControllerKey

   $disk.UnitNumber = $hd.ExtensionData.UnitNumber

   $disk.Key = -($spec.DeviceChange.Count + 1)

   $dev.Device = $disk


   $dev.Operation = [VMware.Vim.VirtualDeviceConfigSpecOperation]::add

   $spec.DeviceChange += $dev  

}


$vm2.ExtensionData.ReconfigVM($spec)


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

View solution in original post

0 Kudos
Highlighted
Enthusiast
Enthusiast

Thank you!

I cannot put into words how awesome your PowerCLI skills are!

This will probable save us hundreds of hours of very tedious work.

0 Kudos