Teams Dialpad

Wer mit Microsoft Teams auch Rufnummern erreichen möchte, muss Rufnummern eingeben können. Ein guter Indikator für die Konfiguration ist das "Dialpad". Diese Seite beschreibt, welche Voraussetzungen erfüllt sein müssen und wie Sie ein fehlendes Dialpad diagnostizieren können.

Das Dialpad

Wenn Anwender mit Microsoft Teams auch Audio nutzen dürfen, dann erscheint links der Telefonhörer mit der Beschriftung "Anrufe". Allerdings können nur Anwender mit einer Telefonie-Funktion auch mittels Rufnummern eine Verbindung aufbauen:

Wie sinnvoll nun eine Eingabefläche für Rufnummern im Stiel eines Telefons ist, lasse ich mal dahingestellt. Ich gebe die Rufnummer immer auf dem PC direkt ein aber vielleicht nutzen Sie ja ein Touch-Gerät und brauchen das Feld. Allerdings gibt es immer wieder Support-Anrufe, dass Benutzer kein Wahlfeld haben, obwohl angeblich alles richtig konfiguriert ist und die Anwender sogar über ihre Telefonnummer erreichbar sind.

Fehlersuche Admincenter

Ehe sie in die Tiefen der Teams PowerShell absteigen, könnten sie einen neuen Troubleshooter von Microsoft ausprobieren, der in vielen Fällen schon den Fehler findet, sofern er im Backend zu erkennen ist. Sie starten den Troubleshooter entweder aus dem Teams Admin Center oder direkt über folgende Kurz-URL:

Beim Admin-Center klicken sie oben rechts auf das Fragezeichen und suchen mit einer deutschen Oberfläche nach "Wähltastatur..." und sehen sehr schnell den Einstieg zum Troubleshooter.

 

Geben Sie hier dann einfach die SIP-Adresse des Benutzers ein.

Wenn Sie die englische Version nutzen, dann kann es sein, dass zwar die Hilfeartikel gefunden werden aber der Troubleshooter verborgen bleibt:

Über den Weg könne Sie auch den Troubleshooter aber auch weiterführende Links erreichen.

Voraussetzungen

Die Checkliste ist relativ lange und erfordert "Teams Admin"-Rechte. 1/2nd Level Support mit Zugriff auf den Client können auch mit den Client Logs den Fehler ohne Mithilfe des Teams Administrators schon untersuchen und damit schon die Punkte der Checkliste eingrenzen.

Sollte der Troubleshooter aber nicht helfen, dann kann ihnen meine Checkliste helfen:

Voraussetzung Geprüft

Teams Lizenz

Die allermeisten Pakete von Microsoft 365 enthalten auch eine Teams Lizenz. Es gibt natürlich ausnahmen wie z.B. "Microsoft 365 Apps for Enterprise", in der nur Word, Excel, PowerPoint, OneDrive enthalten ist. Diese Benutzer können dann aber sowieso kein Teams starten. Für die Telefonie braucht es aber noch zusätzlich eine "Phone System"-Lizenz, die z.B. in Office 365 E3 nicht enthalten ist. In Office 365 E5 oder Microsoft 365 E5 ist sie Bestandteil. Sie können dies einfach per Teams PowerShell prüfen:

PS C:\> (Get-Csonlineuser user@msxfaq.net).AssignedPlan

AssignedTimestamp   Capability      CapabilityStatus 
-----------------   ----------      ---------------- 
23.03.2022 17:36:04 Teams           Enabled
23.03.2022 17:36:04 MCOEV           Enabled
23.03.2022 17:36:04 MCOProfessional Enabled
23.01.2018 22:55:43 MCOMEETADD      Enabled

Neben "Teams" muss auch MCOEV vorhanden sind. Sie sehen auch den "CapabilityStatus" und wann die Lizenz zugewiesen wurde. Es kann manchmal bis zu 72 Stunden dauern, bis das Provisioning abgeschlossen ist. Auch eine Abfrage nach "FeatureType" liefert weitere Informationen:

