DSCResources/DSC_NetworkTeamInterface/DSC_NetworkTeamInterface.psm1

$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules'

# Import the Networking Common Modules
Import-Module -Name (Join-Path -Path $modulePath `
        -ChildPath (Join-Path -Path 'NetworkingDsc.Common' `
            -ChildPath 'NetworkingDsc.Common.psm1'))

Import-Module -Name (Join-Path -Path $modulePath -ChildPath 'DscResource.Common')

# Import Localization Strings
$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US'

<#
    .SYNOPSIS
    Returns the current state of a network team interface in a Network Team.
 
    .PARAMETER Name
    Specifies the name of the network team interface to create.
 
    .PARAMETER TeamName
    Specifies the name of the network team on which this particular interface should exist.
#>

function Get-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [Parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [Parameter(Mandatory = $true)]
        [System.String]
        $TeamName
    )

    $configuration = @{
        Name     = $Name
        TeamName = $TeamName
    }

    Write-Verbose -Message ($script:localizedData.GetTeamNicInfo -f $Name)

    $getNetLbfoTeamNicParameters = @{
        Name        = $Name
        Team        = $TeamName
        ErrorAction = 'SilentlyContinue'
    }
    $teamNic = Get-NetLbfoTeamNic @getNetLbfoTeamNicParameters

    if ($teamNic)
    {
        Write-Verbose -Message ($script:localizedData.FoundTeamNic -f $Name)

        $configuration.Add('VlanId', $teamNic.VlanId)
        $configuration.Add('Ensure', 'Present')
    }
    else
    {
        Write-Verbose -Message ($script:localizedData.TeamNicNotFound -f $Name)

        $configuration.Add('Ensure', 'Absent')
    }

    return $configuration
}

<#
    .SYNOPSIS
    Adds, updates or removes a network team interface from a Network Team.
 
    .PARAMETER Name
    Specifies the name of the network team interface to create.
 
    .PARAMETER TeamName
    Specifies the name of the network team on which this particular interface should exist.
 
    .PARAMETER VlanId
    Specifies VlanId to be set on network team interface.
 
    .PARAMETER Ensure
    Specifies if the network team interface should be created or deleted.
#>

