DSCResources/cSwitchEmbeddedTeam/cSwitchEmbeddedTeam.psm1
# Fallback message strings in en-US DATA localizedData { # same as culture = "en-US" ConvertFrom-StringData @' PacketDirectMustUseHyperVPort=Using Enable Packet Redirect on the SET team must use Hyper-V Port mode as the load balancing algorightm. This will reset the LB mode. NoHyperVModule=Hyper-V PowerShell Module not found. CheckSETMembers=Checking if SET network adapter members match or not. TeamMembersUpdate=SET Network Adapter members mismatch. This will be updated. LBUpdate=SET load balancing mode is different. It will be updated. TeamingModeUpdate=SET teaming mode is differet. It will be updated. UpdatingSETeam=Updating SET configuration as requested. UpdateAllowManagementOS=Updating AllowManagementOS on the VM switch associated with the SET. IOVcannotbeUpdated=EnableIOV cannot be updated once SET is created. Ignoring this change in configuration. ReservationModeCannotBeUpdated=Reservation mode cannot be updated once SET is created. Ignoring this change in configuration. PacketDirectCannotBeUpdated=Packet Direct cannot be updated once SET is created. Ignoring this change in configuration. CheckNetAdapter=Checking if network adapter specified is a part of another VM switch. SwitchWithNameExists=Another switch with specified name already exists. It is not recommeded to use the same name for mulitple switches. UsedAdapter=One of the adapters in the specified SET configuration is being used in another switch. CreateSET=Creating SwitchEmbeddedTeam. UpdateSET=Updating SwitchEmbeddedTeam. RemoveSET=Removing SwitchEmbeddedTeam. CheckSwitchExists=Checking if SET already exists. SETMembersDontMatch=SET members don't match. This team will be updated. CheckSETIOV=Checking if IOV is enabled. CheckSETReservationMode=Checking if reservation mode is configured as desired. CheckSETEnablePacketDirect=Checking if packet direct is enabled. CheckSETLoadBalacing=Checking if load balancing mode is configured as desired. CheckSETTeamingMode=Checking if SET teaming mode is configured as desired. SwitchConfigPresentNoAction=Switch configuration present as desired. No action needed. SwitchPresentRemove=Switch team is present while it should not. It will be removed. SwitchNotPresentCreate=Switch team does not exist. It will be created. SwitchNotPresentNoAction=Switch team exists. No action needed. SwitchNotPresent=Switch is not present. CheckSETAllowManagementOS=Checking if AllowManagementOS configurtion is present. '@ } if (Test-Path "$PSScriptRoot\$PSCulture") { Import-LocalizedData LocalizedData -filename "cSwitchEmbeddedTeam.psd1" -BaseDirectory "$PSScriptRoot\$PSCulture" } function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory)] [String]$Name, [parameter()] [String[]]$NetAdapterName ) # Check if Hyper-V module is present for Hyper-V cmdlets if(!(Get-Module -ListAvailable -Name Hyper-V)) { Throw $localizedData.NoHyperVModule } $SwitchTeam = Get-VMSwitchTeam -Name $Name -ErrorAction SilentlyContinue $Switch = Get-VMSwitch -Name $Name -ErrorAction SilentlyContinue $SwitchAdapter = ((Get-NetAdapter).Where({$switchTeam.NetAdapterInterfaceDescription -contains $_.InterfaceDescription})).Name @{ Name = $SwitchTeam.Name NetAdapterName = $SwitchAdapter AllowManagementOS = $switch.AllowManagementOS EnablePacketDirect = $Switch.PacketDirectEnabled EnableIov = $switch.IovEnabled BandwidthReservationMode = $switch.BandwidthReservationMode TeamingMode = $SwitchTeam.TeamingMode LoadBalancingAlgorithm = $SwitchTeam.LoadBalancingAlgorithm } } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory)] [String]$Name, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateLength(1,8)] [String[]]$NetAdapterName, [Parameter()] [Boolean]$AllowManagementOS, [Parameter()] [Boolean]$EnableIov, [Parameter()] [Boolean]$EnablePacketDirect, [parameter()] [ValidateSet('SwitchIndependent')] [String]$TeamingMode='SwitchIndependent', [parameter()] [ValidateSet('Dynamic','HyperVPort')] [String]$LoadBalancingAlgorithm='Dynamic', [Parameter()] [ValidateSet('None', 'Default', 'Weight', 'Absolute')] [String] $BandwidthReservationMode, [ValidateSet("Present","Absent")] [String]$Ensure = "Present" ) # Check if Hyper-V module is present for Hyper-V cmdlets if(!(Get-Module -ListAvailable -Name Hyper-V)) { Throw $localizedData.NoHyperVModule } if($Ensure -eq 'Present') { $switchTeam = (Get-VMSwitchTeam -Name $Name -ErrorAction SilentlyContinue) if($switchTeam) { $switch = Get-VMSwitch -Name $Name -ErrorAction SilentlyContinue Write-Verbose $localizedData.CheckSETMembers $SwitchAdapter = ((Get-NetAdapter).Where({$switchTeam.NetAdapterInterfaceDescription -contains $_.InterfaceDescription})).Name $SwitchTeamMembers = Compare-Object -ReferenceObject $NetAdapterName -DifferenceObject $SwitchAdapter $TeamParameters = @{ Name = $name } if($SwitchTeamMembers -ne $null) { $TeamParameters.Add('NetAdapterName',$NetAdapterName) $UpdateTeam = $true Write-Verbose $localizedData.TeamMembersUpdate } if ($switchTeam.LoadBalancingAlgorithm -ne $LoadBalancingAlgorithm) { $TeamParameters.Add('LoadBalancingAlgorithm',$LoadBalancingAlgorithm) Write-Verbose $localizedData.LBUpdate $UpdateTeam = $true } if ($switchTeam.TeamingMode -ne $TeamingMode) { $TeamParameters.Add('TeamingMode', $TeamingMode) Write-Verbose $localizedData.TeamingModeUpdate $UpdateTeam = $true } if ($UpdateTeam) { Write-Verbose $localizedData.UpdatingSETeam Set-VMSwitchTeam @TeamParameters -Verbose } if ($switch.AllowManagementOS -ne $AllowManagementOS) { Write-Verbose $localizedData.UpdateAllowManagementOS $switch | Set-VMSwitch -AllowManagementOS $AllowManagementOS -Verbose } if ($switch.IovEnabled -ne $EnableIov) { Write-Warning $localizedData.IOVcannotbeUpdated } elseif ($BandwidthReservationMode -and ($switch.BandwidthReservationMode -ne $BandwidthReservationMode)) { Write-Warning $locallizedData.ReservationModeCannotBeUpdated } if ($switch.PacketDirectEnabled -ne $EnablePacketDirect) { Write-Warning $localizedData.PacketDirectCannotBeUpdated } } else { Write-Verbose -Message $localizedData.CheckNetAdapter $VMSwitchArray = Get-VMSwitch Foreach ($vmSwitch in $VMSwitchArray) { if ($vmSwitch.Name -eq $Name) { Write-Warning $localizedData.SwitchWithNameExists } $SwitchAdapter = ((Get-NetAdapter).Where({$vmSwitch.NetAdapterInterfaceDescriptions -contains $_.InterfaceDescription})).Name $UsedAdapter = ((Compare-Object $SwitchAdapter $NetAdapterName -IncludeEqual).Where({$_.SideIndicator -eq '=='})).InputObject if ($UsedAdapter) { Throw $localizedData.UsedAdapter } } $parameters = @{ Name = $Name NetAdapterName = $NetAdapterName AllowManagementOS = $AllowManagementOS EnablePacketDirect = $EnablePacketDirect } if ($EnablePacketDirect -and ($LoadBalancingAlgorithm -ne 'HyperVPort')) { Write-Warning $localizedData.PacketDirectMustUseHyperVPort $LoadBalancingAlgorithm = 'HyperVPort' } if ($NetAdapterName.Length -eq 1) { $parameters.Add('EnableEmbeddedTeaming',$true) } if ($EnableIov) { $parameters.Add('EnableIov',$true) } elseif($BandwidthReservationMode) { $parameters.Add('MinimumBandwidthMode',$BandwidthReservationMode) } Write-Verbose $localizedData.CreateSET $null = New-VMSwitch @parameters -ErrorAction Stop Write-Verbose $localizedData.UpdateSET $null = Set-VMSwitchTeam -Name $Name -TeamingMode $TeamingMode -LoadBalancingAlgorithm $LoadBalancingAlgorithm -ErrorAction Stop } } # Ensure is set to "Absent", remove the switch else { Write-Verbose $localizedData.RemoveSET Get-VMSwitch $Name -ErrorAction SilentlyContinue | Remove-VMSwitch -Force -ErrorAction Stop } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory)] [String]$Name, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateLength(1,8)] [String[]]$NetAdapterName, [Parameter()] [Boolean]$AllowManagementOS, [Parameter()] [Boolean]$EnableIov, [Parameter()] [Boolean]$EnablePacketDirect, [parameter()] [ValidateSet('SwitchIndependent')] [String]$TeamingMode='SwitchIndependent', [parameter()] [ValidateSet('Dynamic','HyperVPort')] [String]$LoadBalancingAlgorithm='Dynamic', [Parameter()] [ValidateSet('None', 'Default', 'Weight', 'Absolute')] [String] $BandwidthReservationMode, [ValidateSet("Present","Absent")] [String]$Ensure = "Present" ) # Check if Hyper-V module is present for Hyper-V cmdlets if(!(Get-Module -ListAvailable -Name Hyper-V)) { Throw $localizedData.NoHyperVModule } try { # Check if switch exists Write-Verbose $localizedData.CheckSwitchExists $switchTeam = Get-VMSwitchTeam -Name $Name -ErrorAction Stop # If SET exists if($switchTeam) { $Switch = Get-VMSwitch -Name $Name if($Ensure -eq 'Present') { Write-Verbose $localizedData.CheckSETMembers $SwitchAdapter = ((Get-NetAdapter).Where({$switchTeam.NetAdapterInterfaceDescription -contains $_.InterfaceDescription})).Name $SwitchTeamMembers = Compare-Object -ReferenceObject $NetAdapterName -DifferenceObject $SwitchAdapter if($SwitchTeamMembers -ne $null) { Write-Verbose $localizedData.SETMembersDontMatch return $false } if($PSBoundParameters.ContainsKey("AllowManagementOS")) { Write-Verbose $localizedData.CheckSETAllowManagementOS if(($switch.AllowManagementOS -ne $AllowManagementOS)) { Write-Verbose $localizedData.UpdateAllowManagementOS return $false } } if ($EnableIov) { Write-Verbose $localizedData.CheckSETIOV if (-not $switch.IovEnabled) { Write-Warning $localizedData.IOVcannotbeUpdated #We cannot update this configuration once switch is created unless we destroy and re-create. Destroying is a good option. So, don't return false. return $true } } else { Write-Verbose $localizedData.CheckSETReservationMode if ($BandwidthReservationMode -and ($BandwidthReservationMode -ne $switch.BandwidthReservationMode)) { Write-Warning $localizedData.ReservationModeCannotBeUpdated return $true } } if ($EnablePacketDirect) { Write-Verbose $localizedData.CheckSETEnablePacketDirect if (-not $switch.EnablePacketDirect) { Write-Warning $localizedData.PacketDirectCannotBeUpdated #We cannot update this configuration once switch is created unless we destroy and re-create. Destroying is a good option. So, don't return false. return $true } } Write-Verbose $localizedData.CheckSETLoadBalacing if ($switchTeam.LoadBalancingAlgorithm -ne $LoadBalancingAlgorithm) { return $false } Write-Verbose $localizedData.CheckSETTeamingMode if ($switchTeam.TeamingMode -ne $TeamingMode) { return $false } Write-Verbose $localizedData.SwitchConfigPresentNoAction return $true } # If switch should be absent, but is there, return $false else { Write-Verbose $localizedData.SwitchPresentRemove return $false } } else { if ($Ensure -eq 'Present') { Write-Verbose $localizedData.SwitchNotPresentCreate return $false } else { Write-Verbose $localizedData.SwitchNotPresentNoAction return $true } } } catch [System.Management.Automation.ActionPreferenceStopException] { Write-Verbose $localizedData.SwitchNotPresent return $false } } Export-ModuleMember -Function *-TargetResource |