PS C:\> (Get-Csonlineuser user@msxfaq.net).FeatureTypes
AudioConferencing
PhoneSystem
Teams

SfBOnline User/TeamsOnly - nicht On-Prem

Das Dialpal und die Telefonie-Funktion von Teams ist nur mit Benutzern möglich, die in "in der Cloud sind. Speziell bei Firmen mit Skype for Business On-Premises und Teams Islandmode könnten hier eine Fehlerquelle liegen. Prüfen Sie, dass der Benutzer "TeamsOnly" ist.

PS C:\> Get-Csonlineuser user@msxfaq.net | fl RegistrarPool, HostingProvider,TeamsUpgradeEffectiveMode

RegistrarPool             : sippoolbl20a31.infra.lync.com
HostingProvider           : sipfed.online.lync.com
TeamsUpgradeEffectiveMode : TeamsOnly

Prüfen Sie hier:

  • Registrarpool muss einen OnlinePool oder "Teams:" enthalten
  • HostingProvider sollte "sipfed.online.lync.com" lauten.
  • Der Benutzer sollte "TeamsOnly" sein.

Enterprise Voice Enabled

Natürlich muss er auch hier für Telefonie in der Cloud aktiviert sein.

PS C:\> Get-Csonlineuser user@msxfaq.net | fl *enterprise*

EnterpriseVoiceEnabled       : True
OnPremEnterpriseVoiceEnabled : False

Sollte der Wert auf "False" stehen, können Sie ihn direkt setzen:

Set-CsPhoneNumberAssignment `
   -Identity user@msxfaq.net `
   -EnterpriseVoiceEnabled $True

Manchmal hängt etwas in Teams und es kann Wunder wirken, wenn Sie "-EnterpriseVoiceEnabled $True" einfach noch einmal ausführen, um ein erneutes Provisioning anzustoßen.

TeamsCallingPolicy und AllowPrivateCalling

Über entsprechende Richtlinien können Sie weiter steuern, was der Benutzer verwenden darf.

PS C:\> Get-CsUserPolicyAssignment -Identity user@msxfaq.net -PolicyType TeamsCallingPolicy | fl

PolicyName   : FC CRM-Test
PolicySource : {FC CRM-Test}
PolicyType   : TeamsCallingPolicy

Wenn die Policy leer ist dann fragen wir die "Global"-Policy ab. Ansonsten eben die hier angegebene Policy. Für das Dialpad muss "AllowPrivateCalling" auf $true stehen

PS C:\> Get-CsTeamsCallingPolicy -Identity "FC CRM-Test" | fl identity,AllowPrivateCalling

Identity            : Tag:FC CRM-Test
AllowPrivateCalling : True

WebCalling und Browser

Wenn Sie nicht die Teams App sondern Teams im Browser nutzen, dann müssen sie auch noch "WebCalling" erlauben.

PS C:\> Get-CsTeamsCallingPolicy -Identity "FC CRM-Test" | fl identity,AllowWebPSTNCalling 

Identity            : Tag:FC CRM-Test
AllowWebPSTNCalling : True

Zudem sollten Sie den Browser bzw. den UserAgent überprüfen. Telefonie mit Teams im Browser funktioniert nicht mit jedem Browser. Edge und Chome gehen schon länger. Internet Explorer 11, Safari und Firefox waren auch im Jan 2023 noch nicht supported.

LineURI

Das ist die Rufnummer, anhand der eingehende Verbindungen zu einem Benutzer vermittelt und welche bei ausgehenden Anrufen mit übermittelt wird. Dieses Feld muss eindeutig sein und hat eine Besonderheit: Wenn der Benutzer durch ADSync verwaltet wird und im lokalen AD das Feld "msRTCSIP-Line" gepflegt ist, dann schreibt ADSync dies in der Cloud-Feld "OnPremLineUri", welches dann in das Feld "LineURI" kopiert wird. Wenn das Feld "msRTCSIP-Line" leer ist, dann können sie trotz ADSync das "LineURI"-Feld in Teams verwalten.

