Public/AutoAttendant/Update-TeamsAutoAttendantHoliday.ps1
# Module: TeamsFunctions # Function: AutoAttendant # Author: David Eberhardt # Updated: 03-SEP 2022 # Status: RC function Update-TeamsAutoAttendantHoliday { <# .SYNOPSIS Changing, amending or replacing the Holiday Call Flow on existing Auto Attendants; Calling Set-CsAutoAttendant .DESCRIPTION Editing exiting Auto Attendants with Set-CsAutoAttendant requires manual creation of objects and surgical replacement. This script tries to simplify editing Auto Attendants by providing four functions: Update-TeamsAutoAttendant covers general Settings of the Auto Attendnat Update-TeamsAutoAttendantBusinessHours covers the Default Call Flow Update-TeamsAutoAttendantAfterHours covers the After Hours Call Flow Update-TeamsAutoAttendantHoliday covers the Holiday Call Flow Each individual Script can replace the full call flow with a previously created object, or amend some specific parts of the respective flow .PARAMETER Name Name of the Auto Attendant. Required to locate the Auto Attendant. Alternatively ID of the Auto Attendant for more precise location .PARAMETER HolidaySetGreeting Optional. Creates a Greeting for the Holiday Set Call Flow utilising New-TeamsAutoAttendantPrompt A supported Audio File or a text string that is parsed by the text-to-voice engine in the Language specified The last 4 digits will determine the type. For an AudioFile they are expected to be the file extension: '.wav', '.wma' or 'mp3' If CallFlows and CallHandlingAssociations are provided, this parameter will be ignored. .PARAMETER HolidaySetCallFlowOption Optional. Disconnect, TransferCallToTarget, Menu. Default is Disconnect. TransferCallToTarget requires HolidaySetCallTarget. Menu requires HolidaySetMenu If CallFlows and CallHandlingAssociations are provided, this parameter will be ignored. .PARAMETER HolidaySetCallTarget Optional. Requires HolidaySetCallFlowOption to be TransferCallToTarget. Creates a Callable entity for this Call Target Expected are UserPrincipalName (User, ResourceAccount), a TelURI (ExternalPstn), an Office 365 Group Name (SharedVoicemail) If CallFlows and CallHandlingAssociations are provided, this parameter will be ignored. .PARAMETER HolidaySetMenu Optional. Requires HolidaySetCallFlowOption to be Menu and a HolidaySetCallTarget If CallFlows and CallHandlingAssociations are provided, this parameter will be ignored. .PARAMETER HolidaySetSchedule Optional. Default Schedule to apply: Either a 2-digit Country Code to create the schedule for the next three years for, a Schedule Object created beforehand or an existing Schedule Object ID already created in the Tenant If not provided, an empty Schedule Object will be created which will never be in effect. If CallFlows and CallHandlingAssociations are provided, this parameter will be ignored. .PARAMETER Replace Replaces all Holiday Flows with the current. If not provided, will add a Flow instead .PARAMETER EnableTranscription Optional. Where possible, tries to enable Voicemail Transcription. Effective only for SharedVoicemail Targets as an Operator or MenuOption. Otherwise has no effect. .PARAMETER PassThru Optional. Displays Auto Attendant Object after action. .PARAMETER Force Suppresses confirmation prompt to enable Users for Enterprise Voice, if Users are specified Currently no other impact .EXAMPLE New-TeamsAutoAttendant -Name "My Auto Attendant" Creates a new Auto Attendant "My Auto Attendant" with Defaults TimeZone is UTC, Language is en-US and Schedule is Mon-Fri 9to5. Business hours and After Hours action is Disconnect .EXAMPLE New-TeamsAutoAttendant -Name "My Auto Attendant" -TimeZone UTC-05:00 -LanguageId pt-BR -AfterHoursSchedule MonToFri8to12and13to18 -EnableVoiceResponse Creates a new Auto Attendant "My Auto Attendant" and sets the TimeZone to UTC-5 and the language to Portuguese (Brazil) The Schedule of Mon-Fri 8to12 and 13to18 will be applied. Also enables VoiceResponses .EXAMPLE New-TeamsAutoAttendant -Name "My Auto Attendant" -Operator "tel:+1555123456" Creates a new Auto Attendant "My Auto Attendant" with default TimeZone and Language, but defines an Operator as a Callable Entity (Forward to Pstn) .EXAMPLE New-TeamsAutoAttendant -Name "My Auto Attendant" -BusinessHoursGreeting "Welcome to Contoso" -BusinessHoursCallFlowOption TransferCallToTarget -BusinessHoursCallTarget $CallTarget Creates a new Auto Attendant "My Auto Attendant" with defaults, but defines a Text-to-Voice Greeting, then forwards the Call to the Call Target. The CallTarget is queried based on input and created as required. UserPrincipalname for Users or ResourceAccount, Group Name for SharedVoicemail, provided as a string in the Variable $UPN This example is equally applicable to AfterHours. .EXAMPLE New-TeamsAutoAttendant -Name "My Auto Attendant" -DefaultCallFlow $DefaultCallFlow -CallFlows $CallFlows -CallHandlingAssociations $CallHandlingAssociations -InclusionScope $InGroups -ExclusionScope $OutGroups Creates a new Auto Attendant "My Auto Attendant" and passes through all objects provided. In this example, provided Objects are passed on through tto New-CsAutoAttendant and override other respective Parmeters provided: A DefaultCallFlow Object is passed on which overrides all "-BusinessHours"-Parmeters. One or more CallFlows and one or more CallHandlingAssociation Objects are passed on overriding all "-AfterHours" and "-HolidaySet" Parameters An InclusionScope and an ExclusionScope are defined. These are passed on as-is All other values, like Language and TimeZone are defined with their defaults and can still be defined with the Objects. .INPUTS System.String .OUTPUTS System.Object .NOTES BusinessHours Parameters aim to simplify input for the Default Call Flow AfterHours Parameters aim to simplify input for the After Hours Call Flow HolidaySet Parameters aim to simplify input for the Holiday Set Call Flow Use of CsAutoAttendant Parameters will override the respective '-BusinessHours', '-AfterHours' and '-HolidaySet' Parameters InclusionScope and ExclusionScope Objects can be created with New-TeamsAutoAttendantDialScope and the Group Names This was deliberately not integrated into this CmdLet .COMPONENT TeamsAutoAttendant .FUNCTIONALITY Creates a Auto Attendant with custom settings and friendly names as input .LINK https://github.com/DEberhardt/TeamsFunctions/tree/master/docs/Update-TeamsAutoAttendantHoliday.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/master/docs/about_TeamsAutoAttendant.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/master/docs/ #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [Alias('Update-TeamsAAHoliday')] [OutputType([System.Void])] param( [Parameter(Mandatory, ValueFromPipeline, HelpMessage = 'Name of the Auto Attendant')] [string]$Name, [Parameter(HelpMessage = 'Holiday Set Greeting - Text String or Recording')] [ArgumentCompleter( { '<Your Text-to-speech-string>', 'C:\Temp\' })] [string]$HolidaySetGreeting, [Parameter(HelpMessage = 'Holiday Set Call Flow - Default options')] [ValidateSet('Disconnect', 'TransferCallToTarget', 'Menu')] [string]$HolidaySetCallFlowOption, [Parameter(HelpMessage = 'Holiday Set Call Target - HolidaySetCallFlowOption = TransferCallToTarget')] [string]$HolidaySetCallTarget, [Parameter(HelpMessage = 'Holiday Set Call Target - HolidaySetCallFlowOption = Menu')] [object]$HolidaySetMenu, #TODO This may need to be mandatory as otherwise useless to apply an empty Holiday Schedule (unless disconnect & Replace) #[Parameter(Mandatory, HelpMessage = 'Default Schedule to apply, can be a 2-digit CountryCode a ScheduleObject or an ID of one')] [Parameter(HelpMessage = 'Default Schedule to apply, can be a 2-digit CountryCode a ScheduleObject or an ID of one')] $HolidaySetSchedule, [Parameter(HelpMessage = 'Replaces all Holiday Flows with the current. If not provided, will add a Flow instead')] [switch]$Replace, [Parameter(HelpMessage = 'Tries to Enable Transcription wherever possible')] [switch]$EnableTranscription, [Parameter(HelpMessage = 'By default, no output is generated, PassThru will display the Object changed')] [switch]$PassThru, [Parameter(HelpMessage = 'Suppresses confirmation prompt to enable Users for Enterprise Voice, if Users are specified')] [switch]$Force ) #param begin { Show-FunctionStatus -Level RC Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand)" Write-Verbose -Message "Need help? Online: $global:TeamsFunctionsHelpURLBase$($MyInvocation.MyCommand)`.md" # Asserting AzureAD Connection if ( -not $script:TFPSSA) { $script:TFPSSA = Assert-AzureADConnection; if ( -not $script:TFPSSA ) { break } } # Asserting MicrosoftTeams Connection if ( -not (Assert-MicrosoftTeamsConnection) ) { break } # Setting Preference Variables according to Upstream settings if (-not $PSBoundParameters.ContainsKey('Verbose')) { $VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference') } if (-not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference') } if (-not $PSBoundParameters.ContainsKey('WhatIf')) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') } if (-not $PSBoundParameters.ContainsKey('Debug')) { $DebugPreference = $PSCmdlet.SessionState.PSVariable.GetValue('DebugPreference') } else { $DebugPreference = 'Continue' } if ( $PSBoundParameters.ContainsKey('InformationAction')) { $InformationPreference = $PSCmdlet.SessionState.PSVariable.GetValue('InformationAction') } else { $InformationPreference = 'Continue' } #Initialising Counters $private:StepsID0, $private:StepsID1 = Get-WriteBetterProgressSteps -Code $($MyInvocation.MyCommand.Definition) -MaxId 1 $private:ActivityID0 = $($MyInvocation.MyCommand.Name) [int] $private:CountID0 = [int] $private:CountID1 = 1 $StatusID0 = 'Verifying input' $CurrentOperationID0 = 'Validating CallFlows' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 #region Processing HolidaySet Parameters if ( $PSBoundParameters.ContainsKey('HolidaySetCallFlowOption') ) { if ($HolidaySetCallFlowOption -eq 'TransferCallToTarget') { # Must contain Target if (-not $PSBoundParameters.ContainsKey('HolidaySetCallTarget')) { Write-Error -Message "HolidaySetCallFlowOption (TransferCallToTarget) - Parameter 'HolidaySetCallTarget' missing" break } # Must not contain a Menu if ($PSBoundParameters.ContainsKey('HolidaySetMenu')) { Write-Verbose -Message 'HolidaySetCallFlowOption (TransferCallToTarget) - Parameter HolidaySetMenu cannot be used and will be omitted!' -Verbose $PSBoundParameters.Remove('HolidaySetMenu') } } elseif ($HolidaySetCallFlowOption -eq 'Menu') { # Must contain a Menu if (-not $PSBoundParameters.ContainsKey('HolidaySetMenu')) { Write-Error -Message 'HolidaySetCallFlowOption (Menu) - HolidaySetMenu missing' break } else { if (($HolidaySetMenu | Get-Member | Select-Object -First 1).TypeName -notmatch 'Microsoft.Rtc.Management.Hosted.OAA.Models.Menu') { Write-Error -Message "HolidaySetCallFlowOption (Menu) - HolidaySetMenu not of the Type 'Microsoft.Rtc.Management.Hosted.OAA.Models.Menu'" -Category InvalidType break } } # Must not contain Target if ($PSBoundParameters.ContainsKey('HolidaySetCallTarget')) { Write-Verbose -Message "HolidaySetCallFlowOption (Menu) - Parameter 'HolidaySetCallTarget' cannot be used and will be omitted!"-Verbose $PSBoundParameters.Remove('HolidaySetCallTarget') } } } #endregion # Preparing Splatting Object for New-TeamsCallableEntity $TeamsCallableEntityParams = @{ 'ErrorAction' = 'Stop' } if ( $PSBoundParameters.ContainsKey('EnableTranscription') ) { $TeamsCallableEntityParams = @{ 'EnableTranscription' = $true } } } #begin process { Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand)" #region PREPARATION $StatusID0 = 'Querying Object' #region Query Unique Element $CurrentOperationID0 = "Finding unique result for provided Name '$Name'" Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ( $Name -match $script:TFMatchGuid ) { #Identity or ObjectId Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - ID - '$Name'" $AAInstance = Get-CsAutoAttendant -Identity "$Name" -WarningAction SilentlyContinue -ErrorAction SilentlyContinue } else { #Name Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand) - Name - '$Name'" # Initial Query to determine unique result (single object) $AAInstance = Get-CsAutoAttendant -NameFilter "$Name" -WarningAction SilentlyContinue $AAInstance = $AAInstance | Where-Object Name -EQ "$Name" } if ($null -eq $AAInstance) { Write-Error "'$Name' No Object found" -Category ParserError -RecommendedAction "Please check 'Name' provided" -ErrorAction Stop } elseif ($AAInstance.GetType().BaseType.Name -eq 'Array') { Write-Error "'$Name' Multiple Results found! Cannot determine unique result." -Category ParserError -RecommendedAction 'Please provide Auto Attendant GUID instead of name' -ErrorAction Stop } else { $AAID = $AAInstance.Identity Write-Information "INFO: '$Name' Auto Attendant found: Identity: $AAID" if ($PSBoundParameters.ContainsKey('Debug') -or $DebugPreference -eq 'Continue') { " Function: $($MyInvocation.MyCommand.Name) - Auto Attendant", ($AAInstance | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } } #endregion # Defining Name for reference below $AAName = "$($AAInstance.Name)" #endregion #region SETTINGS #NOTE All Options in Region Settings use ID 1 for showing progress $ActivityID1 = 'Holiday Call Flow' $StatusID1 = 'Preparing Parameters' # Preparing Call Flow String (to adhere to 64 Character limit) $RandomString = '{0:d4}' -f $(Get-Random -Minimum 0000 -Maximum 9999) if ($AAName.length -gt 40) { Write-Verbose 'Auto Attendant Name is too long and cannot be used for Call Flow Name(s) as-is. Name will be shortened' $CallFlowNamePrefix = -join "$AAName"[0..38] $CallFlowNamePrefix = $CallFlowNamePrefix + $RandomString } else { $CallFlowNamePrefix = "$AAName" } Write-Verbose "Auto Attendant Call Flow Name Prefix used: '$CallFlowNamePrefix'" #region Finding Artefacts $AllCHA = $AAInstance.CallHandlingAssociations $AllCallFlows = $AAInstance.CallFlows if ( $PSBoundParameters.ContainsKey('Replace') ) { Write-Verbose -Message "Parameter 'Replace' - Replacing all existing Call Flows & Call Handling Associations" Write-Warning -Message 'This operation is performed against the InMemory Object' Write-Information 'INFO: This will only be applied to the Auto Attendant if Set-CsAutoAttendant is called at the end!' # Finding All Non-Holiday Call Flows $NonHolidayCHA = $AllCHA | Where-Object Type -NE 'Holiday' $NonHolidayCFs = $AllCallFlows | Where-Object Id -EQ $NonHolidayCHA.CallFlowId if ($PSBoundParameters.ContainsKey('Debug')) { " Function: $($MyInvocation.MyCommand.Name) - CFs before removal:", ($AAInstance.CallFlows | Format-Table -AutoSize | Out-String).Trim() | Write-Debug " Function: $($MyInvocation.MyCommand.Name) - CHA before removal:", ($AAInstance.CallHandlingAssociations | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } if ($PSCmdlet.ShouldProcess("$AAName", 'Remove existing Holiday Call Flows & Call Handling Associations')) { Write-Verbose -Message 'Resetting CFs to only AfterHours CFs' $AAInstance.CallFlows = @($NonHolidayCFs) Write-Verbose -Message 'Resetting CHA to only AfterHours CHA' $AAInstance.CallHandlingAssociations = @($NonHolidayCHA) Write-Information 'INFO: Pending Application: Holiday CallFlow changed: Other Call Flows removed' Write-Information 'INFO: Pending Application: Call Handling Associations changed: Other CHA removed' } } if ($PSBoundParameters.ContainsKey('Debug')) { " Function: $($MyInvocation.MyCommand.Name) - CFs:", ($AAInstance.CallFlows | Format-Table -AutoSize | Out-String).Trim() | Write-Debug " Function: $($MyInvocation.MyCommand.Name) - CHA:", ($AAInstance.CallHandlingAssociations | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } #endregion #region Processing HolidaySetSchedule if ( $PSBoundParameters.ContainsKey('HolidaySetSchedule') ) { if ( $HolidaySetSchedule -match $script:TFMatchGuid ) { # Holiday Schedule provided as ID of existing Schedule in the Tenant - Taken as is. $HolidaySchedule = @{ Id = $HolidaySetSchedule Name = 'Holiday' } } elseif ( $HolidaySetSchedule.Id -match $script:TFMatchGuid) { # Holiday Schedule provided as Schedule Object in the Tenant $HolidaySchedule = $HolidaySetSchedule } elseif ( $HolidaySetSchedule -match '^[a-z][a-z]$') { # Holiday Schedule provided is a Country for which a Schedule Object will be created [int]$CurrentYear = Get-Date -Format yyyy #TEST whether 3 years is a good supply for a standard schedule #$Year = $CurrentYear $Year = @($CurrentYear, $($CurrentYear + 1), $($CurrentYear + 2)) $HolidaySchedule = New-TeamsHolidaySchedule -CountryCode $HolidaySetSchedule -Year $Year } else { Write-Warning -Message 'HolidaySchedule provided does not match an ID, Object or CountryCode! Creating empty Schedule' $HolidaySchedule = $null } } else { Write-Warning -Message 'HolidaySchedule not provided! Creating empty Schedule' $HolidaySchedule = $null } #endregion #region HolidaySet Call Flow if ( $HolidaySchedule ) { if ($PSBoundParameters.ContainsKey('Debug') -or $DebugPreference -eq 'Continue') { " Function: $($MyInvocation.MyCommand.Name) - Holiday Schedules (current)", ($AAInstance.Schedules | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } # Processing HolidaySetsCallFlowOption $CurrentOperationID1 = 'Holiday Call Flow' Write-BetterProgress -Id 1 -Activity $ActivityID1 -Status $StatusID1 -CurrentOperation $CurrentOperationID1 -Step ($private:CountID1++) -Of $private:StepsID1 foreach ( $HolSchedule in $HolidaySchedule ) { # Validating Holiday Schedule Name is not currently used if ( $HolSchedule.Name -in $AAInstance.Schedules.Name ) { $HolSchedule.Name = "$($HolSchedule.Name) $(Get-Date -Format 'dd-MMM-yyyy HH:mm:ss')" Write-Information "INFO: Holiday Schedule Name amended to allow processing (Name must be unique): $($HolSchedule.Name)" } # Initialising Variables for Call Handling Association $HolidaySetCallHandlingAssociationParams = @{} $HolidaySetCallHandlingAssociationParams.Type = 'Holiday' if ($PSBoundParameters.ContainsKey('Debug') -or $DebugPreference -eq 'Continue') { " Function: $($MyInvocation.MyCommand.Name) - Holiday Schedule (to add)", ($HolSchedule | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } $AAInstance.Schedules += $HolSchedule Write-Information 'INFO: Pending Application: Holiday Schedule changed: New Schedule added' $CurrentOperationID1 = 'Holiday Call Flow - Call Flows & Call Flow Option' Write-BetterProgress -Id 1 -Activity $ActivityID1 -Status $StatusID1 -CurrentOperation $CurrentOperationID1 -Step ($private:CountID1) -Of $private:StepsID1 # Option Selected Write-Verbose -Message "'$AAName' CallFlow - No Custom Object - Processing 'HolidaySetCallFlowOption'..." $HolidaySetCallFlowParameters = @{} $HolidaySetCallFlowParameters.Name = "$CallFlowNamePrefix - $($HolSchedule.Name)" #region Processing HolidaySetCallFlowOption switch ($HolidaySetCallFlowOption) { 'TransferCallToTarget' { Write-Verbose -Message "'$AAName' CallFlow - Transferring to Target" # Process HolidaySetCallTarget try { $HolidaySetCallTargetEntity = New-TeamsCallableEntity "$HolidaySetCallTarget"@TeamsCallableEntityParams if ( -not $HolidaySetCallTargetEntity) { throw } # Building Menu Only if Successful $HolidaySetMenuOptionTransfer = New-CsAutoAttendantMenuOption -Action TransferCallToTarget -CallTarget $HolidaySetCallTargetEntity -DtmfResponse Automatic $HolidaySetMenuObject = New-CsAutoAttendantMenu -Name 'Holiday Set Menu' -MenuOptions @($HolidaySetMenuOptionTransfer) Write-Information "INFO: '$AAName' Holiday Set Call Flow - Menu (TransferCallToTarget) created" } catch { Write-Warning -Message 'HolidaySetCallTarget - Error creating Call Target - Defaulting to disconnect' $HolidaySetMenuOptionDefault = New-CsAutoAttendantMenuOption -Action DisconnectCall -DtmfResponse Automatic $HolidaySetMenuObject = New-CsAutoAttendantMenu -Name 'Business Hours Menu' -MenuOptions @($HolidaySetMenuOptionDefault) } } 'Menu' { Write-Verbose -Message "'$AAName' CallFlow - HolidaySetCallFlow - Menu" if ($PSBoundParameters.ContainsKey('HolidaySetMenu')) { # Menu is passed on as-is - $HolidaySetMenu is defined and attached $HolidaySetMenuObject = $HolidaySetMenu Write-Information "INFO: '$AAName' Holiday Set Call Flow - Menu (BusinessHoursMenu) used" } else { # No custom / default Menu is currently created # $HolidaySetMenu is Mandatory. If this is built out, the check against this must also be removed! } } 'Disconnect' { Write-Verbose -Message "'$AAName' CallFlow - HolidaySetCallFlow not provided or Disconnect. Using Disconnect" $HolidaySetMenuOptionDefault = New-CsAutoAttendantMenuOption -Action DisconnectCall -DtmfResponse Automatic $HolidaySetMenuObject = New-CsAutoAttendantMenu -Name 'Holiday Set Menu' -MenuOptions @($HolidaySetMenuOptionDefault) } } #endregion #region HolidaySetGreeting if ($PSBoundParameters.ContainsKey('HolidaySetGreeting')) { $CurrentOperationID1 = 'Holiday Call Flow - Greeting' Write-BetterProgress -Id 1 -Activity $ActivityID1 -Status $StatusID1 -CurrentOperation $CurrentOperationID1 -Step ($private:CountID1) -Of $private:StepsID1 try { $HolidaySetGreetingObject = New-TeamsAutoAttendantPrompt -String "$HolidaySetGreeting" if ($HolidaySetGreetingObject) { $HolidaySetCallFlowParameters.Greetings = @($HolidaySetGreetingObject) Write-Information 'INFO: Pending Application: Holiday CallFlow changed: Greeting' } } catch { Write-Warning -Message "'$AAName' CallFlow - HolidaySetCallFlow - Greeting not enumerated. Omitting Greeting" } } #endregion #region Building Call Flow $CurrentOperationID1 = "Holiday Call Flow - $($HolSchedule.Name) - Building Call Flow" Write-BetterProgress -Id 1 -Activity $ActivityID1 -Status $StatusID1 -CurrentOperation $CurrentOperationID1 -Step ($private:CountID1) -Of $private:StepsID1 # Adding Holiday Set Call Flow $HolidaySetCallFlowParameters.Menu = $HolidaySetMenuObject if ($PSBoundParameters.ContainsKey('Debug') -or $DebugPreference -eq 'Continue') { " Function: $($MyInvocation.MyCommand.Name) - Parameters for HolidaySetCallFlow (New-CsAutoAttendantCallFlow)", ($HolidaySetCallFlowParameters | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } $HolidaySetCallFlow = New-CsAutoAttendantCallFlow @HolidaySetCallFlowParameters Write-Verbose "Auto Attendant '$AAName' Holiday Set Call Flow - Call Flow created" $AAInstance.CallFlows += $HolidaySetCallFlow Write-Information 'INFO: Pending Application: Holiday CallFlow changed: New Holiday Call Flow added' # Adding Call Flow ID(s) to Call handling Associations $HolidaySetCallHandlingAssociationParams.CallFlowId = $HolidaySetCallFlow.Id # Adding singular Flow #endregion #region Holiday Set Schedule & Call Handling Association $CurrentOperationID1 = "Holiday Call Flow - $($HolSchedule.Name) - Call Handling Association" Write-BetterProgress -Id 1 -Activity $ActivityID1 -Status $StatusID1 -CurrentOperation $CurrentOperationID1 -Step ($private:CountID1) -Of $private:StepsID1 $HolidaySetCallHandlingAssociationParams.ScheduleId = $HolSchedule.Id if ($PSBoundParameters.ContainsKey('Debug') -or $DebugPreference -eq 'Continue') { " Function: $($MyInvocation.MyCommand.Name) - Parameter for HolidaySetCallHandlingAssociation (New-CsAutoAttendantCallHandlingAssociation)", ($HolidaySetCallHandlingAssociationParams | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } $HolidaySetCallHandlingAssociation = New-CsAutoAttendantCallHandlingAssociation @HolidaySetCallHandlingAssociationParams Write-Verbose "Auto Attendant '$AAName' Holiday Set Call Flow - Call Handling Association created with Holiday Schedule" $AAInstance.CallHandlingAssociations += $HolidaySetCallHandlingAssociation Write-Information 'INFO: Pending Application: Call Handling Association changed: New Holiday CHA added' #endregion } } else { Write-Warning -Message 'HolidaySchedule not present or not enumerated. No action taken' } #endregion Write-Progress -Id 1 -Activity $ActivityID1 -Completed #endregion #region Preparing Splatting Object $Parameters = $null $Parameters += @{'Instance' = $AAInstance } $Parameters += @{'WarningAction' = if ( $PSBoundParameters.ContainsKey('WarningAction') ) { $PSCmdlet.SessionState.PSVariable.GetValue('WarningAction') } else { 'Continue' } } $Parameters += @{'ErrorAction' = if ( $PSBoundParameters.ContainsKey('ErrorAction') ) { $PSCmdlet.SessionState.PSVariable.GetValue('ErrorAction') } else { 'Stop' } } #endregion #region ACTION Write-Verbose -Message '[PROCESS] Updating Auto Attendant' if ($PSBoundParameters.ContainsKey('Debug') -or $DebugPreference -eq 'Continue') { " Function: $($MyInvocation.MyCommand.Name) - Parameters (Set-CsAutoAttendant)", ($Parameters | Format-Table -AutoSize | Out-String).Trim() | Write-Debug } # Updating Auto Attendant (Set-CsAutoAttendant) $StatusID0 = 'Updating Auto Attendant' $CurrentOperationID0 = "'$AAName'" Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($PSCmdlet.ShouldProcess("$AAName", 'Set-CsAutoAttendant')) { try { # Create the Auto Attendant with all enumerated Parameters passed through splatting $null = (Set-CsAutoAttendant @Parameters) #Write-Information "INFO: All pending changes applied to Auto Attendant Instance for '$AAName'" Write-Host "INFO: All pending changes applied to Auto Attendant Instance for '$AAName'" -ForegroundColor Magenta } catch { Write-Error -Message "Error updating the Auto Attendant: $($_.Exception.Message)" -Category InvalidResult if ( $_.Exception.Message.contains('Auto attendant cannot contain multiple schedules with the same ID or name') ) { Write-Verbose -Message "Schedules cannot be re-used. To do so, please use Export/Import-CsAutoAttendantHolidays or create a new Schedule with a unique name!" -Verbose } if ($PSBoundParameters.ContainsKey('Debug') -or $DebugPreference -eq 'Continue') { Write-Debug -Message 'Detailed output for all aspects of the Call Flow relevant to Holiday Call Flow' Write-Verbose 'Auto Attendant Instance Object' -Verbose $AAInstance Write-Verbose 'Auto Attendant Instance Object - Schedules' -Verbose $AAInstance.Schedules Write-Verbose 'Auto Attendant Instance Object - Call Flows' -Verbose $AAInstance.Callflows Write-Verbose 'Auto Attendant Instance Object - Call Handling Associations' -Verbose $AAinstance.CallHandlingAssociations Write-Debug -Message 'Detailed output for all aspects of the Call Flow relevant to Holiday Call Flow' } return } } else { return } #endregion #region OUTPUT if ( $PassThru ) { $StatusID0 = 'Validation/PassThru' $CurrentOperationID0 = 'Re-Querying Object' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 $AAFinal = Get-TeamsAutoAttendant -Name $AAInstance.Identity -WarningAction SilentlyContinue Write-Output $AAFinal } #endregion Write-Progress -Id 0 -Activity $ActivityID0 -Completed } #process end { Write-Verbose -Message "[END ] $($MyInvocation.MyCommand)" } #end } # Update-TeamsAutoAttendantHoliday |