Public/AutoAttendant/Get-TeamsAutoAttendant.ps1
# Module: TeamsFunctions # Function: AutoAttendant # Author: David Eberhardt # Updated: 01-MAR-2022 # Status: Live #IMPROVE Unknown what DialByNameResourceId is or does (GUID, denoting what object exactly? - how to test/query/translate?) #TEST Output to be identical for Schedules,CallFlows,DefaultCallFlow, etc. like Get-CsAutoAttendant - only with -Detailed does it do this currently! function Get-TeamsAutoAttendant { <# .SYNOPSIS Queries Auto Attendants and displays friendly Names (UPN or DisplayName) .DESCRIPTION Same functionality as Get-CsAutoAttendant, but display reveals friendly Names, like UserPrincipalName or DisplayName for the following connected Objects Operator and ApplicationInstances (Resource Accounts) .PARAMETER Name Required for ParameterSet Name. Finds all Auto Attendants with this name (unique results). If not provided, all Auto Attendants are queried, returning only the name .PARAMETER SearchString Required for ParameterSet Search. Searches all Auto Attendants for this string (multiple results possible). .PARAMETER Detailed Optional Switch. Displays nested Objects for all Parameters of the Auto Attendant By default, only Names of nested Objects are shown. .EXAMPLE Get-TeamsAutoAttendant Same result as Get-CsAutoAttendant .EXAMPLE Get-TeamsAutoAttendant -Name "My AutoAttendant" Returns an Object for every Auto Attendant found with the exact Name "My AutoAttendant" .EXAMPLE Get-TeamsAutoAttendant -Name "My AutoAttendant" -Detailed Returns an Object for every Auto Attendant found with the exact Name "My AutoAttendant" Detailed view will display all nested Objects indented as a tree .EXAMPLE Get-TeamsAutoAttendant -Name "My AutoAttendant" -SearchString "My AutoAttendant" Returns an Object for every Auto Attendant found with the exact Name "My AutoAttendant" and Returns an Object for every Auto Attendant matching the String "My AutoAttendant" .EXAMPLE Get-TeamsAutoAttendant -SearchString "My AutoAttendant" Returns an Object for every Auto Attendant matching the String "My AutoAttendant" Synonymous with Get-CsAutoAttendant -NameFilter "My AutoAttendant", but output shown differently. .INPUTS System.String .OUTPUTS System.Object .NOTES Without any parameters, Get-TeamsAutoAttendant will show names only. Operator and Resource Accounts, etc. are displayed with friendly name. Main difference to Get-CsAutoAttendant (apart from the friendly names) is how the Objects are shown. The connected Objects DefaultCallFlow, CallFlows, Schedules, CallHandlingAssociations and DirectoryLookups are all shown with Name only, but can be queried with .<ObjectName> This also works with Get-CsAutoAttendant, but with the help of "Display" Parameters. .COMPONENT TeamsAutoAttendant .FUNCTIONALITY Get-CsAutoAttendant with friendly names instead of GUID-strings for connected objects .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/Get-TeamsAutoAttendant.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/about_TeamsAutoAttendant.md .LINK https://github.com/DEberhardt/TeamsFunctions/tree/main/docs/ #> [CmdletBinding(SupportsPaging, DefaultParameterSetName = 'Name')] [Alias('Get-TeamsAA')] [OutputType([System.Object[]])] param( [Parameter(ParameterSetName = 'Name', Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName, HelpMessage = 'Full Name of the Auto Attendant')] [AllowNull()] [Alias('Identity')] [string[]]$Name, [Parameter(ParameterSetName = 'Search', HelpMessage = 'Partial or full Name of the Auto Attendant to search')] [Alias('NameFilter')] [string]$SearchString, [Parameter()] [switch]$Detailed ) #param begin { Show-FunctionStatus -Level Live Write-Verbose -Message "[BEGIN ] $($MyInvocation.MyCommand.Name)" Write-Verbose -Message "Need help? Online: $global:TeamsFunctionsHelpURLBase$($MyInvocation.MyCommand.Name)`.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 #Initialising splatting Object $GetCsAutoAttendantParameters = @{ WarningAction = 'SilentlyContinue' ErrorAction = 'Continue' } if ( $PSBoundParameters.ContainsKey('First') ) { $GetCsAutoAttendantParameters.First = $PSCmdlet.PagingParameters.First } if ( $PSBoundParameters.ContainsKey('Skip') ) { $GetCsAutoAttendantParameters.Skip = $PSCmdlet.PagingParameters.Skip } if ( $PSBoundParameters.ContainsKey('IncludeTotalCount') ) { $GetCsAutoAttendantParameters.IncludeTotalCount = $PSCmdlet.PagingParameters.IncludeTotalCount } if ($PSBoundParameters.ContainsKey('Detailed')) { Write-Verbose -Message "Parameter 'Detailed' - This may take a bit of time..." -Verbose } $previousFEL = $global:FormatEnumerationLimit $global:FormatEnumerationLimit = 20 #Worker Function function GetAutoAttendants { [CmdletBinding()] [OutputType([System.Object])] param( [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName, HelpMessage = 'Auto Attendant object')] [AllowNull()] [object]$AA, [Parameter()] [bool]$Detailed ) #param begin { } process { # Initialising counters for Progress bars [int] $private:CountID0 = 1 $ActivityID0 = "'$($AA.Name)'" # Initialising Arrays [System.Collections.Generic.List[object]]$AIObjects = @() [System.Collections.Generic.List[object]]$AuthorizedUserObjects = @() $StatusID0 = 'Parsing' #region Finding Operator $CurrentOperationID0 = 'Operator' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($null -eq $AA.Operator) { $AAOperator = $null } else { # Parsing Callable Entity try { $CallableEntity = Get-TeamsCallableEntity "$($AA.Operator.Id)" -WarningAction SilentlyContinue $Operator = $CallableEntity.Entity } catch { Write-Warning -Message "$ActivityID0 $StatusID0 $CurrentOperationID0`: Not enumerated: $($_.Exception.Message)" } } # Output: $Operator, $OperatorTranscription #endregion #region Application Instance UPNs $CurrentOperationID0 = 'Application Instances' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 foreach ($AI in $AA.ApplicationInstances) { $AIObject = $null $AIObject = Get-CsOnlineApplicationInstance -WarningAction SilentlyContinue | Where-Object { $_.ObjectId -eq $AI } | Select-Object UserPrincipalName, DisplayName, PhoneNumber if ($null -ne $AIObject) { [void]$AIObjects.Add($AIObject) } } # Output: $AIObjects.UserPrincipalName #endregion #region Inclusion & Exclusion Scope Groups $CurrentOperationID0 = 'Inclusion Scope Groups' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($AA.DirectoryLookupScope.InclusionScope) { [System.Collections.Generic.List[object]]$InclusionScopeDistributionLists = @() foreach ($DL in $AA.DirectoryLookupScope.InclusionScope.GroupScope.GroupIds) { #$DLObject = Get-UniqueAzureADGroup "$DL" -WarningAction SilentlyContinue -ErrorAction SilentlyContinue $DLObject = $null $DLObject = Get-AzureADGroup -ObjectId "$DL" -WarningAction SilentlyContinue if ($DLObject) { [void]$InclusionScopeDistributionLists.Add($DLObject.DisplayName) } } } $CurrentOperationID0 = 'Exclusion Scope Groups' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($AA.DirectoryLookupScope.ExclusionScope) { [System.Collections.Generic.List[object]]$ExclusionScopeDistributionLists = @() foreach ($DL in $AA.DirectoryLookupScope.ExclusionScope.GroupScope.GroupIds) { #$DLObject = Get-UniqueAzureADGroup "$DL" -WarningAction SilentlyContinue -ErrorAction SilentlyContinue $DLObject = $null $DLObject = Get-AzureADGroup -ObjectId "$DL" -WarningAction SilentlyContinue if ($DLObject) { [void]$ExclusionScopeDistributionLists.Add($DLObject.DisplayName) } } } # Output: $InclusionScopeDistributionLists, $ExclusionScopeDistributionLists #endregion #region Authorized Users $CurrentOperationID0 = 'Authorized Users' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 foreach ($User in $AA.AuthorizedUsers) { $UserObject = $null try { $UserObject = Get-AzureADUser -ObjectId "$($User.Guid)" -WarningAction SilentlyContinue -ErrorAction Stop | Select-Object UserPrincipalName, DisplayName, JobTitle, CompanyName, Country, UsageLocation, PreferredLanguage [void]$AuthorizedUserObjects.Add($UserObject) } catch { [string]$Message = $_ | Get-ErrorMessageFromErrorString Write-Warning -Message "'$($AA.Name)' - $Operation`: GetUser$($Message.Split(':')[1])" } } # Output: $AIObjects.UserPrincipalName #endregion #region Finding Artefacts $AfterHoursCHA = $AA.CallHandlingAssociations | Where-Object Type -EQ 'AfterHours' $AfterHoursScheduleId = $AfterHoursCHA.ScheduleId $AfterHoursCallFlowId = $AfterHoursCHA.CallFlowId $AfterHoursScheduleObject = $AA.Schedules | Where-Object Id -EQ $AfterHoursScheduleId $AfterHoursCallFlow = $AA.CallFlows | Where-Object Id -EQ $AfterHoursCallFlowId $HolidayCHA = $AA.CallHandlingAssociations | Where-Object Type -EQ 'Holiday' $HolidayScheduleId = $HolidayCHA.ScheduleId $HolidayCallFlowId = $HolidayCHA.CallFlowId $HolidayScheduleObject = $AA.Schedules | Where-Object Id -EQ $HolidayScheduleId $HolidayCallFlow = $AA.CallFlows | Where-Object Id -EQ $HolidayCallFlowId #endregion #region Creating Output Object # Building custom Object with Friendly Names $StatusID0 = 'Processing' $CurrentOperationID0 = 'Constructing Output Object' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 $AAObject = $null $AAObject = [PsCustomObject][ordered]@{ PSTypeName = 'PowerShell.TeamsFunctsions.AutoAttendant' Identity = $AA.Identity Name = $AA.Name LanguageId = $AA.LanguageId TimeZoneId = $AA.TimeZoneId VoiceId = $AA.VoiceId VoiceResponseEnabled = $AA.VoiceResponseEnabled OperatorName = $Operator OperatorType = $AA.Operator.Type Operator = $null DefaultCallFlowName = $AA.DefaultCallFlow.Name AfterHoursCallFlow = $AfterHoursCallFlow HolidayCallFlow = $HolidayCallFlow AfterHoursSchedule = $AfterHoursScheduleObject HolidaySchedule = $HolidayScheduleObject DefaultCallFlow = $null CallFlows = $null Schedules = $null CallHandlingAssociations = $null DialByNameResourceId = $AA.DialByNameResourceId DirectoryLookupScope = $AA.DirectoryLookupScope.Name InclusionScopeDistributionLists = $InclusionScopeDistributionLists ExclusionScopeDistributionLists = $ExclusionScopeDistributionLists AuthorizedUsers = $($AuthorizedUserObjects.UserPrincipalName -join ', ') } $AAObject.AfterHoursCallFlow | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force $AAObject.HolidayCallFlow | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force $AAObject.AfterHoursSchedule | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force $AAObject.HolidaySchedule | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force #endregion #region Extending Output Object with Switch Detailed if ( $Detailed ) { $StatusID0 = 'Switch Detailed (Nested Objects)' #region Operator $CurrentOperationID0 = 'Operator' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 if ($AA.Operator) { $AAOperator = @() $AAOperator = [PsCustomObject][ordered]@{ PSTypeName = 'PowerShell.TeamsFunctsions.AutoAttendant.Operator' 'Entity' = $Operator 'Type' = $AA.Operator.Type 'EnableTranscription' = $AA.Operator.EnableTranscription 'Id' = $AA.Operator.Id } Add-Member -Force -InputObject $AAOperator -MemberType ScriptMethod -Name ToString -Value { [System.Environment]::NewLine + (($this | Format-List * | Out-String) -replace '^\s+|\s+$') } } else { $AAOperator = $null } #endregion #region DefaultCallFlow $CurrentOperationID0 = 'DefaultCallFlow' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: Prompts" #Write-Debug -Message "'$($AA.Name)' - $Operation - Prompts" if ( $AA.DefaultCallFlow.Menu.Prompts ) { $AADefaultCallFlowMenuPrompts = Merge-AutoAttendantArtefact -Type Prompt -Object $AA.DefaultCallFlow.Menu.Prompts } else { $AADefaultCallFlowMenuPrompts = '' } # Default Call Flow Menu Options Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: MenuOptions" #Write-Debug -Message "'$($AA.Name)' - $Operation - MenuOptions" if ( $AA.DefaultCallFlow.Menu.MenuOptions ) { [System.Collections.Generic.List[object]]$AADefaultCallFlowMenuOptions = @() foreach ( $MenuOption in $AA.DefaultCallFlow.Menu.MenuOptions ) { try { if ( $MenuOption.Prompt ) { # Announcements: Processing Call Flow Prompts Write-Debug -Message "'$($AA.Name)' - $Operation - MenuOptions - Prompt" $MenuOptionPrompt = $null $MenuOptionPrompt = Merge-AutoAttendantArtefact -Type Prompt -Object $MenuOption.Prompt Write-Debug -Message "'$($AA.Name)' - $Operation - MenuOptions - MenuOptions" $MenuOptionsObject = Merge-AutoAttendantArtefact -Type MenuOption -Object $MenuOption -Prompts $MenuOptionPrompt } else { throw } } catch { Write-Debug -Message "'$($AA.Name)' - $Operation - MenuOptions - MenuOptions w/o prompt" $MenuOptionsObject = Merge-AutoAttendantArtefact -Type MenuOption -Object $MenuOption } $AADefaultCallFlowMenuOptions.Add($MenuOptionsObject) } } else { $AADefaultCallFlowMenuOptions = '' } # Default Call Flow Menu Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: Menu" #Write-Debug -Message "'$($AA.Name)' - $Operation - Menu" $AADefaultCallFlowMenu = Merge-AutoAttendantArtefact -Type Menu -Object $AA.DefaultCallFlow.Menu -Prompts $AADefaultCallFlowMenuPrompts -MenuOptions $AADefaultCallFlowMenuOptions # Default Call Flow Greetings if ($AA.DefaultCallFlow.Greetings) { $AADefaultCallFlowGreetings = Merge-AutoAttendantArtefact -Type Prompt -Object $AA.DefaultCallFlow.Greetings } else { $AADefaultCallFlowGreetings = '' } # Default Call Flow Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: Call Flow" #Write-Debug -Message "'$($AA.Name)' - $Operation - Call Flow" $AADefaultCallFlow = Merge-AutoAttendantArtefact -Type CallFlow -Object $AA.DefaultCallFlow -Prompts $AADefaultCallFlowGreetings -Menu $AADefaultCallFlowMenu #endregion #region CallFlows $CurrentOperationID0 = 'CallFlows' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 $AACallFlows = @() foreach ($Flow in $AA.CallFlows) { # Call Flow Prompts $AACallFlowMenuPrompts = $null Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - Prompts" #Write-Debug -Message "'$($AA.Name)' - $Operation - $($Flow.Name) - Prompts" if ($Flow.Menu.Prompts) { $AACallFlowMenuPrompts = Merge-AutoAttendantArtefact -Type Prompt -Object $Flow.Menu.Prompts } else { $AACallFlowMenuPrompts = '' } # Call Flow Menu Options $AACallFlowMenuOptions = $null Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - MenuOptions" #Write-Debug -Message "'$($AA.Name)' - $Operation - $($Flow.Name) - MenuOptions" if ($Flow.Menu.MenuOptions) { [System.Collections.Generic.List[object]]$AACallFlowMenuOptions = @() foreach ( $MenuOption in $Flow.Menu.MenuOptions ) { try { if ( $MenuOption.Prompt ) { # Announcements: Processing Call Flow Prompts Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - MenuOptions - Prompt" $MenuOptionPrompt = $null $MenuOptionPrompt = Merge-AutoAttendantArtefact -Type Prompt -Object $MenuOption.Prompt Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - MenuOptions - MenuOptions" $MenuOptionsObject = Merge-AutoAttendantArtefact -Type MenuOption -Object $MenuOption -Prompts $MenuOptionPrompt } else { throw } } catch { Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - MenuOptions - MenuOptions w/o prompt" $MenuOptionsObject = Merge-AutoAttendantArtefact -Type MenuOption -Object $MenuOption } $AACallFlowMenuOptions.Add($MenuOptionsObject) } } else { $AACallFlowMenuOptions = '' } # Call Flow Menu Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - Menu" #Write-Debug -Message "'$($AA.Name)' - $Operation - $($Flow.Name) - Menu" $AACallFlowMenu = $null $AACallFlowMenu = Merge-AutoAttendantArtefact -Type Menu -Object $Flow.Menu -Prompts $AACallFlowMenuPrompts -MenuOptions $AACallFlowMenuOptions # Call Flow Greetings $AACallFlowGreetings = $null Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - Greetings" #Write-Debug -Message "'$($AA.Name)' - $Operation - $($Flow.Name) - Greetings" if ($Flow.Greetings) { $AACallFlowGreetings = Merge-AutoAttendantArtefact -Type Prompt -Object $Flow.Greetings } else { $AACallFlowGreetings = '' } # Call Flow Write-Debug -Message "$ActivityID0 - $StatusID0 - $CurrentOperationID0`: '$($Flow.Name)' - Call Flow" #Write-Debug -Message "'$($AA.Name)' - $Operation - $($Flow.Name) - Call Flow" $AACallFlows += Merge-AutoAttendantArtefact -Type CallFlow -Object $Flow -Prompts $AACallFlowGreetings -Menu $AACallFlowMenu } #endregion #region Schedules $CurrentOperationID0 = 'Schedules' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 $AASchedules = @() foreach ($Schedule in $AA.Schedules) { $AASchedule = Get-CsOnlineSchedule -Id $Schedule.Id $AASchedules += Merge-AutoAttendantArtefact -Type Schedule -Object $AASchedule } #endregion #region CallHandlingAssociations $CurrentOperationID0 = 'CallHandlingAssociations' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 $AACallHandlingAssociations = @() foreach ($item in $AA.CallHandlingAssociations) { # Determine Call Flow Name $AACallHandlingAssociationCallFlowName = ($AA.CallFlows | Where-Object Id -EQ $item.CallFlowId).Name # CallHandlingAssociations $AACallHandlingAssociations += Merge-AutoAttendantArtefact -Type CallHandlingAssociation -Object $item -CallFlowName $AACallHandlingAssociationCallFlowName } #endregion # Adding nested Objects $AAObject.Operator = $AAOperator $AAObject.DefaultCallFlow = $AADefaultCallFlow $AAObject.CallFlows = $AACallFlows $AAObject.Schedules = $AASchedules $AAObject.CallHandlingAssociations = $AACallHandlingAssociations <# # Adding nested Objects $AAObject | Add-Member -MemberType NoteProperty -Name Operator -Value $AAOperator $AAObject | Add-Member -MemberType NoteProperty -Name DefaultCallFlow -Value $AADefaultCallFlow $AAObject | Add-Member -MemberType NoteProperty -Name CallFlows -Value $AACallFlows $AAObject | Add-Member -MemberType NoteProperty -Name Schedules -Value $AASchedules $AAObject | Add-Member -MemberType NoteProperty -Name CallHandlingAssociations -Value $AACallHandlingAssociations #> } else { # Adding nested Objects $AAObject.Operator = $AA.Operator $AAObject.DefaultCallFlow = $AA.DefaultCallFlow $AAObject.CallFlows = $AA.CallFlows $AAObject.Schedules = $AA.Schedules $AAObject.CallHandlingAssociations = $AA.CallHandlingAssociations $AAObject.CallFlows | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force $AAObject.Schedules | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force $AAObject.CallHandlingAssociations | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Name } -Force <# # Adding Objects as is to allow drill-down $AAObject | Add-Member -MemberType NoteProperty -Name Operator -Value $AA.Operator $AAObject | Add-Member -MemberType NoteProperty -Name DefaultCallFlow -Value $AA.DefaultCallFlow $AAObject | Add-Member -MemberType NoteProperty -Name CallFlows -Value $AA.CallFlows $AAObject | Add-Member -MemberType NoteProperty -Name Schedules -Value $AA.Schedules $AAObject | Add-Member -MemberType NoteProperty -Name CallHandlingAssociations -Value $AA.CallHandlingAssociations #> } # Adding Resource Accounts $AAObject | Add-Member -MemberType NoteProperty -Name ApplicationInstances -Value $AIObjects.UserPrincipalName #endregion # Output Write-Progress -Id 1 -Activity $ActivityID0 -Completed Write-Progress -Id 0 -Activity $ActivityID0 -Completed Write-Output $AAObject } end { } } } #begin process { Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand)" [int] $private:CountID0 = [int] $private:CountID1 = 1 $StatusID0 = 'Information Gathering' #region Data gathering $CurrentOperationID0 = 'Querying Auto Attendants' Write-BetterProgress -Id 0 -Activity $ActivityID0 -Status $StatusID0 -CurrentOperation $CurrentOperationID0 -Step ($private:CountID0++) -Of $private:StepsID0 # Capturing no input if (-not $PSBoundParameters.ContainsKey('Name') -and -not $PSBoundParameters.ContainsKey('SearchString') ) { Write-Information 'INFO: No Parameters - Listing names only. To query individual items, please provide Parameter Name or SearchString' Get-CsAutoAttendant @GetCsAutoAttendantParameters | Select-Object Name return } else { $AutoAttendants = @() switch ($PSCmdlet.ParameterSetName) { 'Name' { # Lookup Write-Verbose -Message "Parameter 'Name' - Querying unique result for each provided Name" foreach ($DN in $Name) { if ( $DN -match $script:TFMatchGuid ) { #Identity or ObjectId #NOTE MicrosoftTeams v2.3.1 - DO NOT use `-IncludeStatus` with Identity, it generates an error ParameterBindingException Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand.Name) - ID - '$DN'" $AAByName = Get-CsAutoAttendant -Identity "$DN" @GetCsAutoAttendantParameters $AutoAttendants += $AAByName } else { #Name Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand.Name) - Name - '$DN'" #$AAByName = Get-CsAutoAttendant -NameFilter "$DN" @GetCsAutoAttendantParameters $AAByName = Get-CsAutoAttendant -NameFilter "$DN" -IncludeStatus @GetCsAutoAttendantParameters $AAByName = $AAByName | Where-Object Name -EQ "$DN" $AutoAttendants += $AAByName } } } 'Search' { # Search Write-Verbose -Message "[PROCESS] $($MyInvocation.MyCommand.Name) - SearchString - '$SearchString'" #$AAbyName = Get-CsAutoAttendant -NameFilter "$SearchString" @GetCsAutoAttendantParameters $AAbyName = Get-CsAutoAttendant -NameFilter "$SearchString" -IncludeStatus @GetCsAutoAttendantParameters $AutoAttendants += $AAByName } } } #endregion # Parsing found Objects Write-Verbose -Message "[PROCESS] Processing found Auto Attendants: $($AutoAttendants.Count)" foreach ($AA in $AutoAttendants) { Write-Output (GetAutoAttendants -AA $AA -Detailed ($PSBoundParameters.ContainsKey('Detailed')) @args) } } #process end { Write-Verbose -Message "[END ] $($MyInvocation.MyCommand.Name)" if ($PSCmdlet.PagingParameters.IncludeTotalCount) { [double]$Accuracy = 1.0 $PSCmdlet.PagingParameters.NewTotalCount($AutoAttendants, $Accuracy) } # Resetting EnumerationLimit $global:FormatEnumerationLimit = $previousFEL } #end } #Get-TeamsAutoAttendant |