-- Ben Armstrong, Virtualization Program Manager
Talking about core virtualization at Microsoft (Hyper-V, Virtual PC and Virtual Server).
Moving on with the series, we arrive at creating an external virtual network.
VBScript:
option explicit
Dim HyperVServer
Dim SwitchFriendlyName
Dim TypeLib
Dim SwitchName
Dim InternalEthernetPortFriendlyName
Dim InternalSwitchPortFriendlyName
Dim InternalSwitchPortName
Dim InternalEthernetPortName
Dim ExternalSwitchPortFriendlyName
Dim ExternalSwitchPortName
Dim ExternalEthernetPort
Dim ExternalEthernetPorts
Dim ExternalEthernetPortName
Dim ExternalEthernetPortString
Dim ScopeofResidence
Dim WMIService
Dim VirtualSwitchManagementService
Dim Switch
Dim InternalSwitchPort
Dim ExternalSwitchPort
Dim InParam
Dim OutParams
Dim Job
Dim Test
'Prompt for the Hyper-V Server to use
HyperVServer = InputBox("Specify the Hyper-V Server to create the internal virtual network switch:")
'Get an instance of the WMI Service in the virtualization namespace.
set WMIService = GetObject("winmgmts:\\" & HyperVServer & "\root\virtualization")
'Get the Msvm_VirtualSwitchManagementService object
set VirtualSwitchManagementService = WMIService.ExecQuery("select * from Msvm_VirtualSwitchManagementService").ItemIndex(0)
'Get all possible physical network adapters that can be used for a switch
Set ExternalEthernetPorts = WMIService.ExecQuery("Select * From Msvm_ExternalEthernetPort WHERE IsBound=False AND EnabledState=2")
'Build the string to ask what physical network adapter to use
ExternalEthernetPortString = "The following network adapters are available:" & chr(10) & chr(10)
for each ExternalEthernetPort in ExternalEthernetPorts
ExternalEthernetPortString = ExternalEthernetPortString & ExternalEthernetPort.Name & chr(10)
next
ExternalEthernetPortString = ExternalEthernetPortString & chr(10) & "Please type in the (exact) name of the network adapter you want to use for the external connection:"
'Setup a loop to keep on asking for a network adapter until we get a valid response
Test = true
while test
ExternalEthernetPortName = InputBox(ExternalEthernetPortString)
on error resume next
Set ExternalEthernetPort = WMIService.ExecQuery("Select * From Msvm_ExternalEthernetPort WHERE Name='" & ExternalEthernetPortName & "' AND IsBound=False AND EnabledState=2").ItemIndex(0)
If Err.Number = 0 Then
Test = false
End If
on error goto 0
Wend
'Get friendly name for the external virtual network switch (and the internal ethernet port)
SwitchFriendlyName = InputBox("Specify the name of the new external virtual network switch:")
InternalEthernetPortFriendlyName = SwitchFriendlyName
'Set the friendly name for the internal switch port and external switch port
InternalSwitchPortFriendlyName = "InternalSwitchPort"
ExternalSwitchPortFriendlyName = "ExternalSwitchPort"
'Generate GUIDs for the unique switch name, internal switch port name, internal ethernet port name and external switch port name
Set TypeLib = CreateObject("Scriptlet.TypeLib")
SwitchName = TypeLib.Guid
InternalSwitchPortName = TypeLib.Guid
InternalEthernetPortName = TypeLib.Guid
ExternalSwitchPortName = TypeLib.Guid
'Create a new virtual network switch
'Setup the input parameter list
set InParam = VirtualSwitchManagementService.Methods_("CreateSwitch").InParameters.SpawnInstance_()
InParam.FriendlyName = SwitchFriendlyName
InParam.Name = SwitchName
InParam.NumLearnableAddresses = 1024
InParam.ScopeofResidence = null
'Execute the method and store the results in OutParam
set OutParams = VirtualSwitchManagementService.ExecMethod_("CreateSwitch", InParam)
'Get the new switch object out of the results
Set Switch = WMIService.Get(OutParams.CreatedVirtualSwitch)
'Create a new internal switch port
set InParam = VirtualSwitchManagementService.Methods_("CreateSwitchPort").InParameters.SpawnInstance_()
InParam.VirtualSwitch = Switch.Path_.Path
InParam.FriendlyName = InternalSwitchPortFriendlyName
InParam.Name = InternalSwitchPortName
set OutParams = VirtualSwitchManagementService.ExecMethod_("CreateSwitchPort", InParam)
'Get the new internal switch port out of the results
Set InternalSwitchPort = WMIService.Get(OutParams.CreatedSwitchPort)
'Create a new external switch port
InParam.FriendlyName = ExternalSwitchPortFriendlyName
InParam.Name = ExternalSwitchPortName
'Get the new external switch port out of the results
Set ExternalSwitchPort = WMIService.Get(OutParams.CreatedSwitchPort)
'Pull it all together with a call to SetupSwitch
set InParam = VirtualSwitchManagementService.Methods_("SetupSwitch").InParameters.SpawnInstance_()
InParam.ExternalSwitchPort = ExternalSwitchPort.Path_.Path
InParam.InternalSwitchPort = InternalSwitchPort.Path_.Path
InParam.ExternalEthernetPort = ExternalEthernetPort.Path_.Path
InParam.InternalEthernetPortName = InternalEthernetPortName
InParam.InternalEthernetPortFriendlyName = InternalEthernetPortFriendlyName
'Execute the method and store the results in OutParams
set OutParams = VirtualSwitchManagementService.ExecMethod_("SetupSwitch", InParam)
'Check to see if the job completed synchronously
if (OutParams.ReturnValue = 0) then
Wscript.Echo "External virtual network created."
elseif (OutParams.ReturnValue <> 4096) then
Wscript.Echo "Failed to create external virtual network." & OutParams.ReturnValue
else
'Get the job object
set Job = WMIService.Get(OutParams.Job)
'Wait for the job to complete (3 == starting, 4 == running)
while (Job.JobState = 3) or (Job.JobState = 4)
Wscript.Echo "Creating virtual network. " & Job.PercentComplete & "% complete"
WScript.Sleep(1000)
'Refresh the job object
'Provide details if the job fails (7 == complete)
if (Job.JobState <> 7) then
Wscript.Echo "ErrorCode:" & Job.ErrorCode
Wscript.Echo "ErrorDescription:" & Job.ErrorDescription
Wscript.Echo "Failed to create external virtual network."
end If
end if
PowerShell:
# Prompt for the Hyper-V Server to use
$HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
# List the available physical network adapters
Write-Host "The following physical network adapters are avaiable for an external virtual network:"
# Get the collection of external network adapters that are not associated with switches
$query = "Select * From Msvm_ExternalEthernetPort WHERE IsBound=False AND EnabledState=2"
$ExternalEthernetPorts = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
# Output the elementname for each external nic
foreach ($Nic in $ExternalEthernetPorts)
{
Write-Host $Nic.Name
}
# Keep on asking for a physical network adapter until we get a valid answer
$ExternalEthernetPort = $null
While ($ExternalEthernetPort -eq $null)
# Ask for the NIC name to use for the switch
$ExternalEthernetPortName = Read-Host "Please type in the (exact) name of the network adapter you want to use for the external connection"
# Get the WMI object for the external nic
$query = "Select * From Msvm_ExternalEthernetPort WHERE Name='" + $ExternalEthernetPortName + "' AND IsBound=False AND EnabledState=2"
$ExternalEthernetPort = gwmi -namespace "root\virtualization" -Query $query -computername $HyperVServer
# Get friendly name for the external virtual network switch (and internal ethernet port)
$SwitchFriendlyName = Read-Host "Specify the name of the new external virtual network switch"
$InternalEthernetPortFriendlyName = $SwitchFriendlyName
# Set the friendly name for the internal switch port and external switch port
$InternalSwitchPortFriendlyName = "InternalSwitchPort"
$ExternalSwitchPortFriendlyName = "ExternalSwitchPort"
# Generate GUIDs for the unique switch name, internal switch port name, internal ethernet port name and external switch port name
$SwitchName = [guid]::NewGuid().ToString()
$InternalSwitchPortName = [guid]::NewGuid().ToString()
$InternalEthernetPortName = [guid]::NewGuid().ToString()
$ExternalSwitchPortName = [guid]::NewGuid().ToString()
# Setup some other values that will be used
$NumLearnableAddresses = 1024
$ScopeOfResidence = ""
# Get the Msvm_VirtualSwitchManagementService WMI Object on the system we are going to be working with
$VirtualSwitchManagementService = gwmi Msvm_VirtualSwitchManagementService -namespace "root\virtualization" -computername $HyperVServer
# Create a new switch with 1024 learnable addresses
$Result = $VirtualSwitchManagementService.CreateSwitch($SwitchName, $SwitchFriendlyName, $NumLearnableAddresses, $ScopeOfResidence)
# Get the WMI object for the new switch out of the results
$Switch = [WMI]$Result.CreatedVirtualSwitch
# Create Internal Switch Port
$Result = $VirtualSwitchManagementService.CreateSwitchPort($Switch, $InternalSwitchPortName, $InternalSwitchPortFriendlyName, $ScopeOfResidence)
# Get the WMI object for the new switch port out of the results
$InternalSwitchPort = [WMI]$Result.CreatedSwitchPort
# Create External Switch Port
$Result = $VirtualSwitchManagementService.CreateSwitchPort($Switch, $ExternalSwitchPortName, $ExternalSwitchPortFriendlyName, $ScopeOfResidence)
$ExternalSwitchPort = [WMI]$Result.CreatedSwitchPort
# Pull it all together with a call to SeutpSwitch
$Result = $VirtualSwitchManagementService.SetupSwitch($ExternalSwitchPort, $InternalSwitchPort, $ExternalEthernetPort, $InternalEthernetPortName, $InternalEthernetPortFriendlyName)
# Return success if the return value is "0"
if ($Result.ReturnValue -eq 0)
{write-host "External virtual network created."}
# If the return value is not "0" or "4096" then the operation failed
ElseIf ($Result.ReturnValue -ne 4096)
{write-host "Failed to create external virtual network."}
Else
{# Get the job object
$job=[WMI]$Result.job
# Provide updates if the jobstate is "3" (starting) or "4" (running)
while ($job.JobState -eq 3 -or $job.JobState -eq 4)
{write-host $job.PercentComplete
start-sleep 1
#Refresh the job object
$job=[WMI]$Result.job}
# A jobstate of "7" means success
if ($job.JobState -eq 7)
{write-host "Failed to create external virtual network."
write-host "ErrorCode:" $job.ErrorCode
write-host "ErrorDescription" $job.ErrorDescription}
Let’s step through the flow here:
Some extra points to make:
Cheers, Ben
very well explained Thank you so much helped me quite. I have one question though. How to I delete a Virtual Network so that my NIC card is vacated to be used again in some other virtual network.
If I delete The VirtualSwicth and Ports which have been associated with the Swicth, my NIC would still not get unbinded and be available to be hooked with other virtual switches. Any help would be greatly appreciated :)