Public/Channel/Get-TeamsTeamAndChannel.ps1

# Module: Orbit
# Function: TeamManagement
# Author: David Eberhardt
# Updated: 08-MAY-2021
# Status: Live




function Get-TeamsTeamAndChannel {
  <#
  .SYNOPSIS
    Returns a Team Object and a Channel Object from Team & Channel Names or IDs
  .DESCRIPTION
    Combining lookup for Team (Get-Team) and Channel (Get-TeamChannel) into one function to return the channel object.
  .PARAMETER Team
    Required. Name or GroupId (Guid). As the name might not be unique, validation is performed for unique matches.
    If the input matches a 36-digit GUID, lookup is performed via GroupId, otherwise via DisplayName
    Using Team & Channel does not require a Unique match for Team and Channel and will return all matches found.
  .PARAMETER Channel
    Required. Name or Id (Guid). If multiple Teams have been discovered, all Channels with this name in each team are returned.
    If the input matches a GUID (starting with "19:"), lookup is performed via Id, otherwise via DisplayName
    Using Team & Channel does not require a Unique match for Team and Channel and will return all matches found.
  .PARAMETER String
    Required for Parameterset String - Alternative lookup as a concatenated String of both Team Name (or Guid) and Channel Name (or Guid))
    "TeamId\ChannelId", "TeamId\ChannelDisplayName", "TeamDisplayName\ChannelId" or "TeamDisplayName\ChannelDisplayName"
    The string is split on the \ between these two.
    Using String requires a Unique match and will error if multiple results are found.
  .EXAMPLE
    Get-TeamsTeamAndChannel -Team "My Team" -Channel "CallQueue"
 
    Searches for Teams with the DisplayName of "My Team".
    If found, looking for a channel with the DisplayName "CallQueue"
    If found, the Channel Object will be returned
    Multiple Objects could be returned if multiple Teams called "My Team" with Channels called "CallQueue" exist.
  .EXAMPLE
    Get-TeamsTeamAndChannel -Team 1234abcd-1234-1234-1234abcd5678 -Channel "CallQueue"
 
    Searches for Teams with the GroupId of 1234abcd-1234-1234-1234abcd5678.
    If found, looking for a channel with the DisplayName "CallQueue"
    If found, the Channel Object will be returned
  .EXAMPLE
    Get-TeamsTeamAndChannel -Team "My Team" -Channel 19:1234abcd567890ef1234abcd567890ef@thread.skype
 
    Searches for Teams with the DisplayName of "My Team".
    If found, looking for a channel with the ID "19:1234abcd567890ef1234abcd567890ef@thread.skype"
    If found, the Channel Object will be returned
  .EXAMPLE
    Get-TeamsTeamAndChannel -Team 1234abcd-1234-1234-1234abcd5678 -Channel 19:1234abcd567890ef1234abcd567890ef@thread.skype
 
    If a Team with the GroupId 1234abcd-1234-1234-1234abcd5678 is found and this team has a channel with the ID
    "19:1234abcd567890ef1234abcd567890ef@thread.skype", the Channel Object will be returned
    This is the safest option as it will always find a correct result provided the entities exist.
    .EXAMPLE
    Get-TeamsTeamAndChannel -String "1234abcd-1234-1234-1234abcd5678\19:abcdef1234567890abcdef1234567890@thread.tacv2"
 
    If a Team with the GroupId 1234abcd-1234-1234-1234abcd5678 is found and this team has a channel with the ID
    "abcdef1234567890abcdef1234567890@thread.tacv2", the Channel Object will be returned
  .INPUTS
    System.String
  .OUTPUTS
    System.Object
  .NOTES
    This CmdLet combines two lookups in order to find a valid channel by Name(s).
    It is used to determine usability for Call Queues (Forward to Channel)
  .COMPONENT
    TeamsCallQueue
  .FUNCTIONALITY
    The idea is to simplify lookup of Teams and Channels and provide one CmdLet to find a unique match.
    When used with DisplayNames it executes the following command:
    Get-Team -DisplayName "$Team" | Get-TeamChannel | Where-Object Id -eq "$Channel"
    The CmdLet also supports providing the GUID for the Team or Channel to allow for more sturdy lookup.
  .LINK
    https://github.com/DEberhardt/Orbit/tree/main/docs/Orbit.Teams/Get-TeamsTeamAndChannel.md
  .LINK
    https://github.com/DEberhardt/Orbit/tree/main/docs/about/about_TeamsCallQueue.md
  .LINK
    https://github.com/DEberhardt/Orbit/tree/main/docs/
  #>


  [CmdletBinding(DefaultParameterSetName = 'Name')]
  [Alias('Get-Channel')]
  [OutputType([System.Object[]])]

  param (
    [Parameter(Mandatory, Position = 0, ParameterSetName = 'Name', ValueFromPipelineByPropertyName, HelpMessage = 'DisplayName (or GroupId) of the Team')]
    [string]$Team,

    [Parameter(Mandatory, Position = 1, ParameterSetName = 'Name', ValueFromPipelineByPropertyName, HelpMessage = 'DisplayName (or Id) of the Channel')]
    [string]$Channel,

    [Parameter(Mandatory, ParameterSetName = 'String', ValueFromPipeline, ValueFromPipelineByPropertyName, HelpMessage = 'Concatenated String of both Team Name (or Id) and Channel Name (or Id))')]
    [ValidateScript( {
        If ($_ -match '\\') { $True } else {
          throw [System.Management.Automation.ValidationMetadataException] "String must contain one '\'-character"
        } })]
    [string]$String
  )

  begin {
    Show-OrbitFunctionStatus -Level Live
    Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand)"

    # Asserting MicrosoftTeams Connection
    if ( -not (Assert-MicrosoftTeamsConnection) ) { throw 'Connection to Microsoft Teams not established. Please validate connection' }

    # Setting Preference Variables according to Upstream settings
    if (-not $PSBoundParameters['Verbose']) { $VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference') }
    if (-not $PSBoundParameters['Confirm']) { $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference') }
    if (-not $PSBoundParameters['WhatIf']) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') }
    $DebugPreference = if (-not $PSBoundParameters['Debug']) { $PSCmdlet.SessionState.PSVariable.GetValue('DebugPreference') } else { 'Continue' }
    $InformationPreference = if ( $PSBoundParameters['InformationAction']) { $PSCmdlet.SessionState.PSVariable.GetValue('InformationAction') } else { 'Continue' }

  } #begin

  process {
    Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand)"

    switch ( $PSCmdlet.ParameterSetName ) {
      'Name' { <# No action required #> }
      'String' { $Team, $Channel = $String.split('\') }
    }

    #Looking up Team
    try {
      Write-Verbose -Message "[PROCESS] Processing '$Team'"
      if ( $script:OrbitRegexGuid.isMatch($Team) ) {
        Write-Verbose -Message "Team '$Team' - Looking up Team with GroupId/GUID"
        $TeamObject = Get-Team -GroupId $Team -ErrorAction Stop
      }
      else {
        Write-Verbose -Message "Team '$Team' - Looking up Team with DisplayName"
        $TeamObject = Get-Team -DisplayName "$Team" -ErrorAction Stop
        Write-Verbose -Message "Team '$Team' - $($TeamObject.Count) Objects Found with '$Team' in the DisplayName"
        if ( $TeamObject.Count -gt 1 ) {
          $TeamObject = $TeamObject | Where-Object DisplayName -EQ "$Team"
          Write-Verbose -Message "Team '$Team' - $($TeamObject.Count) Objects Found with '$Team' as the exact DisplayName"
        }
        if ($null -eq $TeamObject) {
          Write-Error "No Object found for '$Team'!" -Category ParserError -RecommendedAction "Please check 'Name' provided" -ErrorAction Stop
          return $null, $null # Stopping operation as no Team was found
        }
      }
    }
    catch {
      throw "Error looking up Teams Team '$Team': $($_.Exception.Message)"
    }

    if ($PSBoundParameters['Debug'] -or $DebugPreference -eq 'Continue') {
      " Function: $($MyInvocation.MyCommand.Name) - TeamObject:", ($TeamObject | Format-Table -AutoSize | Out-String).Trim() | Write-Debug
    }

    #TEST Alternative
    #if ( $TeamObject.GetType().BaseType.Name -eq 'Array' ) {
    if ( $TeamObject.Count -gt 1 ) {
      switch ( $ParameterSetName ) {
        'Name' {
          Write-Warning -Message "Multiple Results found for '$Team' ($($TeamObject.Count)) - Searching for a unique match for the Channel '$Channel' within each team to determine a match! - All matches are returned" -Verbose
        }
        'String' {
          if ( $TeamObject.Count -gt 1 ) {
            Write-Verbose "$($MyInvocation.MyCommand) - Target is a Team\Channel, but not unique!"
            #throw [System.Reflection.AmbiguousMatchException]::New('Multiple Targets found - Result not unique (Team)')
            Write-Error "Multiple Results found for '$Team' ($($TeamObject.Count)) - A unique result is required for the Team" -ErrorAction Stop
          }
          else {
            Write-Verbose -Message "Unique result found for '$Team' - Id: '$($TeamObject.GroupId)'"
          }
        }
      }
    }
    else {
      Write-Verbose -Message "Unique result found for '$Team' - Id: '$($TeamObject.GroupId)'"
    }

    foreach ($TeamObj in $TeamObject) {
      #Looking up Channel within the Team
      Write-Verbose -Message "[PROCESS] Processing found object: '$($TeamObj.DisplayName)' - Channel '$Channel'"
      try {
        if ( $script:OrbitRegexChannelGuid.isMatch($Channel) ) {
          $ChannelObj = $TeamObj | Get-TeamChannel | Where-Object Id -EQ "$Channel" -ErrorAction Stop
        }
        else {
          $ChannelObj = $TeamObj | Get-TeamChannel | Where-Object DisplayName -EQ "$Channel" -ErrorAction Stop
        }
        if ($PSBoundParameters['Debug'] -or $DebugPreference -eq 'Continue') {
          " Function: $($MyInvocation.MyCommand.Name) - Channel:", ($ChannelObj | Format-Table -AutoSize | Out-String).Trim() | Write-Debug
        }

        # Output
        if ( $ChannelObj ) {
          Write-Verbose -Message "Team '$($TeamObj.DisplayName)' - Channel '$Channel' found"
          Write-Output $TeamObj, $ChannelObj
        }
        else {
          Write-Output $TeamObj
          throw "Team '$($TeamObj.DisplayName)' - Channel '$Channel': No Channel found in Team with this Name ID"

        }
      }
      catch {
        Write-Error "Team '$($TeamObj.DisplayName)' - Channel '$Channel': $($_.Exception.Message)"
      }
    }
  } #process

  end {
    Write-Verbose -Message "[END ] $($MyInvocation.MyCommand)"

  } #end
} #Get-TeamsTeamAndChannel