When you use the Virtual Network Manager to create a new switch and assign it a physical Network Adapter, this NIC is assigned to the new switch exclusively and a new Virtual NIC is created in the parent partition. There might be confugurations where you might not want the parent partition to be connected to this network. The simplest way is to disable this virtual NIC or unbind all protocols.
However, with some scripting, you can create a new switch and connect a physical NIC without a virtual NIC created on the parent partition.
Here are the steps in vbscript.
1. Create a swich using the vb script on http://msdn.microsoft.com/en-us/library/cc136783(VS.85).aspx As paramter pass the switch name. E.g "HV LAN1"
2. Bind a unused NIC to the Virtual Switch using vb script on http://msdn.microsoft.com/en-us/library/cc136768(VS.85).aspx As Paramter pass the friendly NIC name. E.g. "Broadcom NetXtreme 57xx Gigabit Controller" which can be found on the NIC properties.
3. Create a port on the switch using the vb script on http://msdn.microsoft.com/en-us/library/cc136782(VS.85).aspx As Paramter pass the Switch name you used in 1. and a Port name. E,G "HV LAN1" "HVLAN1ExternalPort"
4. Connect the switch port to the NIC by using below script. As Paramter pass the Switch name you used in 1. the Port name from 3. and the NIC name from 2. e.g.: "HV LAN1" "HVLAN1ExternalPort" "Broadcom NetXtreme 57xx Gigabit Controller"
Now you should have a new switch connected to the external NIC. This Switch can now be used to connect NICs to your VMs only.
Cheers
-Robert
#ConnectSwitchPort2NIC.vbs
option explicit
dim objWMIServicedim switchServicedim fileSystem
const wmiStarted = 4096const wmiSuccessful = 0
Main()
'-----------------------------------------------------------------' Main'-----------------------------------------------------------------Sub Main() dim computer, objArgs dim switchFriendlyName, switchPortFriendlyName, switch, switchPort dim vmName, vmEthernetPortType, vmEthernetPortClassName dim NICFriendlyName, vmEthernetPort, vmEthernetPortEndPoint
set objArgs = WScript.Arguments if WScript.Arguments.Count = 3 then switchFriendlyName = objArgs.Unnamed.Item(0) switchPortFriendlyName = objArgs.Unnamed.Item(1) NICFriendlyName = objArgs.Unnamed.Item(2) else Usage() end if set fileSystem = Wscript.CreateObject("Scripting.FileSystemObject") computer = "."
set objWMIService = GetObject("winmgmts:\\" & computer & "\root\virtualization") set switchService = objWMIService.ExecQuery("select * from Msvm_VirtualSwitchManagementService").ItemIndex(0) set switch = GetVirtualSwitch(switchFriendlyName) if (switch Is Nothing) then WriteLog Format1("Unable to find switch {0}", switchFriendlyName) WScript.Quit(1) end if set switchPort = GetVirtualSwitchPort(switch, switchPortFriendlyName)
if (switchPort Is Nothing) then WriteLog Format1("Unable to find switchPort '{0}'", switchPortFriendlyName) WScript.Quit(1) end if
set vmEthernetPort = GetEthernetPort(NiCFriendlyName) if ConnectSwitchPort(switchPort, vmEthernetPort) then WriteLog "Done" WScript.Quit(0) else WriteLog "ConnectSwitchPort failed" WScript.Quit(1) end if
End Sub
'-----------------------------------------------------------------' Display command line help'-----------------------------------------------------------------Sub Usage()
WScript.Echo "usage: cscript ConnectSwitchPort SwitchFriendlyName " &_ "SwitchPortFriendlyName NiCName" WScript.Quit(1)
'-----------------------------------------------------------------' Retrieve VirtualSwitch '-----------------------------------------------------------------Function GetVirtualSwitch(friendlyName) dim query set GetVirtualSwitch = Nothing query = Format1("select * from Msvm_VirtualSwitch where ElementName = '{0}'", friendlyName) set GetVirtualSwitch= objWMIService.ExecQuery(query).ItemIndex(0)End Function
'-----------------------------------------------------------------' Retrieve VirtualSwitchPort'-----------------------------------------------------------------Function GetVirtualSwitchPort(switch, switchPortFriendlyName) dim query, switchPort, switchPorts set GetVirtualSwitchPort = Nothing query = Format1("ASSOCIATORS OF {{0}} WHERE resultClass = Msvm_SwitchPort", switch.Path_.Path) set switchPorts= objWMIService.ExecQuery(query) for each switchPort in switchPorts if lcase(switchPort.ElementName) = lcase(switchPortFriendlyName) then set GetVirtualSwitchPort = switchPort end if nextEnd Function
'-----------------------------------------------------------------' Get Ethernet port'-----------------------------------------------------------------Function GetEthernetPort(NicFriendlyName)dim strComputer, objWMIService, niccollecion, nic
set GetEthernetPort = Nothing
strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\virtualization") Set niccollecion = objWMIService.ExecQuery("SELECT * FROM CIM_LANEndpoint ",,48)
For Each nic in niccollecion
if lcase(nic.ElementName) = lcase(NicFriendlyName) then set GetEthernetPort = nic Wscript.Echo nic.ElementName end if Next
if (GetEthernetPort Is Nothing) then WriteLog Format1("Unable to find specified NIC", NicFriendlyName) WScript.Quit(1) end if End Function
'-----------------------------------------------------------------' Connect switch port with Ethernet endpoint'-----------------------------------------------------------------Function ConnectSwitchPort(switchPort, lanEndpoint) dim objInParam, objOutParams ConnectSwitchPort = false set objInParam = switchService.Methods_("ConnectSwitchPort").InParameters.SpawnInstance_() objInParam.LANEndPoint = lanEndpoint.Path_.Path objInParam.SwitchPort = switchPort.Path_.Path
set objOutParams = switchService.ExecMethod_("ConnectSwitchPort", objInParam) if objOutParams.ReturnValue = wmiSuccessful then ConnectSwitchPort = true else WriteLog Format1("ConnectSwitchPort failed with error code {0}", objOutParams.ReturnValue) end if
End Function
'-----------------------------------------------------------------' Create the console log files.'-----------------------------------------------------------------Sub WriteLog(line) dim fileStream set fileStream = fileSystem.OpenTextFile(".\ConnectSwitchPort.log", 8, true) WScript.Echo line fileStream.WriteLine line fileStream.Close
'------------------------------------------------------------------------------' The string formating functions to avoid string concatenation.'------------------------------------------------------------------------------Function Format2(myString, arg0, arg1) Format2 = Format1(myString, arg0) Format2 = Replace(Format2, "{1}", arg1)End Function
'------------------------------------------------------------------------------' The string formating functions to avoid string concatenation.'------------------------------------------------------------------------------Function Format1(myString, arg0) Format1 = Replace(myString, "{0}", arg0)End Function
Hi Robert,
Good information! I've been looking for more information on this. Can you elaborate on the "configurations" or "scenarios" where this would be beneficial.
Also with regards to disabling or unbinding the protocols, would this provide additional security, especially when the host server is physically connected to the internet? Even on the private side, most configurations we have run into, very few define the IPV4 or IPV6 stacks; running them as dymanic IPs. Would it be possible, hack their subnets and spin up a DHCP server and started sending trash IPs over so when they attempted to connected to the host box……DOS. Which brings me to another question, should those virtual nics’ IP be define and if so, what IPV4 and IPV6 subnets, same or different subnet? Thanks!
Best regards,
Bryant Fong
Hi Bryant,
it depends on which Networks/Subnets you connect your NICs. A common scenario is to have multiple NICs in the same host connected to the same subnet. You use one as dedicated for the host, but all the autocreated ones are then redundant. The host has then multiple ways to talk to the same subnet and will pick one he thinks to be the best one. No load balancing or failover will take place in this scenario though.
It's not desireable that the host picks one of the autocreated ones. So in this configuration I'd recommend to disable them or use the script, so you don't get them in the first place.
If your host needs to be multihomed in different subnets, you will need the autocreated NICs.
Regarding security, if your VMs are connected via the switch to a "unsecure" network, having the autocreated NIC enabled, with bindings, exposes the host as well to this network. Just as without Hyper-V..
Robert
my script is essentially creating a Dedicated Virtual NIC as John describes.
Disabling the autocreated NIC's or creating Dedicated Virtual NICs doesn't put more load on the host.
When a VM needs to talk to the host, one might be concerned that the traffic then goes outside the box and will be reflected by the switch. If this traffic is huge (e.g Backup of the VM) I'd think about another Private Network between Host and VMs.
Great info. So, let me confirm here. A few of my colleague have this notion that unbinding the nic puts all the traffic on the Host/Parent Nic which essentially opens the door to create additional security nightmares:
Either running the scripts above or disable (clearing) the all the binds for the protocols/services, limits how the host/parent partition from being access.
Also I found this link: - http://blogs.technet.com/jhoward/archive/2008/06/17/hyper-v-what-are-the-uses-for-different-types-of-virtual-networks.aspx
Which mentions a forth network type called “dedicated virtual network” / Parent partition to externally located servers. Would that be the same as what your script is trying to do? Thanks again!