Private/Merge-AutoAttendantArtefact.ps1

# Module: TeamsFunctions
# Function: Teams Auto Attendant
# Author: David Eberhardt
# Updated: 01-DEC-2020
# Status: Live




function Merge-AutoAttendantArtefact {
  <#
    .SYNOPSIS
        Merges multiple Artefacts of an Auto Attendant into one Object for display
    .DESCRIPTION
    Helper function to prepare a nested Object of an Auto Attendant for display
    Used in Get-TeamsAutoAttendant
  .PARAMETER Object
    The input Object to transform
  .PARAMETER Type
    Type of Object (will determine Output)
  .PARAMETER Prompts
    Only valid for Type Call Flow and Menu - Object representing the Call Prompts
  .PARAMETER MenuOptions
    Only valid for Type Menu - Object representing the Menu Options
  .PARAMETER Menu
    Only valid for Type Call Flow - Object representing the Menu
  .INPUTS
    Microsoft.Rtc.Management.Hosted.OAA.Models.CallFlow
    Microsoft.Rtc.Management.Hosted.OAA.Models.Menu
    Microsoft.Rtc.Management.Hosted.OAA.Models.MenuOption
    Microsoft.Rtc.Management.Hosted.OAA.Models.CallHandlingAssociation
    Microsoft.Rtc.Management.Hosted.Online.Models.Schedule
    Microsoft.Rtc.Management.Hosted.OAA.Models.Prompt
  .OUTPUTS
    PSCustomObject
  .NOTES
    Schedule requires the queried Object from Get-CsOnlineSchedule
    All other parmeter work with the nested Object from the Auto Attendant Object
  .LINK
    https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/
  .LINK
    Get-TeamsAutoAttendant
 
    #>


  [CmdletBinding(DefaultParameterSetName = 'MenuOption')]
  [OutputType([System.Object[]])]
  param(
    [Parameter(Mandatory, HelpMessage = 'Object for the AA')]
    [object[]]$Object,

    [Parameter(Mandatory, HelpMessage = 'Type of Object presented. Determines Output')]
    [ValidateSet('Prompt', 'MenuOption', 'Menu', 'CallFlow', 'Schedule', 'CallHandlingAssociation')]
    [string]$Type,

    [Parameter(Mandatory, ParameterSetName = 'CallFlow', HelpMessage = "Merged Object of 'Prompts' to be added to Call Flows or Menus")]
    [Parameter(Mandatory, ParameterSetName = 'Menu', HelpMessage = "Merged Object of 'Prompts' to be added to Call Flows or Menus")]
    [Parameter(ParameterSetName = 'MenuOption', HelpMessage = "Merged Object of 'Prompts' to be added to Menu Options")]
    [AllowNull()]
    [object[]]$Prompts,

    [Parameter(Mandatory, ParameterSetName = 'Menu', HelpMessage = "Merged Object of 'MenuOptions' to be added to Menus")]
    [AllowNull()]
    [object[]]$MenuOptions,

    [Parameter(Mandatory, ParameterSetName = 'CallFlow', HelpMessage = "Merged Object of 'Menu' to be added to Call Flows")]
    [AllowNull()]
    [object]$Menu,

    [Parameter(Mandatory, ParameterSetName = 'CallHandlingAssociation', HelpMessage = 'CallHandling Association only: Name of the Call Flow')]
    [object]$CallFlowName
  ) #param

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

    $OFS = ''
  } #begin

  process {
    Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - Processing Auto Attendant Artefact of Type '$Type'"

    #$MergedObject = @()
    [System.Collections.Generic.List[object]]$MergedObject = @()
    switch ($Type) {
      'Prompt' {
        foreach ($O in $Object) {
          if ( $O.HasAudioFilePromptData ) {
            Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Querying Audio File for Prompt"
            $AudioFilePrompt = @()
            $AudioFilePrompt = [PsCustomObject][ordered]@{
              PSTypeName          = 'PowerShell.TeamsFunctsions.AutoAttendant.Prompt.AudioFilePrompt'
              'Id'                = $O.AudioFilePrompt.Id
              'FileName'          = $O.AudioFilePrompt.FileName
              'DownloadUri'       = $O.AudioFilePrompt.DownloadUri
              'MarkedForDeletion' = $O.AudioFilePrompt.MarkedForDeletion
            }
            Add-Member -Force -InputObject $AudioFilePrompt -MemberType ScriptMethod -Name ToString -Value {
              [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
            }
          }
          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Creating Prompt Object"
          $SingleObject = @()
          $SingleObject = [PsCustomObject][ordered]@{
            PSTypeName           = 'PowerShell.TeamsFunctsions.AutoAttendant.Prompt'
            'ActiveType'         = $O.ActiveType
            'TextToSpeechPrompt' = $O.TextToSpeechPrompt
            'AudioFilePrompt'    = $AudioFilePrompt
            # More boolean parameters are available with | FL *:
            # HasTextToSpeechPromptData, HasAudioFilePromptData, IsAudioFileAlreadyUploaded, IsDisabled, HasDualPromptData
          }

          Add-Member -Force -InputObject $SingleObject -MemberType ScriptMethod -Name ToString -Value {
            [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
          }

          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Adding Object"
          $MergedObject.Add($SingleObject)
        }

        return $MergedObject
      }

      'MenuOption' {
        foreach ($O in $Object) {
          # Enumerating Call Target
          if ($O.CallTarget.Id) {
            Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Querying Call Target for Menu Option"
            $CallTargetEntity = Get-TeamsCallableEntity $O.CallTarget.Id

            $CallTarget = @()
            $CallTarget = [PsCustomObject][ordered]@{
              PSTypeName = 'PowerShell.TeamsFunctsions.AutoAttendant.Menu.MenuOption.CallTarget'
              'Entity'   = $CallTargetEntity.Entity
              'Identity' = $O.CallTarget.Id
              'Type'     = $O.CallTarget.Type
            }

            Add-Member -Force -InputObject $CallTarget -MemberType ScriptMethod -Name ToString -Value {
              #[System.Environment]::NewLine +
              (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
            }
          }
          else {
            $CallTarget = $null
          }

          # Creating Object
          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Creating MenuOption Object"
          $SingleObject = @()
          $SingleObject = [PsCustomObject][ordered]@{
            PSTypeName       = 'PowerShell.TeamsFunctsions.AutoAttendant.Menu.MenuOption'
            'DtmfResponse'   = $O.DtmfResponse
            'VoiceResponses' = $O.VoiceResponses
            'Prompt'         = if ( $Prompts ) { $Prompts } else { $O.Prompt }
            'Action'         = $O.Action
            'CallTarget'     = if ( $CallTarget ) { $CallTarget } else { $O.Prompt } # $CallTarget
          }

          Add-Member -Force -InputObject $SingleObject -MemberType ScriptMethod -Name ToString -Value {
            ([System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine).replace(',', [System.Environment]::NewLine)
          }

          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Adding Object"
          $MergedObject.Add($SingleObject)
        }

        return $MergedObject
      }

      'Menu' {
        foreach ($O in $Object) {
          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Creating Menu Object"
          $SingleObject = @()
          $SingleObject = [PsCustomObject][ordered]@{
            PSTypeName              = 'PowerShell.TeamsFunctsions.AutoAttendant.Menu'
            'Name'                  = $O.Name
            'Prompts'               = if ( $Prompts ) { $Prompts } else { $O.Prompt } # $Prompts
            'MenuOptions'           = if ( $MenuOptions ) { $MenuOptions } else { $O.MenuOptions } # $MenuOptions
            'DialByNameEnabled'     = $O.DialByNameEnabled
            'DirectorySearchMethod' = $O.DirectorySearchMethod
          }

          Add-Member -Force -InputObject $SingleObject -MemberType ScriptMethod -Name ToString -Value {
            [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
          }

          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Adding Object"
          $MergedObject.Add($SingleObject)
        }

        return $MergedObject
      }

      'CallFlow' {
        foreach ($O in $Object) {
          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Creating Call Flow Object"
          $SingleObject = @()
          $SingleObject = [PsCustomObject][ordered]@{
            PSTypeName  = 'PowerShell.TeamsFunctsions.AutoAttendant.CallFlow'
            'Name'      = $O.Name
            'Id'        = $O.Id
            'Greetings' = if ( $Prompts ) { $Prompts } else { $O.Greetings } # $Prompts
            'Menu'      = $Menu
          }

          Add-Member -Force -InputObject $SingleObject -MemberType ScriptMethod -Name ToString -Value {
            [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
          }

          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Adding Object"
          $MergedObject.Add($SingleObject)
        }

        return $MergedObject
      }

      'Schedule' {
        foreach ($O in $Object) {
          switch ($O.Type) {
            'WeeklyRecurrence' {
              #BODGE This had DisplayMondayHours prior, has the object changed?
              # Schedule Type is WeeklyRecurrence
              Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Creating WeeklyRecurrent Schedule Object"
              $FixedSchedule = $null
              $WeeklyRecurrentSchedule = @()
              <# This worked before but Display...Hours are no longer available?
              $WeeklyRecurrentSchedule = [PsCustomObject][ordered]@{
                PSTypeName = 'PowerShell.TeamsFunctsions.AutoAttendant.Schedule.WeeklyRecurrantSchedule'
                'ComplementEnabled' = $O.WeeklyRecurrentSchedule.ComplementEnabled
                'MondayHours' = $O.WeeklyRecurrentSchedule.DisplayMondayHours
                'TuesdayHours' = $O.WeeklyRecurrentSchedule.DisplayTuesdayHours
                'WednesdayHours' = $O.WeeklyRecurrentSchedule.DisplayWednesdayHours
                'ThursdayHours' = $O.WeeklyRecurrentSchedule.DisplayThursdayHours
                'FridayHours' = $O.WeeklyRecurrentSchedule.DisplayFridayHours
                'SaturdayHours' = $O.WeeklyRecurrentSchedule.DisplaySaturdayHours
                'SundayHours' = $O.WeeklyRecurrentSchedule.DisplaySundayHours
              }
              #>

              $WeeklyRecurrentSchedule = [PsCustomObject][ordered]@{
                PSTypeName          = 'PowerShell.TeamsFunctsions.AutoAttendant.Schedule.WeeklyRecurrantSchedule'
                'ComplementEnabled' = $O.WeeklyRecurrentSchedule.ComplementEnabled
                'MondayHours'       = "$($O.WeeklyRecurrentSchedule.MondayHours.Start)-$($O.WeeklyRecurrentSchedule.MondayHours.End)"
                'TuesdayHours'      = "$($O.WeeklyRecurrentSchedule.TuesdayHours.Start)-$($O.WeeklyRecurrentSchedule.TuesdayHours.End)"
                'WednesdayHours'    = "$($O.WeeklyRecurrentSchedule.WednesdayHours.Start)-$($O.WeeklyRecurrentSchedule.WednesdayHours.End)"
                'ThursdayHours'     = "$($O.WeeklyRecurrentSchedule.ThursdayHours.Start)-$($O.WeeklyRecurrentSchedule.ThursdayHours.End)"
                'FridayHours'       = "$($O.WeeklyRecurrentSchedule.FridayHours.Start)-$($O.WeeklyRecurrentSchedule.FridayHours.End)"
                'SaturdayHours'     = "$($O.WeeklyRecurrentSchedule.SaturdayHours.Start)-$($O.WeeklyRecurrentSchedule.SaturdayHours.End)"
                'SundayHours'       = "$($O.WeeklyRecurrentSchedule.SundayHours.Start)-$($O.WeeklyRecurrentSchedule.SundayHours.End)"
              }

              Add-Member -Force -InputObject $WeeklyRecurrentSchedule -MemberType ScriptMethod -Name ToString -Value {
                [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
              }
            }

            'Fixed' {
              # Schedule Type is Fixed
              Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Creating Fixed Schedule Object"
              $WeeklyRecurrentSchedule = $null
              <# This worked before no longer?
              $FixedSchedule = $Schedule.FixedSchedule.DisplayDateTimeRanges
              #>

              #BODGE This lists all DTR in one list, but should introduce line-break. Need another Call Merge for DTRs, calling itself?
              $FixedSchedule = foreach ( $DTR in $Schedule.FixedSchedule.DateTimeRanges ) { "$($DTR.Start)-$($DTR.End)" }
              Add-Member -Force -InputObject $FixedSchedule -MemberType ScriptMethod -Name ToString -Value {
                [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
              }
            }
          }

          $SingleObject = @()
          $SingleObject = [PsCustomObject][ordered]@{
            PSTypeName                = 'PowerShell.TeamsFunctsions.AutoAttendant.Schedule'
            'Name'                    = $O.Name
            'Type'                    = $O.Type
            'WeeklyRecurrentSchedule' = $WeeklyRecurrentSchedule
            'FixedSchedule'           = $FixedSchedule
            'Id'                      = $O.Id
          }

          Add-Member -Force -InputObject $SingleObject -MemberType ScriptMethod -Name ToString -Value {
            [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
          }
          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Adding Object"
          $MergedObject.Add($SingleObject)
        }

        return $MergedObject
      }

      'CallHandlingAssociation' {
        foreach ($O in $Object) {
          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Creating CallHandlingAssociation Object"
          $SingleObject = @()
          $SingleObject = [PsCustomObject][ordered]@{
            PSTypeName = 'PowerShell.TeamsFunctsions.AutoAttendant.CallHandlingAssociation'
            'Type'     = $O.Type
            'Enabled'  = $O.Enabled
            'Schedule' = $(Get-CsOnlineSchedule -Id $O.ScheduleId).Name
            'CallFlow' = $CallFlowName
          }

          Add-Member -Force -InputObject $SingleObject -MemberType ScriptMethod -Name ToString -Value {
            [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') + [System.Environment]::NewLine
          }
          Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - $Type - Adding Object"
          $MergedObject.Add($SingleObject)
        }

        return $MergedObject
      }
    }

  } #process

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

} # Merge-AutoAttendantArtefact