PS C:\> Get-Csonlineuser user@msxfaq.net | fl *lineuri

LineUri       : tel:+495251304613;ext=613
OnPremLineUri :

Ist ist ein AD-Sync-User, der aber im lokalen AD keine "msRTCSIP-Line" gepflegt hat.

Teams nutzt das Feld zu folgenden Zwecken:

  • Anzeige der Rufnummer unter dem Dialpad
  • Routing eingehender Anrufe an den richtigen Empfänger
  • Matching für ausgehende Rufe anderer User
    Wenn A die Rufnummer B anruft und B im gleichen Tenant ist, dann macht Teams einen "Teams_Anruf" drauf, statt über das Telefonnetz zu gehen

Das Feld hat aber keine Funktion hinsichtlich Extension Dialing.

TelephoneNumber

Der Inhalt dieses Felds ist für die Telefonie zwar streng genommen nicht zwingend erforderlich aber wird von Teams für folgende Funktionen genutzt und sollte daher schon gepflegt sein

  • Erreichbarkeit durch Extension Dialing über einen Auto Attendant
  • Reverse Number Lookup um eingehende Anrufe auf einen Namen abzubilden
    Teams Rückwärtssuche (RNL)
  • Interne Erreichbarkeit mit der Nummer
  • Anzeige in der Kontaktkarte und Anruf darüber

Wenn ihre Anwender aus dem lokalen AD per ADSync repliziert werden, dann ist das Feld im AzureAD geschützt und muss im lokalen AD gepflegt werden. Das Feld können sie leider nicht in der Teams-PowerShell sehen, sondern benötigen die AzureAD-PowerShell:

PS C:\> get-azureadUser -SearchString fcarius | fl *TelephoneNumber

FacsimileTelephoneNumber : +495251304653
TelephoneNumber          : +49(5251)304613;ext=613

Das ";ext=613"-Anhängsel ist für eine Vermittlung mittels Extension Dialing. Die Klammern stören Teams nicht.

PSTN-Anbindung

Natürlich muss irgendwie auch eine Verbindung zum "Amt" hergestellt werden. Dazu haben sie gleich mehrere Optionen, die auch parallel konfiguriert sein können.

PstnConnectivity

Wenn ihr Benutzer per Direct Routing angebunden ist, dann sollte das Feld "PstnConnectivity auf "On-Premises" stehen. Wenn Sie dem Benutzer einen Microsoft Plan zugewiesen haben, dann steht hier "BusinessVoice".

PS C:\> Get-CsOnlineVoiceUser -Identity user@msxfaq.net | fl PstnConnectivity

PstnConnectivity : On-Premises

Sollte gar nichts hinterlegt sein, dann ist der Benutzer nicht korrekt konfiguriert. Prüfen Sie dann die anderen Einstellungen noch einmal.

VoiceRouting

Die Verknüpfung von Benutzer zur TK-Anbindung erfolgt über eine "CsOnlineVoiceRoutingPolicy". Zuerst hole ich mir die Policy für den Anwender:

PS C:\> Get-CsOnlineUser -Identity user@msxfaq.net | fl OnlineVoiceRoutingPolicy

OnlineVoiceRoutingPolicy : DeStandard

Wenn diese Feld nicht gefüllt ist, dann kommt die "Global" Policy zum tragen, die Microsoft per Default mit anlegt aber keine PSTNUsage verbindet. Das kann das ein haben sie schon den Grund für das fehlende Dialpad, denn der Teams Client zeigt das Dialpad nur an, wenn es auch mindestens eine Route gibt.

Ich lasse die "Global"-OnlineVoiceRoutingPolicy dennoch immer auf "Default" und weise jedem Anwender explizit die korrekte Policy zu. Global zu ändern maht nur Sinn, wenn wirklich alle Benutzer die gleiche Einstellung brauchen und sie einfach nur die individuelle Zuweisung sparen wollen.

 Es kann passieren, dass der Wert gesetzt aber dennoch nicht wirksam ist. Sie können ein Neuprovisioning dann anstoßen, indem Sie die Policy entfernen und erneut zuweisen, z.B. mit:

