3 Replies Latest reply on May 4, 2011 9:13 AM by IanGibbs

    Change vnic-portgroup Assignment during Clone operation

    OlivierD Novice





      I've got a powershell script that creates VMs from a Template, and I want to change the vnic-portgroup



      assignement in my Clone Specification.



      $vmcSpec = New-Object VMware.Vim.VirtualMachineCloneSpec

      $vmspec.Config = New-Object VMware.Vim.VirtualMachineConfigSpec



      How can access to the nic configuration through $vmspec.Config ? With deviceChange property ?



      Thanks for your help









        • 1. Re: Change vnic-portgroup Assignment during Clone operation
          LucD Guru
          Community WarriorsvExpertUser Moderators

          Yes, you will have to use the VirtualDeviceConfigSpec via the deviceChange property.

          A useful trick is to first find the device in question and then just change the required properties.

          In this case only the network (portgroup) needed to be changed

          $templateName = <template-name>
          $newVM = <VM-name>
          $esxName = <ESX-hostname>
          $poolName = <resourcepoolname>
          $nicName = <NIC-name>                                # Ex "Virtual Ethernet Adapter"
          $newPGName = <new-portgroup-name>
          $folderName = <foldername>
          $datastoreName = <datastorename>
          $fromVM = Get-View -Id (Get-Template $templateName).Id
          $folder = Get-Folder $folderName | Get-View
          $esx = Get-VMHost $esxName | Get-View
          foreach($pg in $esx.Network){
               if((Get-View $pg).Name  -eq $newPGName){
          $found = $false
          foreach($dev in $fromVM.Config.Hardware.Device){
               if($dev.DeviceInfo.Label -eq $nicName){
                    $found = $true
          $spec = New-Object VMware.Vim.VirtualMachineCloneSpec
          $spec.Config = New-Object VMware.Vim.VirtualMachineConfigSpec 
          $devSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec
          $devSpec.device = $dev
          $devSpec.Device.Backing.DeviceName = $newPGName
          $devSpec.Device.Backing.Network = $pg
          $devSpec.Operation = "edit"
          $spec.Config.deviceChange += $devSpec
          $spec.location = New-Object VMware.Vim.VirtualMachineRelocateSpec
          $spec.location.datastore = (Get-Datastore $datastoreName | Get-View).MoRef
          $spec.location.host = (Get-VMHost $esxName | Get-View).MoRef
          $spec.Location.Pool = (Get-ResourcePool $poolName | Get-View).MoRef
          $spec.powerOn = $false
          $spec.template = $false
          $fromVM.CloneVM_Task($folder.MoRef, $newVM, $spec)


          Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
          • 2. Re: Change vnic-portgroup Assignment during Clone operation
            OlivierD Novice

            Thank you for the tip.


            Here is the extract of my script (My template has 2 nics) :


            $vmcSpec = New-Object VMware.Vim.VirtualMachineCloneSpec

            $templateId = get-view -Id (Get-Template -Name $vmtemplate).Id


            $vmcSpec.Config = New-Object VMware.Vim.VirtualMachineConfigSpec


            #Create an array of VirtualDevice


            $nics = @(New-Object VMware.Vim.VirtualDevice)


            #Get Nics from template

            foreach ($dev in $templateId.Config.Hardware.Device ) {

                 if ($dev.DeviceInfo.Label -eq "Network Adapter 1" ) {

                      $nics[0] = $dev


                 if ($dev.DeviceInfo.Label -eq "Network Adapter 2" ) {

                      $nics += New-Object VMware.Vim.VirtualDevice

                      $nics[1] = $dev





            $nicSpec0 = New-Object VMware.Vim.VirtualDeviceConfigSpec

            $nicSpec0.device = $nics[0]

            $nicSpec0.Device.Backing.DeviceName = $nic0_pg

            $nicSpec0.Device.Backing.Network = $pg

            $nicSpec0.Operation = "edit"


            $vmcSpec.Config.deviceChange += $nicSpec0



            $nicSpec1 = New-Object VMware.Vim.VirtualDeviceConfigSpec

            $nicSpec1.device = $nics[1]

            $nicSpec1.Device.Backing.DeviceName = $nic1_pg

            $nicSpec1.Device.Backing.Network = $pg

            $nicSpec1.Operation = "edit"


            $vmcSpec.Config.deviceChange += $nicSpec1


            etc ....


            Thank you for your help



            • 3. Re: Change vnic-portgroup Assignment during Clone operation
              IanGibbs Enthusiast

              This example code won't work  in current versions of vCenter. Don't know if it ever did.


              1. "Property 'DeviceName' cannot be found on this object; make sure it exists and is settable."


              This will be the first error you get from this code. To resolve, replace


              $devSpec.Device.Backing.DeviceName = $newPGName




              $nicBacking = New-Object VMware.Vim.VirtualEthernetCardNetworkBackingInfo
              $nicBacking.deviceName = $newPGName
              $devSpec.Device.Backing = $nicBacking


              2. "Get-VMHost : Cannot validate argument on parameter 'Name'. The argument is null or empty."


              This will be your next error. To fix this, in each of the following lines (in various places), add -Name after the Get- cmdlet:


              a - $folder = Get-Folder $folderName | Get-View
              b - $esx = Get-VMHost $esxName | Get-View
              c - $spec.location.host = (Get-VMHost $esxName | Get-View).MoRef
              d - $spec.Location.Pool = (Get-ResourcePool $poolName | Get-View).MoRef



              such as


              $esx = Get-VMHost -Name $esxName | Get-View

              As a side note, if you don't have any resource pools in use, you can put the clone in the root of the cluster like this:


              $spec.Location.Pool = (Get-Cluster -Name $cluster_name | Get-ResourcePool -Name "Resources" | Get-View).MoRef