VMware Cloud Community
LittleNickey
Enthusiast
Enthusiast
Jump to solution

Removing Network Adapters from Powered On VM's

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?

-- Oskar
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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)
}


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

View solution in original post

0 Kudos
22 Replies
RvdNieuwendijk
Leadership
Leadership
Jump to solution

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)

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
LittleNickey
Enthusiast
Enthusiast
Jump to solution

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...

-- Oskar
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

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

-- Oskar
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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 ?


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

0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

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.

-- Oskar
0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

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?

-- Oskar
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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


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

LittleNickey
Enthusiast
Enthusiast
Jump to solution

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"?

-- Oskar
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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)
}


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

0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

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
-- Oskar
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

I corrected the code above, have another go.


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

0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

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

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

-- Oskar
0 Kudos
tinchito7
Contributor
Contributor
Jump to solution

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

0 Kudos
LittleNickey
Enthusiast
Enthusiast
Jump to solution

How does your CSV look like?

-- Oskar
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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


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

0 Kudos
tinchito7
Contributor
Contributor
Jump to solution

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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You need the VM object, not the VM name.

Use these lines instead

$vmName = "THIS_IS_MY_VM"

$vm = Get-VM -Name $vmName


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

0 Kudos
tinchito7
Contributor
Contributor
Jump to solution

Works!

Thanks very much.

0 Kudos
madey83
Contributor
Contributor
Jump to solution

@LucD 

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?

0 Kudos