function Set-TargetResource
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [Parameter(Mandatory = $true)]
        [System.String]
        $TeamName,

        [Parameter()]
        [System.UInt32]
        $VlanId,

        [Parameter()]
        [ValidateSet('Present', 'Absent')]
        [System.String]
        $Ensure = 'Present'
    )

    Write-Verbose -Message ($script:localizedData.GetTeamNicInfo -f $Name)

    $getNetLbfoTeamNicParameters = @{
        Name        = $Name
        Team        = $TeamName
        ErrorAction = 'SilentlyContinue'
    }
    $teamNic = Get-NetLbfoTeamNic @getNetLbfoTeamNicParameters

    if ($Ensure -eq 'Present')
    {
        if ($teamNic)
        {
            Write-Verbose -Message ($script:localizedData.FoundTeamNic -f $Name)

            if ($teamNic.VlanId -ne $VlanId)
            {
                Write-Verbose -Message ($script:localizedData.TeamNicVlanMismatch -f $VlanId)

                $isNetModifyRequired = $true
            }

            if ($isNetModifyRequired)
            {
                Write-Verbose -Message ($script:localizedData.ModifyTeamNic -f $Name)

                if ($VlanId -eq 0)
                {
                    $setNetLbfoTeamNicParameters = @{
                        Name        = $Name
                        Team        = $TeamName
                        Default     = $true
                        ErrorAction = 'Stop'
                        Confirm     = $false
                    }
                    Set-NetLbfoTeamNic @setNetLbfoTeamNicParameters
                }
                else
                {
                    <#
                        Required in case of primary interface, whose name gets changed
                        to include VLAN ID, if specified
                    #>

                    $setNetLbfoTeamNicParameters = @{
                        Name        = $Name
                        Team        = $TeamName
                        VlanId      = $VlanId
                        ErrorAction = 'Stop'
                        Confirm     = $false
                    }
                    $renameNetAdapterParameters = @{
                        NewName     = $Name
                        ErrorAction = 'SilentlyContinue'
                        Confirm     = $false
                    }
                    $null = Set-NetLbfoTeamNic @setNetLbfoTeamNicParameters |
                        Rename-NetAdapter @renameNetAdapterParameters
                }
            }
        }
        else
        {
            Write-Verbose -Message ($script:localizedData.CreateTeamNic -f $Name)

            if ($VlanId -ne 0)
            {
                $addNetLbfoTeamNicParameters = @{
                    Name        = $Name
                    Team        = $TeamName
                    VlanId      = $VlanId
                    ErrorAction = 'Stop'
                    Confirm     = $false
                }
                $null = Add-NetLbfoTeamNic @addNetLbfoTeamNicParameters

                Write-Verbose -Message ($script:localizedData.CreatedNetTeamNic -f $Name)
            }
            else
            {
                New-InvalidOperationException `
                    -Message ($script:localizedData.FailedToCreateTeamNic)
            }
        }
    }
    else
    {
        Write-Verbose -Message ($script:localizedData.RemoveTeamNic -f $Name)

        $removeNetLbfoTeamNicParameters = @{
            Team        = $teamNic.Team
            VlanId      = $teamNic.VlanId
            ErrorAction = 'Stop'
            Confirm     = $false
        }
        $null = Remove-NetLbfoTeamNic @removeNetLbfoTeamNicParameters
    }
}

<#
    .SYNOPSIS
    Tests is a specified Network Team Interface is in the correct state.
 
    .PARAMETER Name
    Specifies the name of the network team interface to create.
 
    .PARAMETER TeamName
    Specifies the name of the network team on which this particular interface should exist.
 
    .PARAMETER VlanId
    Specifies VlanId to be set on network team interface.
 
    .PARAMETER Ensure
    Specifies if the network team interface should be created or deleted.
#>

function Test-TargetResource
{
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param
    (
        [Parameter(Mandatory = $true)]
        [System.String]
        $Name,

        [Parameter(Mandatory = $true)]
        [System.String]
        $TeamName,

        [Parameter()]
        [System.UInt32]
        $VlanId,

        [Parameter()]
        [ValidateSet('Present', 'Absent')]
        [System.String]
        $Ensure = 'Present'
    )

    Write-Verbose -Message ($script:localizedData.GetTeamNicInfo -f $Name)

    $getNetLbfoTeamNicParameters = @{
        Name        = $Name
        Team        = $TeamName
        ErrorAction = 'SilentlyContinue'
    }
    $teamNic = Get-NetLbfoTeamNic @getNetLbfoTeamNicParameters

    if ($VlanId -eq 0)
    {
        $VlanValue = $null
    }
    else
    {
        $VlanValue = $VlanId
    }

    if ($Ensure -eq 'Present')
    {
        if ($teamNic)
        {
            Write-Verbose -Message ($script:localizedData.FoundTeamNic -f $Name)

            if ($teamNic.VlanId -eq $VlanValue)
            {
                Write-Verbose -Message ($script:localizedData.TeamNicExistsNoAction -f $Name)

                return $true
            }
            else
            {
                Write-Verbose -Message ($script:localizedData.TeamNicExistsWithDifferentConfig -f $Name)

                return $false
            }
        }
        else
        {
            Write-Verbose -Message ($script:localizedData.TeamNicDoesNotExistShouldCreate -f $Name)

            return $false
        }
    }
    else
    {
        if ($teamNic)
        {
            Write-Verbose -Message ($script:localizedData.TeamNicExistsShouldRemove -f $Name)

            return $false
        }
        else
        {
            Write-Verbose -Message ($script:localizedData.TeamNicExistsNoAction -f $Name)

            return $true
        }
    }
}

Export-ModuleMember -Function *-TargetResource