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

    Change vnic-portgroup Assignment during Clone operation

    OlivierD Novice

       

      Hello,

       

       

      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

       

       

      Olivier

       

       

       

       

       

        • 1. Re: Change vnic-portgroup Assignment during Clone operation
          LucD Guru
          User ModeratorsvExpertCommunity Warriors

          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){
                    break
               }
          }
          
          $found = $false
          foreach($dev in $fromVM.Config.Hardware.Device){
               if($dev.DeviceInfo.Label -eq $nicName){
                    $found = $true
                    break
               }
          }
          
          $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)
          
          

           

          • 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

                 }

            }

             

            #Nic0

            $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

             

            #Nic1

            $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

             

            Olivier

            • 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
              

               

              with

               

              $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