Grant-CsOnlineVoiceRoutingPolicy -Identity user@msxfaq.net -PolicyName $Null
Grant-CsOnlineVoiceRoutingPolicy -Identity user@msxfaq.net -PolicyName DeStandard

Änderungen können bis zu 24h dauern, ehe Sie aktiv werden.

Anhand der zugewiesenen OnlineVoiceRoutingPolicy kann ich dann den RouteType und die OnlinePstnUsages erhalten:

PS C:\> Get-CsOnlineVoiceRoutingPolicy |ft identity,routetype,onlinepstnusages

Identity        RouteType OnlinePstnUsages
--------        --------- ----------------
Global          BYOT      {}
Tag:DePbIntern  BYOT      {DePbIntern}
Tag:DeStandard  BYOT      {DeNational, DeWeltweit}
Tag:TestRouting BYOT      {TestUsage}

Für direkt Routing ist "BYOT" (Bring your own trunk) korrekt. Diese Auswertung können sie auch im Teams Admin Center beim Benutzer sehen:

Mit einem Microsoft Plan ist es dann "BusinesVoice". Über die OnlinePstnUsages und die Rufnummer wird dann das Gateway bestimmt:

PS C:\> Get-CsOnlineVoiceRoute | ft identity,numberpattern,onlinepstnusages,OnlinePstnGatewayList

Identity       NumberPattern      OnlinePstnUsages OnlinePstnGatewayList
--------       -------------      ---------------- ---------------------
DE-PB-Intern   ^(\+495251304\d+)$ {DePbIntern}     {sbc.msxfaq.net}
DE-PB-Local    ^(\+495251\d*)$    {DePbLocal}      {sbc.msxfaq.net}
DE-PB-Weltweit ^(\+\d*)$          {DeWeltweit}     {sbc.msxfaq.net}
DE-PB-National ^(\+49\d*)$        {DeNational}     {nawsbc.msxfaq.net}

Ich bin nicht sicher, ob Fehler hier keine Auswirkung auf das Erscheinen des Dialpad hat aber es bringt ja nichts, wenn der Anwender eine Nummer eingeben aber dann nicht anrufen kann.

Dialplan

Ein Benutzer muss nicht zwingend einen eigenen Dialplan haben, denn Microsoft hat pro Land einen "Default" hinterlegt, der ganz gut funktioniert, solange sie keine internen Nebenstellen über eine Kurzwahl erreichen wollen. Ansonsten prüfen Sie, welcher Dialplan der Anwender hat.

PS C:\> get-csonlineUser -Identity user@msxfaq.net | fl *dialplan

DialPlan       : DE
TenantDialPlan : PB-ohne-Amtsholung FC

Und dann schauen Sie ich die Normalisierungsregeln an:

PS C:\> (Get-CsTenantDialPlan  "PB-ohne-Amtsholung FC").NormalizationRules | ft

Description Pattern           Translation  Name             IsInternalExtension
----------- -------           -----------  ----             -------------------
            ^00(\d*)$         +$1          International 00               False
            ^0(\d*)$          +49$1        National 0                     False
            ^([6-8]\d{2})$    +495251304$1 intern 6xx-8xx                 False
            ^([1-9]\d{1}\d+)$ +495251$1    Ortsbereich PB                 False

Anhand der vom Anwender eingegebenen Nummer erhalten Sie dann die tatsächlich gewählte Nummer. Wenn Sie später eine Dialpad haben, dann können Sie natürlich die Nummer auch im Dialpad eingeben und etwas warten, bis die normalisierte Nummer angezeigt wird.

Teams Client Cache

Sollten sie über den Troubleshooter als auch über meine Checkliste immer noch keine Ursache gefunden haben, dann lohne sich ein Blick auf den Client. Ehe sie aber hier in die Analyse einsteigen, sollten Sie erst einmal Teams beenden, den Cache löschen und neu starten. Oftmals sind Einstellungen aus dem Backend noch nicht auf den Client gekommen. Sie löschen dazu einfach alle Dateien in dem folgenden Verzeichnis beim Benutzer:

