VMware Cloud Community
GrantBrunton
Enthusiast
Enthusiast
Jump to solution

Clone VM and Change from dvSwitch Network

I am currently in the process of creating a script to automate the creation of several VM environments however I have hit upon a snag.

Our current production and preproduction servers that I am cloning into the new environment use dvSwitch networks which do not exist on the server I am cloning to.

With ESX 4.1 you cannot clone a VM to a server that does not have the dvSwitch available on it although when cloning the server via vSphere, you can select the option on the last page to customise the virtual hardware and reconfigure the network adapter to use a vSwitch network and it will clone successfully.

Unfortunately when using the New-VM PowerCLI command the -NetworkName option is not part of the same ParameterSet as the -VM option so you cannot alter the network of the VM when using this command.

If I cannot alter the network during the cloning then the process will fail as the dvSwitch network is not available.

I know I can change the network after cloning using Set-NetworkAdapter but this is no use to me if the initial clone fails.

At this stage it looks like my only option is to clone the server to the local server, change the network and then migrate it to the new server but this is not a feasible option in a script to automate the creation of multiple guests at once.

Is there any other options available to me?

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

This is just one way of doing it, but it should give you an idea of the process.

The VM we clone is called TestVM and we will clone it to a VM called TestVMClone.

To avoid having to construct the NIC device from scratch, I use the NIC of a sample VM that is already connected to the portgroup. This VM is called SampleVM in the script.

$origVM = Get-VM -Name TestVM
$nicLabel = "Network adapter 1"
$folder = Get-Folder "Target Folder" $sampleVM = Get-VM -Name SampleVM
$sampleNic = $sampleVM.ExtensionData.Config.Hardware.Device |
  where {$_.DeviceInfo.Label -eq "Network adapter 1"} $spec = New-Object VMware.Vim.VirtualMachineCloneSpec
$spec
.Config = New-Object VMware.Vim.VirtualMachineConfigSpec

$nicDev
= New-Object VMware.Vim.VirtualDeviceConfigSpec
$nicDev.Operation = "edit"
$nicDev.device = $origVM.ExtensionData.Config.Hardware.Device |
  where {$_.DeviceInfo.Label -eq $nicLabel} $nicDev.device.Backing = $sampleNic.Backing
$nicDev
.device.DeviceInfo.Summary = $sampleNic.DeviceInfo.Summary
$spec
.Config.DeviceChange += $nicDEV
$spec
.Location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.PowerOn = $false
$spec
.Template = $false
$vm
.ExtensionData.CloneVM($folder.ExtensionData.MoRef,"TestVMClone",$spec)


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

View solution in original post

0 Kudos
7 Replies
LucD
Leadership
Leadership
Jump to solution

Yes, the implementation of the New-VM and it's CloneVM parameterset is a choice of the PowerCLI Dev Team.

It doesn't use all the possibilities that the CloneVM_Task method offers.

If you look at the VirtualMachineCloneSpec object, that is passed as a parameter to CloneVM_Task, you'll notice the config.deviceChange property.

Behind this property there is a VirtualDeviceConfigSpec object, that allows you to add or remove, but also edit a virtual device during the clone process.

But this means that you will have to do some SDK API coding in PowerShell instead of just using the New-VM cmdlet.

Let me know if you need some help with the script ?


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

GrantBrunton
Enthusiast
Enthusiast
Jump to solution

Thanks, that at least shows me there are some options!

If you could show me a simple example of performing a clone task using that and setting an existing adapter to a different network that would be exteremely helpful.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

This is just one way of doing it, but it should give you an idea of the process.

The VM we clone is called TestVM and we will clone it to a VM called TestVMClone.

To avoid having to construct the NIC device from scratch, I use the NIC of a sample VM that is already connected to the portgroup. This VM is called SampleVM in the script.

$origVM = Get-VM -Name TestVM
$nicLabel = "Network adapter 1"
$folder = Get-Folder "Target Folder" $sampleVM = Get-VM -Name SampleVM
$sampleNic = $sampleVM.ExtensionData.Config.Hardware.Device |
  where {$_.DeviceInfo.Label -eq "Network adapter 1"} $spec = New-Object VMware.Vim.VirtualMachineCloneSpec
$spec
.Config = New-Object VMware.Vim.VirtualMachineConfigSpec

$nicDev
= New-Object VMware.Vim.VirtualDeviceConfigSpec
$nicDev.Operation = "edit"
$nicDev.device = $origVM.ExtensionData.Config.Hardware.Device |
  where {$_.DeviceInfo.Label -eq $nicLabel} $nicDev.device.Backing = $sampleNic.Backing
$nicDev
.device.DeviceInfo.Summary = $sampleNic.DeviceInfo.Summary
$spec
.Config.DeviceChange += $nicDEV
$spec
.Location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.PowerOn = $false
$spec
.Template = $false
$vm
.ExtensionData.CloneVM($folder.ExtensionData.MoRef,"TestVMClone",$spec)


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

0 Kudos
GrantBrunton
Enthusiast
Enthusiast
Jump to solution

Thanks a lot for that, that's absolutely perfect!

I'm sure I can figure out everything else I need from that.

I'll let you know if I have any extra questions about specifics Smiley Wink

0 Kudos
GrantBrunton
Enthusiast
Enthusiast
Jump to solution

This is fully working now thanks to LucD.

The final script for the part that does the cloning looks something like this:

$vmName = "NewServer"
$selectedHostObj = Get-VMHost "TargetServer"
$selectedDatastoreObj = Get-Datastore "TargetDatastore"
      
$origVM = Get-VM -Name "FromServer"
$folder = Get-Datacenter -VMHost $selectedHostObj | Get-Folder "MyFolder"
$sampleNic = (Get-Template -Name "TemplateServer").ExtensionData.Config.Hardware.Device | where {$_.DeviceInfo.Label -eq "Network adapter 1"} $spec = New-Object VMware.Vim.VirtualMachineCloneSpec $spec.Config = New-Object VMware.Vim.VirtualMachineConfigSpec
$origNics = $origVM.ExtensionData.Config.Hardware.Device | where {$_.DeviceInfo.Label.StartsWith("Network adapter")} foreach ($dev in $origNics) {     $nicDev = New-Object VMware.Vim.VirtualDeviceConfigSpec
    $nicDev.Operation = "edit"
    $nicDev.device = $dev
    $nicDev.device.Backing = $sampleNic.Backing     $nicDev.device.DeviceInfo.Summary = $sampleNic.DeviceInfo.Summary     $spec.Config.DeviceChange += $nicDEV
}
$spec.Location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$spec.Location.Datastore = $selectedDatastoreObj.ExtensionData.MoRef $spec.Location.Host = $selectedHostObj.ExtensionData.MoRef $spec.Location.Pool = ($selectedHostObj | Get-ResourcePool "Resources").ExtensionData.MoRef $spec.Location.Transform = [Vmware.Vim.VirtualMachineRelocateTransformation]::sparse
$spec.PowerOn = $false
$spec.Template = $false
$origVM.ExtensionData.CloneVM_Task($folder.ExtensionData.MoRef,$vmName,$spec)

ps. How did you get that nice coloured syntax highlighting?

EDIT: Fixed syntax highlighting

0 Kudos
LucD
Leadership
Leadership
Jump to solution

GrantBrunton
Enthusiast
Enthusiast
Jump to solution

Thanks again :smileygrin:

0 Kudos