diff --git a/Convert-LBFO2SET.psd1 b/Convert-LBFO2SET.psd1 index ce9cf60..c431cfa 100644 --- a/Convert-LBFO2SET.psd1 +++ b/Convert-LBFO2SET.psd1 @@ -12,7 +12,7 @@ RootModule = 'Convert-LBFO2SET.psm1' # Version number of this module. -ModuleVersion = '2020.11.11.9' +ModuleVersion = '2022.08.18.1' # Supported PSEditions # CompatiblePSEditions = @() @@ -27,7 +27,7 @@ Author = 'Dan Cuomo' CompanyName = 'Microsoft' # Copyright statement for this module -Copyright = '(c) 2020 Inc. All rights reserved.' +Copyright = '(c) 2022 Inc. All rights reserved.' # Description of the functionality provided by this module Description = 'Convert-LBFO2SET converts and LBFO team or vSwitch into a Switch Embedded Team' @@ -51,7 +51,7 @@ Description = 'Convert-LBFO2SET converts and LBFO team or vSwitch into a Switch # ProcessorArchitecture = '' # Modules that must be imported into the global environment prior to importing this module -RequiredModules = @(@{ModuleName = 'Pester'; RequiredVersion = '4.9.0'; }) +RequiredModules = @(@{ModuleName = 'Pester'; RequiredVersion = '5.3.3'; }) # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @() diff --git a/Convert-LBFO2SET.psm1 b/Convert-LBFO2SET.psm1 index 8cac0ac..dcb6e02 100644 --- a/Convert-LBFO2SET.psm1 +++ b/Convert-LBFO2SET.psm1 @@ -1,343 +1,297 @@ -Function Convert-LBFO2Set { -<# - .SYNOPSIS - Virtual Switches attached to an LBFO team has been deprecated by Microsoft. Use this tool, to - migrate your team to the alternative teaming solution, Switch Embedded Teaming (SET). - - .DESCRIPTION - This script will allow you to migrate a LBFO Team into a SET team. It will also migrate a vSwitch (if added to the LBFO Team) - To a new vSwitch on SET including the vNICs. This enables you to migrate a host with active virtual machines. - - .PARAMETER LBFOTeam - The name of the LBFO Team to be migrated - - .PARAMETER SETTeam - The name of the SET team to be created (the team does not need to already exist) - - .PARAMETER AllowOutage - Use this to allow a migration of a team and vSwitch with only one pNIC. In this case, the migration will incur an outage - for any virtual NICs connected to the team because the underlying pNIC can only be connected to one team at a time - - .PARAMETER EnableBestPractices - Use this to set Microsoft recommended best practices for the team and/or Virtual Switch. If this switch is omitted, the - existing settings from the LBFO team will be configured on SET - - .EXAMPLE - Convert-LBFO2Set -LBFOTeam NameofLBFOTeam -SETTeam NewSETTeamName - - .EXAMPLE - Convert-LBFO2Set TODO - - .NOTES - Author: Microsoft Edge OS Networking Team and Microsoft CSS - - Please file issues on GitHub @ GitHub.com/Microsoft/Convert-LBFO2SET - - .LINK - More projects : https://github.com/topics/msftnet - Windows Networking Blog : https://blogs.technet.microsoft.com/networking/ -#> - [CmdletBinding()] - param ( - [parameter(Mandatory = $true)] - [String] $LBFOTeam , - - [parameter(Mandatory = $true)] - [String] $SETTeam , - - [parameter(Mandatory = $False)] - [Switch] $AllowOutage = $false, - - [parameter(Mandatory = $False)] - [Switch] $EnableBestPractices = $false - ) - - Write-Verbose "Collecting data and validating configuration." - # check whether $LBFOTeam is the vSwitch or the LBFO team name bound to a vSwitch - # if there is an LBFO team with the name we simply use that - $isLBFOTeam = Get-NetLbfoTeam -Name $LBFOTeam -ErrorAction SilentlyContinue - if (-NOT $isLBFOTeam) - { - # check to see whether this is a vSwitch - $isvSwitch = Get-VMSwitch $LBFOTeam -ErrorAction SilentlyContinue - - if ($isvSwitch) - { - Write-Verbose "LBFOTeam is a vSwitch. Verifying that an LBFO team is attached." - ## a vSwitch was found. Now make sure there is an LBFO team attached. - # get the vSwitch adapter(s) based on the InterfaceDescription contained in the vSwitch object - $tmpAdapter = Get-NetAdapter | Where-Object InterfaceDescription -in $isvSwitch.NetAdapterInterfaceDescriptions - - # compare to list of LBFO team adapters - $tmpTeam = Get-NetLbfoTeam | Where-Object { $_.Name -in $tmpAdapter.Name -or $_.Name -eq $tmpAdapter.Name } - - if ($tmpTeam) - { - # we found the LBFO team attached to the vSwitch! Set that to $LBFOTeam. We'll rediscover the vSwitch later. - $LBFOTeam = $tmpTeam.Name - } - else - { - Throw "An LBFO team associated with $LBFOTeam could not be detected." - } - } - else - { - Throw "Failed to find an LBFO team or vSwitch named $LBFOTeam`." - } - - Remove-Variable isLBFOTeam,isvSwitch,tmpAdapter,tmpTeam -ErrorAction SilentlyContinue - } - else { - Remove-Variable isLBFOTeam -ErrorAction SilentlyContinue - } +Function Convert-LBFO2Set +{ + <# + .SYNOPSIS + Virtual Switches attached to an LBFO team has been deprecated by Microsoft. Use this tool, to + migrate your team to the alternative teaming solution, Switch Embedded Teaming (SET). - - # get the path to where the module is stored - $here = Split-Path -Parent (Get-Module -Name Convert-LBFO2SET).Path - - if (-NOT $here) - { - throw "Could not find the module path." - } - - # detect the version of Windows - $osMajVer = [System.Environment]::OSVersion.Version.Major - $osBldVer = [System.Environment]::OSVersion.Version.Build - - switch ($osMajVer) - { - 10 - { - switch ($osBldVer) - { - 14393 { - $nicReconnBin = "nicReconnect1.exe" - } - - 17763 { - $nicReconnBin = "nicReconnect5.exe" - } - - default - { - throw "This version of Windows is not yet certified for Convert-LBFO2SET." - } - } - } - - default - { - throw "A supported version of Windows was not detected." - } - } - - - #region Data Collection - $configData = @{ NetLBFOTeam = Get-NetLbfoTeam -Name $LBFOTeam -ErrorAction SilentlyContinue } - - $ValidationResults = Invoke-Pester -Script "$here\tests\unit\unit.tests.ps1" -Tag PreValidation -PassThru - $ValidationResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize - - If ($ValidationResults.FailedCount -ne 0) { - Write-Warning 'Prerequisite checks have failed.' - - Write-Warning "`n`nPlease note: if the failure was due to LACP: `n`t - We will intentionally NOT convert this type of team as the new team will not be functional until the port-channel on the physical switch has been modified" - Write-Warning "To continue with an LACP conversion, please break the port-channel on the physical switch and modify the LBFO team to Switch Independent (Set-NetLbfoTeam -TeamingMode SwitchIndependent)" - - throw - } - - $configData += @{ - NetAdapter = Get-NetAdapter -Name $configData.NetLBFOTeam.TeamNics -ErrorAction SilentlyContinue - NetAdapterBinding = Get-NetAdapterBinding -Name $configData.NetLBFOTeam.TeamNics -ErrorAction SilentlyContinue - } - - $configData += @{ - LBFOVMSwitch = Get-VMSwitch -ErrorAction SilentlyContinue | Where-Object NetAdapterInterfaceGuid -eq $configData.NetAdapter.InterfaceGuid - } - - if ($ConfigData.LBFOVMSwitch) { - $configData += @{ - VMNetworkAdapter = Get-VMNetworkAdapter -All | Where-Object SwitchName -EQ $configData.LBFOVMSwitch.Name -ErrorAction SilentlyContinue - } - - # Grabbing host vNICs (ManagementOS) attached to the LBFO vSwitch - $configData += @{ HostvNICs = @(Get-VMNetworkAdapter -ManagementOS -SwitchName $configData.LBFOVMSwitch.Name) } - } - #endregion - - # EnableIOV should be $true as a best practice unless Hyper-V QoS is in use. Enabling IOV turns the vSwitch Bandwidth mode to 'None' so no legacy QoS - Switch ($ConfigData.LBFOVMSwitch.BandwidthReservationMode) { - {'Absolute' -or 'Weight'} { - If ($configData.VMNetworkAdapter.BandwidthSetting) - { - $IovEnabled = $false - } - Else - { - $IovEnabled = $true - } - } - - 'None' { $IovEnabled = $true } - - default { $IovEnabled = $false } - } - - #region Create new SET team - #TODO: test this logic thuroughly... - if ($AllowOutage -eq $true -and $configData.NetLBFOTeam.Members.Count -eq 1) - { - $NetAdapterNames = $configData.NetLBFOTeam.Members - - # Only one pnIC - Destroy the LBFOTeam - Remove-NetLbfoTeam -Name $configData.NetLBFOTeam.Name -Confirm:$false - } - else - { - $NetAdapterNames = $configData.NetLBFOTeam.Members[0] - - Remove-NetLbfoTeamMember -Name $configData.NetLBFOTeam.Members[0] -Team $configData.NetLBFOTeam.Name -Confirm:$False - } - - $SETTeamParams = @{ - Name = $SETTeam - NetAdapterName = $NetAdapterNames - EnableIov = $IovEnabled - EnablePacketDirect = $false - EnableEmbeddedTeaming = $true - AllowManagementOS = $false - } - - $vSwitchExists = Get-VMSwitch -Name $SETTeam -ErrorAction SilentlyContinue - - if (-NOT $vSwitchExists) - { - New-VMSwitch @SETTeamParams - } - else - { - $VerbosePreference = 'Continue' - - Write-Verbose "Team named [$SETTeam] exists and will be used" - - $VerbosePreference = 'SilentlyContinue' - } - - Remove-Variable SETTeamParams -ErrorAction SilentlyContinue - #endregion - - - $vmNICs = ($configData.VMNetworkAdapter | Where-Object VMName -ne $Null) - $vNICMigrationNeeded = If ($vmNICs) { $true } Else { $false } - - # TODO: Add vmNIC and Host vNIC to test cases. - if ($vNICMigrationNeeded) { Connect-VMNetworkAdapter -VMNetworkAdapter $vmNICs -SwitchName $SETTeam -ErrorAction SilentlyContinue } - - # migrate host vNIC(s) - Foreach ($HostvNIC in $configData.HostvNics) { - & "$($here)\helpers\$($nicReconnBin)" -r "$($HostvNIC.Name)" "$SETTeam" | Out-Null - } - - # validation to make sure there are no more vmNICs attached - $vmMigGood = Get-VMNetworkAdapter -All | Where-Object SwitchName -EQ $configData.LBFOVMSwitch.Name -ErrorAction SilentlyContinue - if ($vmMigGood) - { - throw "Critical vmNIC migration failure. The following virtual NICs were not migrated to the new SET switch:`n$($vmMigGood | ForEach-Object { "`n`t$($_.Name) [$(if ($_.VMName) {"$($_.VMName)"} else {"host"})] " })" - } - -#region Fire and Brimstone - $remainingAdapters = $configData.NetLBFOTeam.Members - - if ($configData.LBFOVMSwitch) - { - Remove-VMSwitch -Name $configData.LBFOVMSwitch.Name -Force -ErrorAction SilentlyContinue | Out-Null - } + .DESCRIPTION + This script will allow you to migrate a LBFO Team into a SET team. It will also migrate a vSwitch (if added to the LBFO Team) + To a new vSwitch on SET including the vNICs. This enables you to migrate a host with active virtual machines. - Remove-NetLbfoTeam -Name $configData.NetLBFOTeam.Name -Confirm:$false -ErrorAction SilentlyContinue - - #TODO: May need to check that the switch and / or team actually were removed before moving on - - Add-VMSwitchTeamMember -NetAdapterName $remainingAdapters -VMSwitchName $SETTeam - - Remove-Variable HostvNIC -ErrorAction SilentlyContinue - - <# Temporarily removing till we work through host vNIC migration plan - foreach ($HostvNIC in ($configData.HostvNICs)) { - $NewNetAdapterName = $configData.HostvNICs.$($HostvNIC.Keys).HostvNICNetAdapter.Name - - Rename-NetAdapter -Name "$NewNetAdapterName-446f776e2057697468204c42464f" -NewName $NewNetAdapterName - } + .PARAMETER LBFOTeam + The name of the LBFO Team to be migrated + + .PARAMETER SETTeam + The name of the SET team to be created (the team does not need to already exist) + + .PARAMETER AllowOutage + Use this to allow a migration of a team and vSwitch with only one pNIC. In this case, the migration will incur an outage + for any virtual NICs connected to the team because the underlying pNIC can only be connected to one team at a time + + .PARAMETER EnableBestPractices + Use this to set Microsoft recommended best practices for the team and/or Virtual Switch. If this switch is omitted, the + existing settings from the LBFO team will be configured on SET + + .EXAMPLE + Convert-LBFO2Set -LBFOTeam NameofLBFOTeam -SETTeam NewSETTeamName + + .EXAMPLE + Convert-LBFO2Set TODO + + .NOTES + Author: Microsoft Edge OS Networking Team and Microsoft CSS + + Please file issues on GitHub @ GitHub.com/Microsoft/Convert-LBFO2SET + + .LINK + More projects : https://github.com/topics/msftnet + Windows Networking Blog : https://blogs.technet.microsoft.com/networking/ #> -#endregion - - if ($EnableBestPractices) { - $SETInterfaces = (Get-VMSwitchTeam -Name $SETTeam).NetAdapterInterfaceDescription - $SETAdapters = (Get-NetAdapter | Where-Object InterfaceDescription -in $SETInterfaces).Name - - Foreach ($interface in $SETAdapters) { - Reset-NetAdapterAdvancedProperty -Name $interface -ErrorAction SilentlyContinue ` - -DisplayName 'NVGRE Encapsulated Task Offload', 'VXLAN Encapsulated Task Offload', 'IPV4 Checksum Offload', - 'NetworkDirect Technology', 'Recv Segment Coalescing (IPv4)', 'Recv Segment Coalescing (IPv6)', - 'Maximum number of RSS Processors', 'Maximum Number of RSS Queues', 'RSS Base Processor Number', - 'RSS Load Balancing Profile', 'SR-IOV', 'TCP/UDP Checksum Offload (IPv4)', 'TCP/UDP Checksum Offload (IPv6)' - - - Set-NetAdapterAdvancedProperty -Name $interface -DisplayName 'Packet Direct' -RegistryValue 0 -ErrorAction SilentlyContinue - Set-NetAdapterAdvancedProperty -Name $interface -RegistryValue 1 -DisplayName 'Receive Side Scaling', 'Virtual Switch RSS', 'Virtual Machine Queues', 'NetworkDirect Functionality' -ErrorAction SilentlyContinue + [CmdletBinding()] + param ( + [parameter(Mandatory = $true)] + [String]$LBFOTeam, + [parameter(Mandatory = $true)] + [String]$SETTeam, + [parameter(Mandatory = $False)] + [Switch]$AllowOutage = $false, + [parameter(Mandatory = $False)] + [Switch]$EnableBestPractices = $false + ) + Write-Verbose "Collecting data and validating configuration." + # check whether $LBFOTeam is the vSwitch or the LBFO team name bound to a vSwitch + # if there is an LBFO team with the name we simply use that + $isLBFOTeam = Get-NetLbfoTeam -Name $LBFOTeam -ErrorAction SilentlyContinue + if (-NOT $isLBFOTeam) + { + # check to see whether this is a vSwitch + $isvSwitch = Get-VMSwitch $LBFOTeam -ErrorAction SilentlyContinue + if ($isvSwitch) + { + Write-Verbose "LBFOTeam is a vSwitch. Verifying that an LBFO team is attached." + ## a vSwitch was found. Now make sure there is an LBFO team attached. + # get the vSwitch adapter(s) based on the InterfaceDescription contained in the vSwitch object + $tmpAdapter = Get-NetAdapter | Where-Object InterfaceDescription -in $isvSwitch.NetAdapterInterfaceDescriptions + # compare to list of LBFO team adapters + $tmpTeam = Get-NetLbfoTeam | Where-Object { $_.Name -in $tmpAdapter.Name -or $_.Name -eq $tmpAdapter.Name } + if ($tmpTeam) + { + # we found the LBFO team attached to the vSwitch! Set that to $LBFOTeam. We'll rediscover the vSwitch later. + $LBFOTeam = $tmpTeam.Name + } + else + { + Throw "An LBFO team associated with $LBFOTeam could not be detected." + } + } + else + { + Throw "Failed to find an LBFO team or vSwitch named $LBFOTeam`." + } + Remove-Variable isLBFOTeam, isvSwitch, tmpAdapter, tmpTeam -ErrorAction SilentlyContinue + } + else + { + Remove-Variable isLBFOTeam -ErrorAction SilentlyContinue + } + # get the path to where the module is stored + $here = Split-Path -Parent (Get-Module -Name Convert-LBFO2SET).Path + if (-NOT $here) + { + throw "Could not find the module path." + } + # detect the version of Windows + $osMajVer = [System.Environment]::OSVersion.Version.Major + $osBldVer = [System.Environment]::OSVersion.Version.Build + switch ($osMajVer) + { + 10 + { + switch ($osBldVer) + { + 14393 { + $nicReconnBin = "nicReconnect1.exe" + } + 17763 { + $nicReconnBin = "nicReconnect5.exe" + } + default + { + throw "This version of Windows is not yet certified for Convert-LBFO2SET." + } + } + } + default + { + throw "A supported version of Windows was not detected." + } + } + #region Data Collection + $configData = @{ NetLBFOTeam = Get-NetLbfoTeam -Name $LBFOTeam -ErrorAction SilentlyContinue } + $ValidationResults = Invoke-Pester -Script "$here\tests\unit\unit.tests.ps1" -Tag PreValidation -PassThru + $ValidationResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize + If ($ValidationResults.FailedCount -ne 0) + { + Write-Warning 'Prerequisite checks have failed.' + Write-Warning "`n`nPlease note: if the failure was due to LACP: `n`t - We will intentionally NOT convert this type of team as the new team will not be functional until the port-channel on the physical switch has been modified" + Write-Warning "To continue with an LACP conversion, please break the port-channel on the physical switch and modify the LBFO team to Switch Independent (Set-NetLbfoTeam -TeamingMode SwitchIndependent)" + throw + } + $configData += @{ + NetAdapter = Get-NetAdapter -Name $configData.NetLBFOTeam.TeamNics -ErrorAction SilentlyContinue + NetAdapterBinding = Get-NetAdapterBinding -Name $configData.NetLBFOTeam.TeamNics -ErrorAction SilentlyContinue + } + $configData += @{ + LBFOVMSwitch = Get-VMSwitch -ErrorAction SilentlyContinue | Where-Object NetAdapterInterfaceGuid -eq $configData.NetAdapter.InterfaceGuid + } + if ($ConfigData.LBFOVMSwitch) + { + $configData += @{ + VMNetworkAdapter = Get-VMNetworkAdapter -All | Where-Object SwitchName -EQ $configData.LBFOVMSwitch.Name -ErrorAction SilentlyContinue + } + # Grabbing host vNICs (ManagementOS) attached to the LBFO vSwitch + $configData += @{ HostvNICs = @(Get-VMNetworkAdapter -ManagementOS -SwitchName $configData.LBFOVMSwitch.Name) } + } + #endregion + # EnableIOV should be $true as a best practice unless Hyper-V QoS is in use. Enabling IOV turns the vSwitch Bandwidth mode to 'None' so no legacy QoS + Write-Verbose "Bandwidth Reservation Mode: $($ConfigData.LBFOVMSwitch.BandwidthReservationMode)" + Switch ($ConfigData.LBFOVMSwitch.BandwidthReservationMode) + { + { 'Absolute' -or 'Weight' } { + If ($ConfigData.VMNetworkAdapter.BandwidthSetting) + { + $IovEnabled = $true + } + Else + { + $IovEnabled = $false + } + } + 'None' { $IovEnabled = $true } + default { $IovEnabled = $false } + } + #region Create new SET team + #TODO: test this logic thuroughly... + if ($AllowOutage -eq $true -and $configData.NetLBFOTeam.Members.Count -eq 1) + { + $NetAdapterNames = $configData.NetLBFOTeam.Members + # Only one pnIC - Destroy the LBFOTeam + Remove-NetLbfoTeam -Name $configData.NetLBFOTeam.Name -Confirm:$false + } + else + { + $NetAdapterNames = $configData.NetLBFOTeam.Members[0] + Remove-NetLbfoTeamMember -Name $configData.NetLBFOTeam.Members[0] -Team $configData.NetLBFOTeam.Name -Confirm:$False + } + Write-Verbose "IOV Enabled: $IovEnabled" + $SETTeamParams = @{ + Name = $SETTeam + NetAdapterName = $NetAdapterNames + EnablePacketDirect = $false + EnableEmbeddedTeaming = $true + AllowManagementOS = $false + MinimumBandwidthMode = $($ConfigData.LBFOVMSwitch.BandwidthReservationMode) + EnableIov = $IovEnabled + } + Write-verbose "SETTeam Parameters: $($SETTeamParams | Out-String)" + $vSwitchExists = Get-VMSwitch -Name $SETTeam -ErrorAction SilentlyContinue + if (-NOT $vSwitchExists) + { + New-VMSwitch @SETTeamParams + } + else + { + $VerbosePreference = 'Continue' + Write-Verbose "Team named [$SETTeam] exists and will be used" + $VerbosePreference = 'SilentlyContinue' + } + Remove-Variable SETTeamParams -ErrorAction SilentlyContinue + #endregion + $vmNICs = ($configData.VMNetworkAdapter | Where-Object VMName -ne $Null) + $vNICMigrationNeeded = If ($vmNICs) { $true } + Else { $false } + # TODO: Add vmNIC and Host vNIC to test cases. + if ($vNICMigrationNeeded) { Connect-VMNetworkAdapter -VMNetworkAdapter $vmNICs -SwitchName $SETTeam -ErrorAction SilentlyContinue } + # migrate host vNIC(s) + Foreach ($HostvNIC in $configData.HostvNics) + { + & "$($here)\helpers\$($nicReconnBin)" -r "$($HostvNIC.Name)" "$SETTeam" | Out-Null + } + # validation to make sure there are no more vmNICs attached + $vmMigGood = Get-VMNetworkAdapter -All | Where-Object SwitchName -EQ $configData.LBFOVMSwitch.Name -ErrorAction SilentlyContinue + if ($vmMigGood) + { + throw "Critical vmNIC migration failure. The following virtual NICs were not migrated to the new SET switch:`n$($vmMigGood | ForEach-Object { + "`n`t$($_.Name) [$(if ($_.VMName) { "$($_.VMName)" } + else { "host" })] " + })" + } + #region Fire and Brimstone + $remainingAdapters = $configData.NetLBFOTeam.Members + if ($configData.LBFOVMSwitch) + { + Remove-VMSwitch -Name $configData.LBFOVMSwitch.Name -Force -ErrorAction SilentlyContinue | Out-Null + } + Remove-NetLbfoTeam -Name $configData.NetLBFOTeam.Name -Confirm:$false -ErrorAction SilentlyContinue + #TODO: May need to check that the switch and / or team actually were removed before moving on + Add-VMSwitchTeamMember -NetAdapterName $remainingAdapters -VMSwitchName $SETTeam + Remove-Variable HostvNIC -ErrorAction SilentlyContinue + <# Temporarily removing till we work through host vNIC migration plan + foreach ($HostvNIC in ($configData.HostvNICs)) { + $NewNetAdapterName = $configData.HostvNICs.$($HostvNIC.Keys).HostvNICNetAdapter.Name + + Rename-NetAdapter -Name "$NewNetAdapterName-446f776e2057697468204c42464f" -NewName $NewNetAdapterName } - - $NodeOSCaption = (Get-CimInstance -ClassName 'Win32_OperatingSystem').Caption - - Switch -Wildcard ($NodeOSCaption) { - '*Windows Server 2016*' { - $SETSwitchUpdates = @{ DefaultQueueVrssQueueSchedulingMode = 'StaticVRSS' } - $vmNICUpdates = @{ VrssQueueSchedulingMode = 'StaticVRSS' } - $HostvNICUpdates = @{ VrssQueueSchedulingMode = 'StaticVRSS' } - } - - '*Windows Server 2019*' { - $SETSwitchUpdates = @{ - EnableSoftwareRsc = $true - DefaultQueueVrssQueueSchedulingMode = 'Dynamic' - } - - $vmNICUpdates = @{ VrssQueueSchedulingMode = 'Dynamic' } - $HostvNICUpdates = @{ VrssQueueSchedulingMode = 'Dynamic' } - } - } - - $SETSwitchUpdates += @{ - Name = $SETTeam - DefaultQueueVrssEnabled = $true - DefaultQueueVmmqEnabled = $true - DefaultQueueVrssMinQueuePairs = 8 - DefaultQueueVrssMaxQueuePairs = 16 - } - - $vmNICUpdates += @{ - VMName = '*' - VrssEnabled = $true - VmmqEnabled = $true - VrssMinQueuePairs = 8 - VrssMaxQueuePairs = 16 - } - - $HostvNICUpdates += @{ - ManagementOS = $true - VrssEnabled = $true - VmmqEnabled = $true - VrssMinQueuePairs = 8 - VrssMaxQueuePairs = 16 - } - - Set-VMSwitch @SETSwitchUpdates - Set-VMSwitchTeam -Name $SETTeam -LoadBalancingAlgorithm HyperVPort - - Set-VMNetworkAdapter @HostvNICUpdates - Set-VMNetworkAdapter @vmNICUpdates - - Remove-Variable SETSwitchUpdates, vmNICUpdates, HostvNICUpdates, NodeOSCaption -ErrorAction SilentlyContinue - } + #> + #endregion + Write-Verbose "Enable Best Practices Parameter Present: $EnableBestPractices" + if ($EnableBestPractices) + { + $SETInterfaces = (Get-VMSwitchTeam -Name $SETTeam).NetAdapterInterfaceDescription + $SETAdapters = (Get-NetAdapter | Where-Object InterfaceDescription -in $SETInterfaces).Name + Foreach ($interface in $SETAdapters) + { + Reset-NetAdapterAdvancedProperty -Name $interface -ErrorAction SilentlyContinue ` + -DisplayName 'NVGRE Encapsulated Task Offload', 'VXLAN Encapsulated Task Offload', 'IPV4 Checksum Offload', + 'NetworkDirect Technology', 'Recv Segment Coalescing (IPv4)', 'Recv Segment Coalescing (IPv6)', + 'Maximum number of RSS Processors', 'Maximum Number of RSS Queues', 'RSS Base Processor Number', + 'RSS Load Balancing Profile', 'SR-IOV', 'TCP/UDP Checksum Offload (IPv4)', 'TCP/UDP Checksum Offload (IPv6)' + Set-NetAdapterAdvancedProperty -Name $interface -DisplayName 'Packet Direct' -RegistryValue 0 -ErrorAction SilentlyContinue + Set-NetAdapterAdvancedProperty -Name $interface -RegistryValue 1 -DisplayName 'Receive Side Scaling', 'Virtual Switch RSS', 'Virtual Machine Queues', 'NetworkDirect Functionality' -ErrorAction SilentlyContinue + } + $NodeOSCaption = (Get-CimInstance -ClassName 'Win32_OperatingSystem').Caption + Switch -Wildcard ($NodeOSCaption) + { + '*Windows Server 2016*' { + $SETSwitchUpdates = @{ DefaultQueueVrssQueueSchedulingMode = 'StaticVRSS' } + $vmNICUpdates = @{ VrssQueueSchedulingMode = 'StaticVRSS' } + $HostvNICUpdates = @{ VrssQueueSchedulingMode = 'StaticVRSS' } + } + '*Windows Server 2019*' { + $SETSwitchUpdates = @{ + EnableSoftwareRsc = $true + DefaultQueueVrssQueueSchedulingMode = 'Dynamic' + } + $vmNICUpdates = @{ VrssQueueSchedulingMode = 'Dynamic' } + $HostvNICUpdates = @{ VrssQueueSchedulingMode = 'Dynamic' } + } + } + $SETSwitchUpdates += @{ + Name = $SETTeam + DefaultQueueVrssEnabled = $true + DefaultQueueVmmqEnabled = $true + DefaultQueueVrssMinQueuePairs = 8 + DefaultQueueVrssMaxQueuePairs = 16 + } + $vmNICUpdates += @{ + VMName = '*' + VrssEnabled = $true + VmmqEnabled = $true + VrssMinQueuePairs = 8 + VrssMaxQueuePairs = 16 + } + $HostvNICUpdates += @{ + ManagementOS = $true + VrssEnabled = $true + VmmqEnabled = $true + VrssMinQueuePairs = 8 + VrssMaxQueuePairs = 16 + } + Set-VMSwitch @SETSwitchUpdates + Set-VMSwitchTeam -Name $SETTeam -LoadBalancingAlgorithm HyperVPort + Set-VMNetworkAdapter @HostvNICUpdates + Set-VMNetworkAdapter @vmNICUpdates + Remove-Variable SETSwitchUpdates, vmNICUpdates, HostvNICUpdates, NodeOSCaption -ErrorAction SilentlyContinue + } } diff --git a/appveyor.yml b/appveyor.yml index 345470d..0b1ef24 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -# YAML Reference Guide : https://www.appveyor.com/docs/appveyor-yml/ +# YAML Reference Guide : https://www.appveyor.com/docs/appveyor-yml/ # Environmental Variables Guide : https://www.appveyor.com/docs/environment-variables/ # YAML Validator : https://ci.appveyor.com/tools/validate-yaml # AppVeyor Build Pipeline : https://www.appveyor.com/docs/build-configuration/ @@ -62,7 +62,7 @@ skip_commits: # There's no need to alter the build number for a Pull Request (PR) since they don't modify anything pull_requests: - do_not_increment_build_number: true + do_not_increment_build_number: false #on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/tests/build/setup/initiate-tests.ps1 b/tests/build/setup/initiate-tests.ps1 index 70c4089..8f1b1d8 100644 --- a/tests/build/setup/initiate-tests.ps1 +++ b/tests/build/setup/initiate-tests.ps1 @@ -7,7 +7,8 @@ New-Item -Path .\tests -Name results -ItemType Directory -Force $testResultPath = '.\tests\build\results\TestResults.xml' # This is a manifest so no code coverage is possible. Original line kept below: #...\results\TestsResults.xml -PassThru -CodeCoverage .\MSFTNetworking.Tools.psd1 -$res = Invoke-Pester -Path ".\tests\build\unit" -OutputFormat NUnitXml -OutputFile $testResultPath -PassThru +Write-Host "Invoking Pester for path - .\tests\build\unit\*" +$res = Invoke-Pester -Path ".\tests\build\unit\*" -OutputFormat NUnitXml -OutputFile $testResultPath -PassThru (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultPath)) diff --git a/tests/build/setup/install.ps1 b/tests/build/setup/install.ps1 index b283a11..5798267 100644 --- a/tests/build/setup/install.ps1 +++ b/tests/build/setup/install.ps1 @@ -5,6 +5,7 @@ Invoke-AppveyorInstallTask [string[]]$PowerShellModules = @("Pester", 'posh-git', 'psake', 'poshspec', 'PSScriptAnalyzer') +Write-Host "Testing Module Manifest - .\$($env:RepoName).psd1" $ModuleManifest = Test-ModuleManifest .\$($env:RepoName).psd1 -ErrorAction SilentlyContinue $repoRequiredModules = $ModuleManifest.RequiredModules.Name $repoRequiredModules += $ModuleManifest.PrivateData.PSData.ExternalModuleDependencies @@ -50,13 +51,19 @@ ForEach ($Module in $PowerShellModules) { } } ElseIf ($Module -eq 'Pester') { - Install-Module $Module -Scope AllUsers -Force -Repository PSGallery -AllowClobber -SkipPublisherCheck -RequiredVersion 4.9.0 - Import-Module $Module -RequiredVersion 4.9.0 + Write-Host "Installing Module - $Module (v5.3.3)" + Install-Module $Module -Scope AllUsers -Force -Repository PSGallery -AllowClobber -SkipPublisherCheck -RequiredVersion 5.3.3 | Out-Null + Write-Host "Importing Module - $Module (v5.3.3)" + Import-Module $Module -RequiredVersion 5.3.3 | Out-Null + continue } else { - Install-Module $Module -Scope AllUsers -Force -Repository PSGallery -AllowClobber - Import-Module $Module + Write-Host "Installing Module - $Module" + Install-Module $Module -Scope AllUsers -Force -Repository PSGallery -AllowClobber | Out-Null + Write-Host "Importing Module - $Module" + Import-Module $Module | Out-Null + continue } - + Write-Host "Importing Module - $Module" Import-Module $Module } diff --git a/tests/build/unit/unit.build.tests.ps1 b/tests/build/unit/unit.build.tests.ps1 index 1a79c43..3e5f13c 100644 --- a/tests/build/unit/unit.build.tests.ps1 +++ b/tests/build/unit/unit.build.tests.ps1 @@ -1,41 +1,40 @@ Describe "$($env:repoName)-Manifest" { - $DataFile = Import-PowerShellDataFile .\$($env:repoName).psd1 -ErrorAction SilentlyContinue - $TestModule = Test-ModuleManifest .\$($env:repoName).psd1 -ErrorAction SilentlyContinue - + BeforeAll { + $DataFile = Import-PowerShellDataFile .\$($env:repoName).psd1 -ErrorAction Stop + $TestModule = Test-ModuleManifest .\$($env:repoName).psd1 -ErrorAction Stop + + Import-Module .\$($env:repoName).psd1 -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue + $command = Get-Command $($env:repoName) -ErrorAction SilentlyContinue + + $module = Find-Module -Name 'Pester' -ErrorAction SilentlyContinue + + $testCommand = Get-Command Convert-LBFO2SET + } Context Manifest-Validation { It "[Import-PowerShellDataFile] - $($env:repoName).psd1 is a valid PowerShell Data File" { - $DataFile | Should Not BeNullOrEmpty + $DataFile | Should -Not -BeNullOrEmpty } It "[Test-ModuleManifest] - $($env:repoName).psd1 should not be empty" { - $TestModule | Should Not BeNullOrEmpty + $TestModule | Should -Not -BeNullOrEmpty } - Import-Module .\$($env:repoName).psd1 -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue - $command = Get-Command $($env:repoName) -ErrorAction SilentlyContinue - It "Should have the $($env:repoName) function available" { - $command | Should not BeNullOrEmpty + $command | Should -Not -BeNullOrEmpty } } Context "Required Modules" { - 'Pester' | ForEach-Object { - $module = Find-Module -Name $_ -ErrorAction SilentlyContinue - - It "Should contain the $_ Module" { - $_ -in ($TestModule).RequiredModules.Name | Should be $true + It "Should contain the Pester Module" { + 'Pester' -in ($TestModule).RequiredModules.Name | Should -Be $true } - It "The $_ module should be available in the PowerShell gallery" { - $module | Should not BeNullOrEmpty + It "The Pester module should be available in the PowerShell gallery" { + $module | Should -Not -BeNullOrEmpty } - } } Context ExportedContent { - $testCommand = Get-Command Convert-LBFO2SET - It 'Should default the LBFOTeam mandatory param' { Get-Command Convert-LBFO2SET | Should -HaveParameter LBFOTeam -Mandatory }