%appdata%\Microsoft\Teams

Dadurch gehen keine Inhalte oder Daten verloren.

Fehlersuche Clientlogs

Wenn auch nach dem Neustart und damit erzwungenen Download der Richtlinien immer noch kein Dialpad vorhanden ist, dann lohnt sich der Bild in die Diagnoselogs. Dazu muss der Client einmal diese generieren lassen. Dazu gibt es folgende Optionen.

  • Kontext-Menü am TrayIcon
  • Teams Client Hotkey
    Halten Sie die Tasten CTRL, SHIFT und ALT fest und drücken dann die "1"

Danach startet der Teams Client einen Dump der relevanten Daten in das "Download"-Verzeichnis mit einem Zeitstempel. Im Unterverzeichnis "web" befinden sich dann die interessanten Dateien:

Interessant ist hier die Datei "MSTeams_Diagnostics Log_<TT_M_YYYY__HH_mm_ss>.txt" , welche Sie am besten in Visual Studio Code, Notepad++ oder einem anderen Editor mit Suchfunktion öffnen. Notfalls tut es auch Windows Notepad.

Die Strings können mehrfach vorkommen. Wenn ihr Editor eine Suche mit regulären Ausdrücken unterstützt, müssen sie die Suche ggfls. anpassen.

Die Auszüge hier sind aus meinem produktiven Benutzerkonto, welcher mit Teams und Direct Routing telefonieren kann und natürlich ein Dialpad angezeigt bekommt. Sie können ihre Werte daher gut damit vergleichen.

Zuerst suche ich nach "CallingSupportService:". Sie sollten gleich mehrere Zeilen mit diesem Text finden.

Interessant sind dahinter die Flags in der Liste. Hier ein Auszug der Zeile hinter "Calculated isPSTNCallingAllowed with the following flags."

Calculated isPSTNCallingAllowed with the following flags: {"isCallingAllowed":true,
   "isSfbCloud":true,
   "isEvEnabled":true,
   "disableCallingForHybridVoice":true,
   "pstnType":"OnPrem",
   "isBusinessVoicePath":false,
   "isByotEnabled":true,
   "allowWebPSTNCalling":true,
   "enableAllowWebPSTNCalling":true,
   "isWeb":false,
   "result":true}.
Old state: true, Current state true

Wir sehen hier auf einen Blick die verschiedenen Einstellungen, die Einfluss auf die Anzeige des Dialpad haben. Im Prinzip müssen alle Felder bei ihrem Problem-Benutzer die gleichen Werte haben. Mit einem Microsoft Dialplan ist dann natürlich "isBusinessVoicePath:True" und "isByotEnabled:False".

