AutomatedLabWorkerNetwork.psm1
#region New-LWNetworkSwitch function New-LWHypervNetworkSwitch { param ( [Parameter(Mandatory)] [AutomatedLab.VirtualNetwork[]]$VirtualNetwork, [switch]$PassThru ) Write-LogFunctionEntry foreach ($network in $VirtualNetwork) { if (-not $network.Name) { throw 'No name specified for virtual network to be created' } Write-ScreenInfo -Message "Creating Hyper-V virtual network '$($network.Name)'" -TaskStart if (Get-VMSwitch -Name $network.Name -ErrorAction SilentlyContinue) { Write-ScreenInfo -Message "The network switch '$($network.Name)' already exists, no changes will be made to configuration" -Type Warning continue } if ((Get-NetIPAddress -AddressFamily IPv4) -contains $network.AddressSpace.FirstUsable) { Write-ScreenInfo -Message "The IP '$($network.AddressSpace.FirstUsable)' Address for network switch '$($network.Name)' is already in use" -Type Error return } if ($network.SwitchType -eq 'External') { $adapterMac = (Get-NetAdapter -Name $network.AdapterName).MacAddress $adapterCountWithSameMac = (Get-NetAdapter | Where-Object { $_.MacAddress -eq $adapterMac -and $_.DriverDescription -ne 'Microsoft Network Adapter Multiplexor Driver' } | Group-Object -Property MacAddress).Count if ($adapterCountWithSameMac -gt 1) { if (Get-NetLbfoTeam -Name $network.AdapterName) { Write-ScreenInfo -Message "Network Adapter ($($network.AdapterName)) is a teamed interface, ignoring duplicate MAC checking" -Type Warning } else { throw "The given network adapter ($($network.AdapterName)) for the external virtual switch ($($network.Name)) is already part of a network bridge and cannot be used." } } $switch = New-VMSwitch -NetAdapterName $network.AdapterName -Name $network.Name -AllowManagementOS $network.EnableManagementAdapter -ErrorAction Stop } else { try { $switch = New-VMSwitch -Name $network.Name -SwitchType ([string]$network.SwitchType) -ErrorAction Stop } catch { Start-Sleep -Seconds 2 $switch = New-VMSwitch -Name $network.Name -SwitchType ([string]$network.SwitchType) -ErrorAction Stop } } Start-Sleep -Seconds 1 if ($network.EnableManagementAdapter) { $config = Get-CimInstance -ClassName Win32_NetworkAdapter | Where-Object NetConnectionID -Match "vEthernet \($($network.Name)\) ?(\d{1,2})?" | Get-CimAssociatedInstance -ResultClassName Win32_NetworkAdapterConfiguration if (-not $config) { throw "The network adapter for network switch '$network' could not be found. Cannot set up address hence will not be able to contact the machines" } if ($network.ManagementAdapter.InterfaceName -ne $null) { #A management adapter was defined, use its provided IP settings $adapterIpAddress = if ($network.ManagementAdapter.ipv4Address.IpAddress -eq $network.ManagementAdapter.ipv4Address.Network) { $network.ManagementAdapter.ipv4Address.FirstUsable } else { $network.ManagementAdapter.ipv4Address.IpAddress } $adapterCidr = if ($network.ManagementAdapter.ipv4Address.Cidr) { $network.ManagementAdapter.ipv4Address.Cidr } else { #default to a class C (255.255.255.0) CIDR if one wasnt supplied 24 } #Assign the IP address to the interface, implementing a default gateway if one was supplied if ($network.ManagementAdapter.ipv4Gateway) { $null = New-NetIPAddress -InterfaceAlias "vEthernet ($($network.Name))" -IPAddress $adapterIpAddress.AddressAsString -AddressFamily IPv4 -PrefixLength $adapterCidr -DefaultGateway $network.ManagementAdapter.ipv4Gateway.AddressAsString } else { $null = New-NetIPAddress -InterfaceAlias "vEthernet ($($network.Name))" -IPAddress $adapterIpAddress.AddressAsString -AddressFamily IPv4 -PrefixLength $adapterCidr } if (-not $network.ManagementAdapter.AccessVLANID -eq 0) { #VLANID has been specified for the vEthernet Adapter, so set it Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $network.Name -Access -VlanId $network.ManagementAdapter.AccessVLANID } } else { #if no address space has been defined, the management adapter will just be left as a DHCP-enabled interface if ($network.AddressSpace -ne $null) { #if the network address was defined, get the first usable IP for the network adapter $adapterIpAddress = if ($network.AddressSpace.IpAddress -eq $network.AddressSpace.Network) { $network.AddressSpace.FirstUsable } else { $network.AddressSpace.IpAddress } while ($adapterIpAddress -in (Get-LabMachineDefinition).IpAddress.IpAddress) { $adapterIpAddress = $adapterIpAddress.Increment() } $arguments = @{ IPAddress = @($adapterIpAddress.AddressAsString) SubnetMask = @($network.AddressSpace.Netmask.AddressAsString) } $result = $config | Invoke-CimMethod -MethodName EnableStatic -Arguments $arguments if ($result.ReturnValue) { throw "Could not set the IP address '$($arguments.IPAddress)' with subnet mask '$($arguments.SubnetMask)' on adapter 'vEthernet ($($network.Name))'. The error code was $($result.ReturnValue). Lookup the documentation of the class Win32_NetworkAdapterConfiguration in the MSDN to get more information about the error code." } } else { Write-ScreenInfo -Message "Management Interface for switch '$($network.Name)' on Network Adapter '$($network.AdapterName)' has no defined AddressSpace and will remain DHCP enabled, ensure this is desired behaviour." -Type Warning } } } Write-ScreenInfo -Message "Done" -TaskEnd if ($PassThru) { $switch } } Write-LogFunctionExit } #endregion New-LWNetworkSwitch #region Remove-LWNetworkSwitch function Remove-LWNetworkSwitch { param ( [Parameter(Mandatory)] [string]$Name ) Write-LogFunctionEntry if (-not (Get-VMSwitch -Name $Name -ErrorAction SilentlyContinue)) { Write-ScreenInfo 'The network switch does not exist' -Type Warning return } if ((Get-VM | Get-VMNetworkAdapter | Where-Object {$_.SwitchName -eq $Name} | Measure-Object).Count -eq 0) { try { Remove-VMSwitch -Name $Name -Force -ErrorAction Stop } catch { Start-Sleep -Seconds 2 Remove-VMSwitch -Name $Name -Force } Write-PSFMessage "Network switch '$Name' removed" } else { Write-ScreenInfo "Network switch '$Name' is still in use, skipping removal" -Type Warning } Write-LogFunctionExit } #endregion Remove-LWNetworkSwitch |