PowerCLI

 View Only
Expand all | Collapse all

Removing Network Adapters from Powered On VM's

  • 1.  Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 08:04 AM

    I wanted to remove Network Adapters from multiple VM's, so I thought a simple script would do it:

    Get-NetworkAdapter -vm test* | ?{$_.NetworkName -like "dummy"} |Remove-NetworkAdapter

    But this only results in error because the VM is powered on:

    Remove-NetworkAdapter : 2013-08-13 15:58:48    Remove-NetworkAdapter        The

    VM must be in the following state: PoweredOff.

    Is it possible to get around this?

    Since this is possible through the vSphere Client it gave me the chance to try out Onyx. Below is the result from Onyx:

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

    $spec.changeVersion = "2013-08-14T07:04:15.86208Z"

    $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)

    $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec

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

    $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualVmxnet3

    $spec.deviceChange[0].device.key = 4000

    $spec.deviceChange[0].device.deviceInfo = New-Object VMware.Vim.Description

    $spec.deviceChange[0].device.deviceInfo.label = "Network adapter 1"

    $spec.deviceChange[0].device.deviceInfo.summary = "dummy"

    $spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualEthernetCardNetworkBackingInfo

    $spec.deviceChange[0].device.backing.deviceName = "dummy"

    $spec.deviceChange[0].device.backing.useAutoDetect = $false

    $spec.deviceChange[0].device.backing.inPassthroughMode = $false

    $spec.deviceChange[0].device.connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo

    $spec.deviceChange[0].device.connectable.startConnected = $true

    $spec.deviceChange[0].device.connectable.allowGuestControl = $false

    $spec.deviceChange[0].device.connectable.connected = $true

    $spec.deviceChange[0].device.connectable.status = "ok"

    $spec.deviceChange[0].device.controllerKey = 100

    $spec.deviceChange[0].device.unitNumber = 7

    $spec.deviceChange[0].device.addressType = "assigned"

    $spec.deviceChange[0].device.macAddress = "00:50:56:8f:74:52"

    $spec.deviceChange[0].device.wakeOnLanEnabled = $false

    $_this = Get-View -Id 'VirtualMachine-vm-646'

    $_this.ReconfigVM_Task($spec)

    After stripping this down a bit I were left with:

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

    $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)

    $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec

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

    $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualVmxnet3

    $spec.deviceChange[0].device.key = 4000

    $spec.deviceChange[0].device.deviceInfo = New-Object VMware.Vim.Description

    $spec.deviceChange[0].device.deviceInfo.label = "Network adapter 1"

    $spec.deviceChange[0].device.deviceInfo.summary = "dummy"

    $_this = Get-View -Id 'VirtualMachine-vm-646'

    $_this.ReconfigVM_Task($spec)

    Running this doesn't give any errors, but still all Network Adapters remain.

    Is there any easy/better way to script this?



  • 2.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 08:31 AM

    You can try the following PowerCLI script to remove a network adapter from a virtual machine.

    $VM = Get-VM -Name "YourVM"

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec 

    $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1) 

    $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec 

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

    $spec.deviceChange[0].device = $VM.ExtensionData.Config.Hardware.Device |

      Where-Object {$_.DeviceInfo.Label -eq "Network adapter 1"}

    $VM.ExtensionData.ReconfigVM_Task($spec)



  • 3.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 08:59 AM

    Thanks for quick reply Robert, but the script runs and shows in the tasks log, but the NIC is still not removed - same as when I ran the Onyx script.

    However, if I power off the machine and run the script it does the trick...



  • 4.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 09:00 AM

    Hmm, when running it in the production environment instead of my test environment it works fine... I'll have to look into this. Both environments run on the same versions as well:

    PowerCLI> Get-PowerCLIVersion

    PowerCLI Version

       VMware vSphere PowerCLI 5.1 Release 2 build 1012425

    PowerCLI> $psversiontable

    Name                           Value

    ----                           -----

    PSVersion                      3.0

    WSManStackVersion              3.0

    SerializationVersion           1.1.0.1

    CLRVersion                     4.0.30319.18034

    BuildVersion                   6.2.9200.16481

    PSCompatibleVersions           {1.0, 2.0, 3.0}

    PSRemotingProtocolVersion      2.2



  • 5.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 11:07 AM

    Could it be that the NIC hot removal is disabled in your environment.

    See NIC is missing in my Virtual Machine

    What is the vmware.log of the VM saying when you run the script ?



  • 6.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 11:53 AM

    Thanks Luc for showing interest.

    However, from the article:

    Note:Remember disabling hotplug means you can neither add not remove a device from virtual machine in powered on state.

    It is still fully possible to add NIC's.



  • 7.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 12:57 PM

    Is there anything in the vmware.log around the time when you remove the NIC ?



  • 8.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 16, 2013 06:25 AM

    It seems that there needs to be an Guest OS installed for this command to work.

    This might be quite obvious, but I don't always bother to install OS on my VM's in my test environment since I'm also creating a script to provision multiple VM's and constantly adding/removing VM's.

    2013-08-16T06:01:15.754Z| vmx| W110: Requesting hot-remove of ethernet1

    2013-08-16T06:01:17.558Z| vcpu-0| I120: Msg_Post: Warning

    2013-08-16T06:01:17.558Z| vcpu-0| I120: [msg.Backdoor.OsNotFound] No operating system was found. If you have an operating system installation disc, you can insert the disc into the system's CD-ROM drive and restart the virtual machine.

    Any ideas on why the script only removes 1 NIC instead of all (up to 5) NIC's with Network Lable/Port Group Name "dummy"?



  • 9.  RE: Removing Network Adapters from Powered On VM's
    Best Answer

    Posted Aug 16, 2013 09:33 AM

    You need to create an entry in the DeviceChange property per device you want to reconfigure.

    Try something like this

    $VMs = Get-VM test*

    $NICs = 1..6 | %{"Network Adapter $_"}
    $i = 0

    foreach($VM in $VMs){
     
    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
     
    $Adapters = Get-NetworkAdapter -VM $VM|?{$_.NetworkName -like "dummy"}
     
    foreach($Adapter in $Adapters){
       
    if($NICs -contains $Adapter){
         
    $devSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec
         
    $devSpec.operation = "remove"
         
    $devSpec.device += $Adapter.ExtensionData
         
    $spec.deviceChange += $devSpec
        }
      }
     
    $VM.ExtensionData.ReconfigVM_Task($spec)
    }


  • 10.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 16, 2013 12:28 PM

    I figured it might have had something to do with the array, but had no idea how to tackle it.

    Thanks for the input, and it seems to run, however still only 1 NIC was actually removed and there was an error on the last instance:

    Name: Reconfigure virtual machine

    Target: test01

    Status: Completed

    Completed Time: 2013-08-16 13:09:45

    Name: Reconfigure virtual machine

    Target: test01

    Status: Completed

    Completed Time: 2013-08-16 13:09:49

    Name: Reconfigure virtual machine

    Target: test01

    Status: Completed

    Completed Time: 2013-08-16 13:09:54

    Name: Reconfigure virtual machine

    Target: test01

    Status: Cannot find the device '0', which is referenced in the edit or remove device operation.

    Completed Time: 2013-08-16 13:09:56

    Here's the test VM:

    Get-NetworkAdapter -VM test01 | select Name, NetworkName, Type, Parent | sort Name | ft -auto
    NameNetworkNameTypeParent
    Network adapter 1dummyVmxnet3test01
    Network adapter 2dummye1000test01
    Network adapter 3VLAN123Vmxnet3test01
    Network adapter 4VLAN234e1000test01
    Network adapter 5dummyVmxnet3test01
    Network adapter 6dummyVmxnet3test01


  • 11.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 16, 2013 12:42 PM

    My mistake, I placed the call to the method at the wrong spot.

    I corrected the code above, have another go.



  • 12.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 16, 2013 12:59 PM

    I guess it's friday, easy to get sleepy...

    Thanks mate, it works great. All "dummy"-NIC's were removed while the others stayed.



  • 13.  RE: Removing Network Adapters from Powered On VM's

    Posted Oct 18, 2015 10:27 AM

    Hi,

    I know this is a bit outdated, but perhaps someone can help me as I recently came across the needs of this post...

    I'm having trouble with LucD's script on the line of the acutal "action": $vm.ExtensionData.ReconfigVM_Task($spec)

    Getting the following error (cropped):

    You cannot call a method on a null-valued expression.

    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

    + FullyQualifiedErrorId : InvokeMethodOnNull

    This is my script modified with our needs :

    $vms = Import-CSV D:\temp\martin\rotem\removenetwork.csv

    Connect-VIServer ***********

    foreach ($vm in $vms){

                 $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

      $adapter = Get-NetworkAdapter -VM $vm.name | ?{$_.NetworkName -like "*****************"}

      $devSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec

      $devSpec.operation = "remove"

      $devSpec.device += $adapter.ExtensionData

      $spec.deviceChange += $devSpec

      $vm.ExtensionData.ReconfigVM_Task($spec)

      #Remove-NetworkAdapter -NetworkAdapter $adapter -Confirm:$false

      }

    Disconnect-VIServer -Confirm:$false



  • 14.  RE: Removing Network Adapters from Powered On VM's

    Posted Oct 19, 2015 07:53 AM

    How does your CSV look like?



  • 15.  RE: Removing Network Adapters from Powered On VM's

    Posted Oct 20, 2015 07:28 AM

    From the error message it looks as if the variable $vm holds a $null value.

    It looks as if your input contains a VmName of the VM that is not present in the environment to which you are connected



  • 16.  RE: Removing Network Adapters from Powered On VM's

    Posted Oct 22, 2015 08:40 AM

    I was skeptical about this but decided to give it a try anyway..

    Changed the script to not to use the csv file and insted only gave 1 VM (that shows on the vcenter by the same name).

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

    $vm = "THIS_IS_MY_VM"

    $adapter = Get-NetworkAdapter -VM $vm | ?{$_.NetworkName -like "FAKE-NETWORK"}

    $devSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec

    $devSpec.operation = "remove"

    $devSpec.device += $adapter.ExtensionData

    $spec.deviceChange += $devSpec

    $vm.ExtensionData.ReconfigVM_Task($spec)

    Still, the same error :

    You cannot call a method on a null-valued expression.

    At D:\temp\martin\removenetwork.ps1:15 char:5

    +              $vm.ExtensionData.ReconfigVM_Task($spec)

    +              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException

        + FullyQualifiedErrorId : InvokeMethodOnNull



  • 17.  RE: Removing Network Adapters from Powered On VM's

    Posted Oct 22, 2015 09:05 AM

    You need the VM object, not the VM name.

    Use these lines instead

    $vmName = "THIS_IS_MY_VM"

    $vm = Get-VM -Name $vmName



  • 18.  RE: Removing Network Adapters from Powered On VM's

    Posted Oct 22, 2015 10:03 AM

    Works!

    Thanks very much.



  • 19.  RE: Removing Network Adapters from Powered On VM's

    Posted Mar 21, 2022 11:48 AM

     

    Hi LucD is it possible to do first disconnection of the network adapter instead "remove" it?

    i see that VirtualDeviceConfigSpecOperation has three options: - add - edit - remove

    i tried modify your code like this:

     

    Foreach($VM in $vms){
        $spec = New-Object VMware.Vim.VirtualMachineConfigSpec  # for powered on vm, You need to create an entry in the DeviceChange property per device you want to reconfigure
        $nics = Get-NetworkAdapter -VM $VM
            foreach($nic in $nics){
                if($nic.MacAddress -eq $MacAddrs){
                    $devSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec
                    $devSpec.operation = "edit"
                    $devSpec.device += $nic.ExtensionData
                    $devSpec.device.Connectable = $nic.ConnectionState.Connected = $false
                    $spec.deviceChange += $devSpec
    
    
                }
            }
            $VM.ExtensionData.ReconfigVM_Task($spec)
    }

     

    but for this line

    $devSpec.device.Connectable = $nic.ConnectionState.Connected = $false

    i got below error
    'Connected' is a ReadOnly property.
    At line:1 char:1
    + $devSpec.device.Connectable = $nic.ConnectionState.Connected = $false
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyAssignmentException

    so i do not know how to push "disconnect" command to ReconfigVM_Task($spec).

    Could you please help me out with this?



  • 20.  RE: Removing Network Adapters from Powered On VM's

    Posted Mar 21, 2022 12:17 PM

    Not sure why you have this

    $devSpec.device.Connectable = $nic.ConnectionState.Connected = $false

     

    This works for me (the VM only has 1 vNIC).

    $vm = Get-VM -Name MyVM
    $vnic = Get-networkadapter -VM $vm
    
    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
    $dev.Operation = 'edit'
    $dev.Device = $vnic.ExtensionData
    $dev.Device.Connectable.Connected = $false
    
    $spec.DeviceChange += $dev
    
    $vm.ExtensionData.ReconfigVM($spec)

      



  • 21.  RE: Removing Network Adapters from Powered On VM's

    Posted Mar 21, 2022 01:05 PM

    thank you LucD for quick replay.

    i got this error:
    $vm.ExtensionData.ReconfigVM($spec)
    You cannot call a method on a null-valued expression.
    At line:1 char:1
    + $vm.ExtensionData.ReconfigVM($spec)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull



  • 22.  RE: Removing Network Adapters from Powered On VM's

    Posted Mar 21, 2022 01:11 PM

    i found the issue in my script.

    Thank you for support.

    no more questions.



  • 23.  RE: Removing Network Adapters from Powered On VM's

    Posted Aug 14, 2013 12:55 PM

    Robert, I worked your script a bit to try and remove all NIC's with a certain port group name (e.g. an entire VLAN) and ended up with the following:

    $VMs = Get-VM test*

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

    $spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)

    $spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec

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

    $NICs = "Network Adapter 1","Network Adapter 2","Network Adapter 3","Network Adapter 4","Network Adapter 5"

    $i = 0

    foreach($VM in $VMs){

        $Adapters = Get-NetworkAdapter -VM $VM|?{$_.NetworkName -like "dummy"}

        foreach($Adapter in $Adapters){

            while ($i -le 4){

                if($Adapter -like $NICs[$i]){

                    $spec.deviceChange[0].device = $VM.ExtensionData.Config.Hardware.Device | ?{$_.DeviceInfo.Label -eq $NICs[$i]}

                    $VM.ExtensionData.ReconfigVM_Task($spec)

                    $i++

                }

                else{

                    $i++

                }

            }

        }

    }

    Probably not the prettiest code, but since $_.DeviceInfo.Lable is mandatory I couldn't switch it to $_.DeviceInfo.Summary -eq "Dummy".

    However, above code only removes one NIC, for some reason the loop seems to end after first "hit". Can you see what I'm missing?