Public/AutoAttendant/Update-TeamsAutoAttendant.ps1
# Module: TeamsFunctions # Function: AutoAttendant # Author: David Eberhardt # Updated: 03-SEP 2022 # Status: Live #FIX EnableTranscription should be a BOOL and processed! EnableSharedVoicemailSystemPromptSuppression should be BOOL too function Update-TeamsAutoAttendant { <# .SYNOPSIS Changing, amending or replacing the Business Hours 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 Name Name of the Auto Attendant. Required to locate the Auto Attendant. .PARAMETER DisplayName Optional. Updates the Name of the Auto Attendant. Name will be normalised (unsuitable characters are filtered) .PARAMETER TimeZone Optional. TimeZone Identifier based on Get-CsAutoAttendantSupportedTimeZone, but abbreviated for easier input. Warning: Due to multiple time zone names with in the same relative difference to UTC this MAY produce incongruent output The time zone will be correct, but only specifying "UTC+01:00" for example will select the first entry. Default Value: "UTC" .PARAMETER TimeZoneId Optional. TimeZone Id (Name) of the Time Zone as Get-CsAutoAttendantSupportedTimeZone provides. This yields a more precise result as the TimeZone parameter above. If both are provided, TimeZone is ignored as TimeZoneId is an exact result .PARAMETER LanguageId Optional. Language Identifier indicating the language that is used to play text and identify voice prompts. Default Value: "en-US" .PARAMETER Operator Optional. Creates a Callable entity for the Operator Expected are UserPrincipalName (User, ResourceAccount), a TelURI (ExternalPstn), an Office 365 Group Name (SharedVoicemail) .PARAMETER InclusionScope Optional. DialScope Object to pass to Set-CsAutoAttendant Object created with New-TeamsAutoAttendantDialScope or Set-CsAutoAttendantDialScope .PARAMETER ExclusionScope Optional. DialScope Object to pass to Set-CsAutoAttendant Object created with New-TeamsAutoAttendantDialScope or Set-CsAutoAttendantDialScope .PARAMETER EnableVoiceResponse Optional Switch to be passed to Set-CsAutoAttendant .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 EnableSharedVoicemailSystemPromptSuppression Optional. Where possible, tries to suppress System Prompts. Effective only for SharedVoicemail Targets as an Operator or MenuOption. Otherwise has no effect. .PARAMETER ForceListenMenuEnabled Optional. Toggles ForceListenMenuEnabled on Call Flow Objects. Only has an effect for Menus with MenuOptions. .PARAMETER AuthorizedUsers Optional. Users allowed to change certain aspects of the Auto Attendant (like Greetings or AudioFiles) These settings are governed by the assigned CsTeamsVoiceApplicationsPolicy (assigned to the User) .PARAMETER VoiceId Optional. Gender of the Voice for VoiceResponses Instructs the speech interpreter to use a specific gender. Dependent on availability for the selected Language. .PARAMETER PassThru Optional. Displays Auto Attendant Object after action. .EXAMPLE Update-TeamsAutoAttendant -Name "My Auto Attendant" -DisplayName "Main Number" Updates the Auto Attendant "My Auto Attendant" Name to "Main Number" .EXAMPLE Update-TeamsAutoAttendant -Name "My Auto Attendant" -TimeZone UTC-05:00 -LanguageId pt-BR -EnableVoiceResponse Updates the Auto Attendant "My Auto Attendant" and sets the TimeZone to UTC-5 and the language to Portuguese (Brazil) Enables VoiceResponses if available not yet enabled. .EXAMPLE Update-TeamsAutoAttendant -Name "My Auto Attendant" -Operator "tel:+1555123456" Updates the Auto Attendant "My Auto Attendant" with an Operator as a Callable Entity (Forward to Pstn) .EXAMPLE Update-TeamsAutoAttendant -Name "My Auto Attendant" -InclusionScope $InGroups -ExclusionScope $OutGroups Updates the Auto Attendant "My Auto Attendant" and passes through all objects provided. The InclusionScope and ExclusionScope parameters are set with the Scope defined prior. .INPUTS System.String .OUTPUTS System.Object .NOTES 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 Updates an Auto Attendant with custom settings and friendly names as input .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/Update-TeamsAutoAttendant.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/about_TeamsAutoAttendant.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/ #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', PositionalBinding = $false)] [Alias('Update-TeamsAA')] [OutputType([System.Void])] param( [Parameter(Mandatory, Position = 0, ValueFromPipeline, HelpMessage = 'Name of the Auto Attendant')] [string]$Name, [Parameter(HelpMessage = 'Changes the Name to this DisplayName')] [string]$DisplayName, [Parameter(HelpMessage = 'TimeZone Identifier from Get-CsAutoAttendantSupportedTimeZone')] [ValidateScript( { if ($_ -in $(&$global:TfAcSbSupportedTimeZone)) { $True } else { throw [System.Management.Automation.ValidationMetadataException] 'Value must be a supported TimeZone. Use Intellisense for options' } })] [ArgumentCompleter({ &$global:TfAcSbSupportedTimeZone })] [string]$TimeZone, [Parameter(HelpMessage = 'TimeZone Identifier from Get-CsAutoAttendantSupportedTimeZone')] [ValidateScript( { if ("'$_'" -in $(&$global:TfAcSbSupportedTimeZoneName)) { $True } else { throw [System.Management.Automation.ValidationMetadataException] 'Value must be a supported TimeZone. Use Intellisense for options' } })] [ArgumentCompleter({ &$global:TfAcSbSupportedTimeZoneName })] [string]$TimeZoneId, [Parameter(HelpMessage = 'Language Identifier from Get-CsAutoAttendantSupportedLanguage.')] [ValidateScript( { if ($_ -in $(&$global:TfAcSbSupportedLanguage).Id ) { $True } else { throw [System.Management.Automation.ValidationMetadataException] 'Value must be a supported Langauge Id. Use Intellisense for options' } })] [ArgumentCompleter({ $(&$global:TfAcSbSupportedLanguage).Id })] [string]$LanguageId, [Parameter(HelpMessage = 'Target String for the Operator (UPN, Group Name or Tel URI')] [string]$Operator, [Parameter(HelpMessage = 'Groups defining the Inclusion Scope')] [object]$InclusionScope, [Parameter(HelpMessage = 'Groups defining the Exclusion Scope')] [object]$ExclusionScope, [Parameter(HelpMessage = 'Voice Responses')] [boolean]$EnableVoiceResponse, [Parameter(HelpMessage = 'Tries to Enable Transcription wherever possible')] [boolean]$EnableTranscription, [Parameter(HelpMessage = 'Tries to Suppress System Prompts wherever possible')] [boolean]$EnableSharedVoicemailSystemPromptSuppression, [Parameter(HelpMessage = 'Enables ForceListen on CallFlow Objects')] [boolean]$ForceListenMenuEnabled, [Parameter(HelpMessage = 'UPN of one or more Users')] [ValidateScript( { If ($_ -match '@' -or $_ -match $script:TFMatchGuid) { $True } else { throw [System.Management.Automation.ValidationMetadataException] 'Value must be a valid UPN or ObjectId' } })] [string[]]$AuthorizedUsers, [Parameter(HelpMessage = 'Gender of the Voice')] [ValidateSet('Female', 'Male')] [string]$VoiceId, [Parameter(HelpMessage = 'By default, no output is generated, PassThru will display the Object changed')] [switch]$PassThru ) #param begin { Show-FunctionStatus -Level Live 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 # Preparing Splatting Object for New-TeamsCallableEntity $TeamsCallableEntityParams = @{ 'ErrorAction' = 'Stop' } if ( $PSBoundParameters.ContainsKey('EnableTranscription') ) { $TeamsCallableEntityParams += @{ EnableTranscription = $EnableTranscription } } if ( $PSBoundParameters.ContainsKey('EnableSharedVoicemailSystemPromptSuppression') ) { $TeamsCallableEntityParams += @{ EnableSharedVoicemailSystemPromptSuppression = $EnableSharedVoicemailSystemPromptSuppression } } } #begin process { Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand)" #region PREPARATION $ActivityID0 = 'Validation' $StatusID0 = 'Querying Object' # preparing Splatting Object $Parameters = $null #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 #region DisplayName $CurrentOperationID0 = 'DisplayName' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 # Normalising $DisplayName if ( $PSBoundParameters.ContainsKey('DisplayName') ) { $NameNormalised = Format-StringForUse -InputString "$DisplayName" -As DisplayName $AAInstance.Name = "$NameNormalised" Write-Information "INFO: Pending Application: DisplayName changed from '$Name' to '$NameNormalised'" Write-Warning -Message 'Future Calls to this Auto Attendant must be against this name (or using the Identity)' } #endregion # Defining Name for reference below $AAName = "$($AAInstance.Name)" #endregion #region SETTINGS #NOTE All Options in Region Settings use ID 0 for showing progress #region TimeZone $CurrentOperationID0 = 'Processing TimeZone' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ( $PSBoundParameters.ContainsKey('TimeZone') -or $PSBoundParameters.ContainsKey('TimeZoneId') ) { if ( $PSBoundParameters.ContainsKey('TimeZone') -and $PSBoundParameters.ContainsKey('TimeZoneId') ) { Write-Information "INFO: TimeZone and TimeZoneId are both provided. TimeZone is ignored: TimeZoneId '$TimeZoneId' is used as it is more precise" [void]$PSBoundParameters.Remove('TimeZone') } if ( $PSBoundParameters.ContainsKey('TimeZone') ) { Write-Verbose -Message "TimeZone - Parsing TimeZone '$TimeZone'" if ($TimeZone -eq 'UTC') { $TimeZoneId = $TimeZone } else { # Query of Supported TimeZones based on previously calculated global Variable if ( -not $global:CsAutoAttendantSupportedTimeZone ) { $global:CsAutoAttendantSupportedTimeZone = Get-CsAutoAttendantSupportedTimeZone -WarningAction SilentlyContinue } $TimeZoneId = ($global:CsAutoAttendantSupportedTimeZone | Where-Object DisplayName -Like "($TimeZone)*" | Select-Object -First 1).Id Write-Verbose -Message "TimeZone '$TimeZone' - Using: '$TimeZoneId' - This is a correct match for the value of the Time Zone, but might not be exact. - Please fine-tune Time Zone in the Admin Center if needed or provide TimeZoneId parameter" -Verbose } } # Applying TimeZoneId if ( $TimeZoneId ) { $AAInstance.TimeZoneId = $TimeZoneId Write-Information "INFO: Pending Application: TimeZone set to: '$TimeZoneId'" } else { Write-Warning -Message 'TimeZone - Error determining TimeZoneId - skipped' } } #endregion #region Langauge $CurrentOperationID0 = 'Processing Language' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ( $PSBoundParameters.ContainsKey('Language') ) { # Language has to be normalised as the Id is case sensitive. Default value: en-US $Language = $($LanguageId.Split('-')[0]).ToLower() + '-' + $($LanguageId.Split('-')[1]).ToUpper() Write-Verbose "LanguageId '$LanguageId' normalised to '$Language'" $AAInstance.LanguageId = $Language Write-Information "INFO: Pending Application: Language set to: '$Language'" } else { $Language = $AAInstance.LanguageId } #endregion #region Voice capabilities # Query of Supported Languages based on previously calculated global Variable if ( -not $global:CsAutoAttendantSupportedLanguage ) { $global:CsAutoAttendantSupportedLanguage = Get-CsAutoAttendantSupportedLanguage -WarningAction SilentlyContinue } $LanguageRecord = $global:CsAutoAttendantSupportedLanguage | Where-Object Id -EQ "$Language" $CurrentOperationID0 = 'Processing EnableVoiceResponse, VoiceId' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($PSBoundParameters.ContainsKey('EnableVoiceResponse') -and $EnableVoiceResponse ) { $VoiceResponsesSupported = $LanguageRecord.VoiceResponseSupported # EnableVoiceResponse if ( $VoiceResponsesSupported ) { Write-Verbose -Message "'$AAName' EnableVoiceResponse - Voice Responses are supported with Language '$Language' and EnableVoiceResponse will be set to: $EnableVoiceResponse" $AAInstance.VoiceResponseEnabled = $EnableVoiceResponse Write-Information "INFO: Pending Application: VoiceResponseEnabled set to: '$EnableVoiceResponse'" } else { Write-Warning -Message "'$AAName' EnableVoiceResponse - Voice Responses are not supported for Language '$Language' and cannot be activated (Switch 'EnableVoiceResponse' will be omitted)" } } # VoiceId if ( $PSBoundParameters.ContainsKey('VoiceId') ) { $Voices = ($LanguageRecord.Voices | Where-Object Id -EQ "$VoiceId") if ( $Voices.Count -gt 0 ) { Write-Verbose -Message "'$AAName' VoiceId - Voice with gender '$VoiceId' found for '$Language'" -Verbose $AAInstance.VoiceId = $Voices[0] Write-Information "INFO: Pending Application: VoiceId set to: '$($Voices[0].Name)' (NOTE: This is experimental in v4.7.0)" } else { Write-Verbose -Message "'$AAName' VoiceId - No Voice with this gender found for '$Language' (using default Voice)" -Verbose } } #endregion #region Operator $CurrentOperationID0 = 'Operator' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($PSBoundParameters.ContainsKey('Operator')) { try { $OperatorEntity = New-TeamsCallableEntity -Identity "$Operator" @TeamsCallableEntityParams if ($OperatorEntity) { $AAInstance.Operator = $OperatorEntity Write-Information "INFO: Pending Application: Operator set to: '$Operator'" } } catch { Write-Warning -Message 'Operator - Error creating Call Target - skipped' } } #endregion #region Inclusion and Exclusion Scope $CurrentOperationID0 = 'Dial Scopes - Inclusion & Exclusion Scope' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 # Inclusion Scope if ($PSBoundParameters.ContainsKey('InclusionScope')) { Write-Verbose -Message "'$AAName' InclusionScope provided. Using as-is" $AAInstance.DirectoryLookupScope.InclusionScope = $InclusionScope Write-Information "INFO: Pending Application: InclusionScope set to Type: '$($InclusionScope.Type)'" } else { #Scope is optional Write-Verbose -Message "'$AAName' InclusionScope not defined. To create one, please run New-TeamsAutoAttendantDialScope or New-CsAutoAttendantDialScope" } # Exclusion Scope if ($PSBoundParameters.ContainsKey('ExclusionScope')) { Write-Verbose -Message "'$AAName' ExclusionScope provided. Using as-is" $AAInstance.DirectoryLookupScope.ExclusionScope = $ExclusionScope Write-Information "INFO: Pending Application: ExclusionScope set to Type: '$($ExclusionScope.Type)'" } else { #Scope is optional Write-Verbose -Message "'$AAName' ExclusionScope not defined. To create one, please run New-TeamsAutoAttendantDialScope or New-CsAutoAttendantDialScope" } #endregion #region AuthorizedUsers - Parsing and verifying AuthorizedUsers $CurrentOperationID0 = 'Parsing AuthorizedUsers' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($PSBoundParameters.ContainsKey('AuthorizedUsers')) { Write-Verbose -Message "'$AAName' - Parsing AuthorizedUsers" [System.Collections.Generic.List[object]]$AuthorizedUserIdList = @() foreach ($User in $AuthorizedUsers) { $Assertion = $null $CallTarget = $null $CallTarget = Get-TeamsCallableEntity -Identity "$User" if ( $CallTarget.ObjectType -ne 'User') { Write-Warning -Message "'$AAName' Object '$User' is not a User, omitting Object!" continue } try { # Asserting Object - Validation of Type $Assertion = Assert-TeamsCallableEntity -UserPrincipalName "$($CallTarget.Entity)" -RequireEV -WarningAction SilentlyContinue -ErrorAction Stop if ( $Assertion ) { Write-Information "INFO: User '$User' will be added as an Authorized User" [void]$AuthorizedUserIdList.Add($CallTarget.Identity) } else { Write-Warning -Message "'$AAName' Object '$User' not found or in unusable state, omitting Object!" continue } } catch { Write-Warning -Message "'$AAName' Object '$User' not in correct state or not enabled for Enterprise Voice, omitting Object!" Write-Debug "Exception: $($_.Exception.Message)" continue } } if ($AuthorizedUserIdList.Count -gt 0 -and $AuthorizedUserIdList -ne '') { # If Object is an Empty String, Count will be 1 Write-Verbose -Message "'$AAName' AuthorizedUsers: Adding $($AuthorizedUserIdList.Count) Users as Managers to the Auto Attendant" -Verbose #TEST AuthorizedUsers may suffer from 'single object trauma' #$Parameters += @{'AuthorizedUsers' = if ( $AuthorizedUserIdList.Count -eq 1 ) { "$AuthorizedUserIdList" } else { @($AuthorizedUserIdList) } } $AAInstance.AuthorizedUsers = $AuthorizedUserIdList Write-Information "INFO: Pending Application: AuthorizedUsers changed: $($AuthorizedUserIdList.Count) Users set" } } #endregion #region Switches $CurrentOperationID0 = 'Processing Switches (ForceListen, Transcription, Skip System Message)' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 # ForceListenMenuEnabled if ( $PSBoundParameters.ContainsKey('ForceListenMenuEnabled') ) { $AAInstance.DefaultCallFlow.ForceListenMenuEnabled = $ForceListenMenuEnabled Write-Information "INFO: Pending Application: Default CallFlow changed: ForceListenMenuEnabled set to: $ForceListenMenuEnabled" $AAInstance.CallFlows | ForEach-Object { $_.ForceListenMenuEnabled = $ForceListenMenuEnabled Write-Information "INFO: Pending Application: CallFlow '$($_.Name)' changed: ForceListenMenuEnabled set to: $ForceListenMenuEnabled" } } # Shared Voicemail Transcription & Skip System Prompt $AAInstance.DefaultCallFlow.Menu.MenuOptions | ForEach-Object { if ($_.CallTarget.Type -eq 'SharedVoicemail') { $SharedVoiceMailCallTarget = $_.Calltarget.Id | Get-TeamsCallableEntity # EnableTranscription if ( $PSBoundParameters.ContainsKey('EnableTranscription') ) { $_.CallTarget.EnableTranscription = $EnableTranscription Write-Information "INFO: Pending Application: DefaultCallFlow changed: Transcription set for MenuOption $($_.DtmfResponse -replace 'Tone', ''): '$($SharedVoiceMailCallTarget.Entity)' ($EnableTranscription)" } # EnableSharedVoicemailSystemPromptSuppression if ( $PSBoundParameters.ContainsKey('EnableSharedVoicemailSystemPromptSuppression') ) { $_.CallTarget.EnableSharedVoicemailSystemPromptSuppression = $EnableSharedVoicemailSystemPromptSuppression Write-Information "INFO: Pending Application: DefaultCallFlow changed: SkipSystemMessage set for MenuOption $($_.DtmfResponse -replace 'Tone', ''): '$($SharedVoiceMailCallTarget.Entity)' ($EnableSharedVoicemailSystemPromptSuppression)" } } } $AAInstance.Callflows.Menu.MenuOptions | ForEach-Object { if ($_.CallTarget.Type -eq 'SharedVoicemail') { $SharedVoiceMailCallTarget = $_.Calltarget.Id | Get-TeamsCallableEntity # EnableTranscription $_.CallTarget.EnableTranscription = $EnableTranscription Write-Information "INFO: Pending Application: CallFlow changed: Transcription set for MenuOption $($_.DtmfResponse -replace 'Tone', ''): '$($SharedVoiceMailCallTarget.Entity)' ($EnableTranscription)" # EnableSharedVoicemailSystemPromptSuppression $_.CallTarget.EnableSharedVoicemailSystemPromptSuppression = $EnableSharedVoicemailSystemPromptSuppression Write-Information "INFO: Pending Application: CallFlow changed: SkipSystemMessage set for MenuOption $($_.DtmfResponse -replace 'Tone', ''): '$($SharedVoiceMailCallTarget.Entity)' ($EnableSharedVoicemailSystemPromptSuppression)" } } #endregion #endregion #region ACTION #Preparing Splatting Object $Parameters = @{ 'Instance' = $AAInstance 'WarningAction' = if ( $PSBoundParameters.ContainsKey('WarningAction') ) { $PSCmdlet.SessionState.PSVariable.GetValue('WarningAction') } else { 'Continue' } 'ErrorAction' = if ( $PSBoundParameters.ContainsKey('ErrorAction') ) { $PSCmdlet.SessionState.PSVariable.GetValue('ErrorAction') } else { 'Stop' } } 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 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-TeamsAutoAttendant |