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?
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
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)
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...
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
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
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.
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?
Is there anything in the vmware.log around the time when you remove the NIC ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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"?
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
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 | ||||||||
Name | NetworkName | Type | Parent | |||||
Network adapter 1 | dummy | Vmxnet3 | test01 | |||||
Network adapter 2 | dummy | e1000 | test01 | |||||
Network adapter 3 | VLAN123 | Vmxnet3 | test01 | |||||
Network adapter 4 | VLAN234 | e1000 | test01 | |||||
Network adapter 5 | dummy | Vmxnet3 | test01 | |||||
Network adapter 6 | dummy | Vmxnet3 | test01 |
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
I guess it's friday, easy to get sleepy...
Thanks mate, it works great. All "dummy"-NIC's were removed while the others stayed.
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
How does your CSV look like?
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
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
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
Works!
Thanks very much.
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?