VMware Cloud Community
scasillas2
Contributor
Contributor
Jump to solution

Adding copied harddisk (VMDK) to a VM

I'm new to PowerCLI and can't seem to find any 'newer' information on this process.

I'm attempting to automate the adding of a cloned hard drive (VMDK) from VM(1) to another existing VM(2).  I figured out how to "Copy-HardDisk" of VM1 to the datastore of VM2, but can't seem the formula to attach it to VM2.

To copy the disk, I'm using the following command:

     $vm1 = "vm1 name"

     $vm2 = "vm2 name"

     $ds = "datastore"

     Get-HardDisk -VM $vm1 | Where {$_.CapacityGB -lt 10} | Copy-HardDisk -DestinationPath "[$ds] $vm2/$vm2-2.vmdk" -Force

Here is actually what it looks like:

     Get-HardDisk -VM System1 | Where {$_.CapacityGB -lt 10} | Copy-HardDisk -DestinationPath "[NFS2] System2/System2-2.vmdk" -Force

The GUI way we do this today via vCenter is - Edit Setting s > Hardware tab > Add > Hard Disk > Use an existing virtual disk > Browse > Verify the Virtual Device Node (SCSI (0:x) -  and it works.  I can boot VM2 and the Windows OS works fine and everyone is happy.

To attach the hard disk via PowerCLI, I'm using the following command:

     New-HardDisk -VM $vm2 -DiskPath "[$ds] $vm2/$vm2-2.vmdk" 

Here is actually what it looks like:

     New-HardDisk -VM System2 -DiskPath "[NFS2] System2/System2-2.vmdk"

When I run the command, I see vCenter 'working' and then errors out with Incompatible device backing specified for device '0'.  I've ready many forums stating the error when doing a RDM or attempting to add a secondary SCSI controller which I don't want to do.

A few things to note:

     Needs to be on the default SCSI controller 0 (Virtual LSI Logic SAS)

     Virtual device node needs to be SCSI 0:2 (this would be a third drive on the system)

     The datastore is a different datastore than the other disks attached to VM2 (disks 1 and 2 are on NFS1, new disk would be on NFS2).

     When I first copy the disk, it states the Persistence as Unknown, not sure if this is a factor. Any help would be appreciated.

     ESXi, 5.0 Update 1 (5.0.0,821926)

     PowerCLI 5.5 Release 2

Thanks,

SC

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Lol, I'll type slowly :smileylaugh:

No, I'm afraid we can't change the API, nor the coding behind the cmdlet.

But we can call the API directly from within PowerCLI, something like this for example

function add-HD {
 
param($VMname, $Filename, $Controller)

 
$dsName = $Filename.Split(']')[0].TrimStart('[')
 
 
$vm = (Get-VM $VMname).ExtensionData
 
$ds = (Get-Datastore -Name $dsName).ExtensionData
 
 
foreach($dev in $vm.config.hardware.device){
   
if ($dev.deviceInfo.label -eq $Controller){
     
$CntrlKey = $dev.key
    }
  }
 
$Unitnumber = 0
 
$DevKey = 0

 
foreach($dev in $vm.config.hardware.device){
   
if ($dev.controllerKey -eq $CntrlKey){
     
if ($dev.Unitnumber -gt $Unitnumber){$Unitnumber = $dev.Unitnumber}
     
if ($dev.key -gt $DevKey) {$DevKey = $dev.key}
    }
  }

 
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
 
$spec.deviceChange = @()
 
$spec.deviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec
 
$spec.deviceChange[0].device = New-Object VMware.Vim.VirtualDisk
 
$spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo
 
$spec.deviceChange[0].device.backing.datastore = $ds.MoRef
 
$spec.deviceChange[0].device.backing.fileName = $Filename
 
$spec.deviceChange[0].device.backing.diskMode = "independent_persistent"
 
$spec.deviceChange[0].device.key = $DevKey + 1
 
## The UnitNUmber SCSIID 7 is reserved for the Controller - so ignore it and skip to 8.
  if ($Unitnumber -eq 6) {$Unitnumber = $Unitnumber + 1}
 
$spec.deviceChange[0].device.unitnumber = $Unitnumber + 1
 
$spec.deviceChange[0].device.controllerKey = $CntrlKey
 
$spec.deviceChange[0].operation = "add"
 
$vm.ReconfigVM_Task($spec)
}

Add-HD -VMname "System2" -FileName "[NFS2] System2/System2-2.vmdk" -Controller "SCSI Controller 0"

I created a function, called Add-HD, that will do more or less the same thing as the New-Harddisk cmdlet does when used with the Filename parameter, but instead of calling the cmdlet, the function calls the API method ReconfigVM_Task directly.

The disadvantage of this is, that we will have to compile the parameter that is passed to this method.

In fact, most of the PowerCLI cmdlets are doing exactly the same thing, they are calling the API methods.

You can see these calls when you trace a cmdlet with the Onyx tool.


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

View solution in original post

5 Replies
LucD
Leadership
Leadership
Jump to solution

Did you already try adding  "-Persistence Persistent" to the New-Harddisk cmdlet ?

I suspect the New-HardDisk cmdlet might be using an incorrect default in the underlying API it calls.


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

0 Kudos
scasillas2
Contributor
Contributor
Jump to solution

Attempted adding '-Persistence Persistent" as well as '-Controller "name"' with no luck.  Still getting Incompatible device backing specified for device '0'.

Tried the following with no luck:

     New-HardDisk -VM System2 -Persistence Persistent -DiskPath "[NFS2] System2/System2-2.vmdk"

     New-HardDisk -VM System2 -Persistence Persistent -Controller "SCSI controller 0" -DiskPath "[NFS2] System2/System2-2.vmdk"

Is there a way to correct the API's? (speak... slowly... please...)  Smiley Happy

Thanks for the quick responce LucD22.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Lol, I'll type slowly :smileylaugh:

No, I'm afraid we can't change the API, nor the coding behind the cmdlet.

But we can call the API directly from within PowerCLI, something like this for example

function add-HD {
 
param($VMname, $Filename, $Controller)

 
$dsName = $Filename.Split(']')[0].TrimStart('[')
 
 
$vm = (Get-VM $VMname).ExtensionData
 
$ds = (Get-Datastore -Name $dsName).ExtensionData
 
 
foreach($dev in $vm.config.hardware.device){
   
if ($dev.deviceInfo.label -eq $Controller){
     
$CntrlKey = $dev.key
    }
  }
 
$Unitnumber = 0
 
$DevKey = 0

 
foreach($dev in $vm.config.hardware.device){
   
if ($dev.controllerKey -eq $CntrlKey){
     
if ($dev.Unitnumber -gt $Unitnumber){$Unitnumber = $dev.Unitnumber}
     
if ($dev.key -gt $DevKey) {$DevKey = $dev.key}
    }
  }

 
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
 
$spec.deviceChange = @()
 
$spec.deviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec
 
$spec.deviceChange[0].device = New-Object VMware.Vim.VirtualDisk
 
$spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo
 
$spec.deviceChange[0].device.backing.datastore = $ds.MoRef
 
$spec.deviceChange[0].device.backing.fileName = $Filename
 
$spec.deviceChange[0].device.backing.diskMode = "independent_persistent"
 
$spec.deviceChange[0].device.key = $DevKey + 1
 
## The UnitNUmber SCSIID 7 is reserved for the Controller - so ignore it and skip to 8.
  if ($Unitnumber -eq 6) {$Unitnumber = $Unitnumber + 1}
 
$spec.deviceChange[0].device.unitnumber = $Unitnumber + 1
 
$spec.deviceChange[0].device.controllerKey = $CntrlKey
 
$spec.deviceChange[0].operation = "add"
 
$vm.ReconfigVM_Task($spec)
}

Add-HD -VMname "System2" -FileName "[NFS2] System2/System2-2.vmdk" -Controller "SCSI Controller 0"

I created a function, called Add-HD, that will do more or less the same thing as the New-Harddisk cmdlet does when used with the Filename parameter, but instead of calling the cmdlet, the function calls the API method ReconfigVM_Task directly.

The disadvantage of this is, that we will have to compile the parameter that is passed to this method.

In fact, most of the PowerCLI cmdlets are doing exactly the same thing, they are calling the API methods.

You can see these calls when you trace a cmdlet with the Onyx tool.


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

scasillas2
Contributor
Contributor
Jump to solution

You are invaluable LucD!!

The Add-HD function call works great.  I also took a look at Onyx, what a great tool!! 

Thanks for your assistance and introducing me to a great troubleshooting tool.

All the best,

SC

0 Kudos
kratos666
Contributor
Contributor
Jump to solution

This works flawlessly.

Thank you!

0 Kudos