Wenn Sie Teams frisch gestartet haben, dann können sie in der Datei auch die aktuellen Richtlinien auslesen. Eie Suche nach "voiceAdminSettings" liefert einen Teil der Einstellungen:

    "voiceAdminSettings": {
      "value": {
        "phoneNumber": "495251304613;ext=613",
        "isEvEnabled": true,
        "isSipEnabled": true,
        "isSmsEnabled": false,
        "isSfbCloud": true,
        "adminSettings": {
          "isEvEnabled": true,
          "isSipEnabled": true,
          "isSmsEnabled": false
        }

Ein paar Zeilen weiter unten findet sich dann auch wieder die Einstellung zu "isByotEnabled" und der Dialplan:

   "policySettings": {
      "value": {
        "byot": {
          "isByotEnabled": true
        },
        "clientPolicy": {},
        "callingLineIdentityPolicy": {},
        "teamsMeetingPolicy": {
          "allowChannelMeetingScheduling": true,
          "allowMeetNow": true,
          "allowCloudRecording": true
        },
        "teamsInteropPolicy": {
          "callingDefaultClient": "Default",
          "chatDefaultClient": "Default"
        },
        "dialPlanPolicy": {
          "normalizationRules": [
            {
              "pattern": "^00(\\d*)$",
              "translation": "+$1"
            },
            {
              "pattern": "^0(\\d*)$",
              "translation": "+49$1"
            },
            {
              "pattern": "^([6-8]\\d{2})$",
              "translation": "+495251304$1"
            },
            {
              "pattern": "^([2]\\d{2})$",
              "translation": "$1"
            },
            {
              "pattern": "^([1-9]\\d{1}\\d+)$",
              "translation": "+495251$1"
            },
            {
              "pattern": "^00(\\d+)$",
              "translation": "+$1"
            },
            {
              "pattern": "^((\\+)?(\\d+))(;)?(ext|extn|EXT|EXTN|x|X)(=)?(\\d+)$",
              "translation": "$1;ext=$7"
            },
            {
              "pattern": "^0(\\d+)$",
              "translation": "+49$1"
            }
          ],
          "ituCountryPrefix": "49"
        },

Und zuletzt finden Sie über eine Suche nach "callingPolicy" auch die dazu aktuell gültigen Einstellungen, bei denen der Wert "allowPrivateCalling" auf True stehen muss.

    "callingPolicy": {
      "value": {
        "allowPrivateCalling": true,
        "allowGroupCalling": true,
        "allowCallForwarding": true,
        "allowWebPSTNCalling": true,
        "allowSIPDevicesCalling": true,
        "allowVoicemail": "UserOverride",
        "allowCallGroups": true,
        "allowDelegation": true,
        "allowCallForwardingToUser": true,
        "allowCallForwardingToPhone": true,
        "busyOnBusyEnabledType": "UserOverride",
        "allowCloudRecordingForCalls": true,
        "musicOnHoldEnabledType": "Enabled",
        "allowTranscriptionForCalling": true,
        "liveCaptionsEnabledTypeForCalling": "DisabledUserOverride",
        "autoAnswerEnabledType": "Disabled",
        "callRecordingExpirationDays": 60,
        "popoutForIncomingPstnCalls": "Enabled",
        "popoutAppPathForIncomingPstnCalls": "https://localhost:8123/rueckwaertssuche/{phone}"
      }

Wenn Sie tiefer in das Teams Troubleshooting einsteigen wollen, dann suchen Sie nach Vorträgen und Präsentationen von "Carolyn Blanding". Als "Microsoft Teams Beta Test Engineer" bekommt Sie viele Eskalations-Tickets von Kunden auf den Tisch und stellt die häufigsten Probleme und deren Analyse immer wieder vor, z.B. auf der Commsverse 2022

Troubleshooting Microsoft Teams Voice [Deep Dive] (ab min 16:18)
https://youtu.be/azWZmwW1xhs?t=978
https://www.youtube.com/watch?v=azWZmwW1xhs

Zusammenfassung

MIcrosoft Teams zeigt dem Anwender nur dann ein Dialpad an, wenn Teams sicher ist, dass die Funktion auch gegeben ist. Allerdings ist es nicht nur eine Einstellung, die sie von "Aus" auf "An" stellen müssen, sondern es müssen ganz viele Weichen richtig gestellt sein, damit am Ende das Dialpad erscheint. Mit der Fehlersuche durch den Troubleshooter im Microsoft Teams Admin Center, meiner Checkliste mit der AzureAD und Teams PowerShell als auch die Analyse auf dem Client über die Teams Client Logs sollte es ihnen aber ermöglichen, die Ursache für ein fehlendes Dialpad zu finden und zu beheben. Wenn Sie aber eine Unstimmigkeit zwischen der Konfiguration im Tenant und der beim Client letztlich effektiven Konfiguration finden, dann reicht manchmal einfach etwas Geduld aber wenn auch nach Tagen kein Dialpad erscheint, dann könnte ein Reprovisioning durch eine doppelte Änderung der inkonsistenten Einstellung oder ein Microsoft Ticket das Problem beseitigen.

Weitere Links