Teams Rufnummern

Wer mit Teams telefoniert, braucht nicht nur einen "Amtsanschluss über Microsoft, Operator Connect oder Direct Routing, sondern auch die passende Lizenz und Konfiguration. Microsoft baut im Unterbau kontinuierlich etwas um und manchmal erhascht man einen Blick hinter die Kulissen.

Diese Seite beschreibt sowohl die "sichtbaren" Rufnummern in den Kontakten als auch die "unsichtbare" Rufnummer über die Teams per Telefonie erreichbar ist. Beachten Sie dazu auch die Seite SfB2Teams Telefonieumstellung.

Sichtbare Rufnummern

Wenn wir beim lokalen Active Directory starten, dann hat jeder Benutzer gleich mehrere AD-Felder, in denen Rufnummern stehen können. Hier ein Ausschnitt:

Dahinter verbergen sich natürlich unterschiedliche Felder, von denen einige Mehrfachfelder sind wie:

  • telephoneNumber
  • telephoneAssistant
  • telexNumber
  • facsimileTelephoneNumber
  • ipPhone
  • homePhone
  • mobil
  • otherFacsimileTelephoneNumber
  • otherHomePhone
  • otherIpPhone
  • otherMobile
  • otherTelefone

Einige der Fehler sind sogar mehrdeutig. Natürlich werden die Felder mit ADSync auch in die Cloud repliziert, damit Sie bei der "Contact Card" eines Benutzers die ganzen Rufnummern sehen und sogar anklicken können. Sie haben aber keine Funktion für das Routen von Telefonanrufen mit Skype for Business oder Microsoft Teams.

Skype/Teams-Rufnummern

Für die Telefonie mit Skype for Business OnPremises oder Microsoft Teams sind hingegen andere Felder relevant. Die "sichtbaren Rufnummern" sind nur zur Information. Das können Sie wie mit Microsoft Exchange vergleichen, welcher nur die Inhalte von "ProxyAddresses" verwendet, während alle andere Felder wie z.B. "mail" zwar aus Gründen der Datenkonsistenz mit gepflegt werden aber für das Mailrouting nicht relevant sind. Für die PSTN-Funktion sind folgende Felder relevant:

Plattform Feldname Beschreibung/Bedeutung

SfB OnPrem

msRTCSIP-Line

Der Inhalt dieses Feldes bestimmt, unter welcher Rufnummer der Anwender aus der Skype for Business-Welt erreichbar ist und welche ausgehende rufende Nummer angezeigt wird.

Teams Online

OnPremLineUri

In der Cloud gibt es (Stand Jun 2022) immer noch das Feld "OnPremLinUri" und es wird auch vom ADSync verwaltet. Skype for Business Online hat das Feld genutzt und anfangs sogar Teams. Mittlerweile liest Teams dieses Feld nur noch bei Hybrid aus und kopiert ist ein das neue Feld LineURI.

In Teams PowerShell Module version 3.0.0 and later, the OnPremLineURI attribute refers only to the LineURI that's set via OnPrem AD. Previously, OnPremLineURI also referred to Direct Routing numbers that were assigned to users via the Set-CsUser cmdlet. OnPremLineUriManuallySet is now deprecated as OnPremLineURI is representative of the On-Prem assignment. Also, Direct Routing numbers are available in the LineURI attribute. You can distinguish Direct Routing Numbers from Calling Plan Numbers by looking at the FeatureTypes attribute.
Quelle: Get-CSOnlineUser https://docs.microsoft.com/en-us/powershell/module/skype/get-csonlineuser?view=skype-ps#parameters

 

Teams Online

LineURI

Mittlerweile nutzt Microsoft Teams dieses Feld für die Telefonie.

Teams Rufnummern verwalten

Früher war dazu das Commandlet Set-CSUser auch in der Cloud zuständig und für Anwender die noch mit Skype for Business OnPremises arbeiten, ist Get-CSUser auch weiterhin das Mittel der Wahl zur Zuweisung von Rufnummern. Mit Microsoft ist Set-CSUser aber abgekündigt und am 10.6.2022 konnte ich meinen Benutzer nur noch mit einer Warnung konfigurieren:

Ich kann zwar noch ein "Set-CSUser -OnPremLineURI" machen, aber das Feld bleibt leer. Wenn es gefüllt ist, dann wird es durch ADSync geschrieben. Dennoch gibt es nun gleich mehrere Commandlets, die mit der Rufnummernkonfiguration etwas zu tun haben:

Commandlet Beschreibung

get-csphonenumberassignment

Damit können Sie die im Tenant zugewiesenen Rufnummern auflisten. Über Parameter können Sie gezielt eine Zuweisung suchen

-TelephoneNumber
-TelephoneNumberContain
-TelephoneNumberGreaterThan
-TelephoneNumberLessThan
-TelephoneNumberStartsWith

Die Rufnummer kann als E.164 mit führendem "+" oder ohne das Plus angegeben werden.

Auch Filter nach dem Anschlusstyp (DirectRouting, PhoneSystem) sind möglich. Folgende Properties liefert das Commandlet z.B. bei meiner Rufnummer:

PS C:\> Get-CsPhoneNumberAssignment -TelephoneNumber +495251304613

TelephoneNumber         : +495251304613
NumberType              : DirectRouting
ActivationState         : Activated
AssignedPstnTargetId    : b39bb717-ea64-46cd-ab57-xxxxxxxxxxxx
Capability              : {ConferenceAssignment, VoiceApplicationAssignment, UserAssignment}
City                    : Paderborn
CivicAddressId          : 00000000-0000-0000-0000-000000000000
IsoCountryCode          :
IsoSubdivision          : All
LocationId              : 00000000-0000-0000-0000-000000000000
LocationUpdateSupported : True
PortInOrderStatus       :
PstnAssignmentStatus    : UserAssigned
PstnPartnerId           :
PstnPartnerName         :

Sie sehen, dass hier kein Usernamen direkt sichtbar ist. Die Rufnummer ist dem Objekt mit der GUID im Feld "AssignedPstnTargetID" zugewiesen.

Der Status "PstnAssignmentStatus" kann auch "unassigned sein, wenn es eine von Microsoft gestellte Rufnummer ist. HIer weiss der Tenant, welche Rufnummern ihnen gehören. Bei DirectRouting ist das nicht der Fall.

Get-CSOnlineUser

Diese Commandlet liefert durchaus auch Werte zu Rufnummern und hilft bei der Analyse eines einzelnen Benutzers.

PS C:\> get-csonlineuser frank.carius@netatwork.de | fl Identity,*line*

Identity                             : b39bb717-ea64-46cd-ab57-xxxxxxxxxxxx
CallingLineIdentity                  :
LineUri                              : tel:+495251304613
OnPremLineUri                        :
OnlineAudioConferencingRoutingPolicy :
OnlineDialOutPolicy                  :
OnlineVoiceRoutingPolicy             : DeStandard
OnlineVoicemailPolicy                :

Sie sehen hier aber auch, dass nur die LineURI gesetzt ist und "OnPremLineUri" leer ist. Hier kommt also keine Nummer mehr von einem OnPremises Skype for Business Server per ADSync in den Tenant.

Allerdings liefert dieses Commandlet auch nur Benutzer aber kein Telefone, Bots, Call Queues etc, die auch eine Rufnummer halten können.

Get-CsOnlineVoiceUser

Das dritte Commandlet zeigt mir wieder eine andere Ansicht. Früher wurden hier auch Benutzer ohne eine "Phone System"-Lizenz (MCOEV*) gelistet. Dies ist seit Version 3.0 nicht mehr.

PS C:\> Get-CsOnlineVoiceUser -Identity frank.carius@netatwork.de

Name                   : Carius, Frank (NAW)
Id                     : b39bb717-ea64-46cd-ab57-00186effe82c
SipDomain              : netatwork.de
DataCenter             : bl2
TenantId               : de21c301-a4ae-4292-aa09-6db710a590a6
Number                 : 495251304613
Location               :
PstnConnectivity       : OnPremises
UsageLocation          : DE
EnterpriseVoiceEnabled : True

Die Gegenstücke "CsOnlineVoiceUser" und "Set-CsOnlineVoiceUserBulk" ist mittlerweile depreciated.

Set-CsPhoneNumberAssignment
Remove-CsPhoneNumberAssignment

Mit wenigen Ausnahmen sind diese beiden Commandlets zukünftig für die Verwaltung von Rufnummern in Microsoft Teams relevant.

Achtung:
Provisioning: Sie sollten immer zuerst eine Lizenz zuweisen, ehe Sie DirectRouting konfigurieren
Deprovisioning: Entfernen Sie immer erst die Rufnummer, ehe Sie die Lizenz entfernen.
Das Entfernen der Lizenz entfernt nicht die Rufnummernzuweisung

Eine Liste aller zugewiesenen Rufnummern bekommen Sie z.B. mit

PS C:\> Get-CsPhoneNumberAssignment | ft TelephoneNumber,ActivationState,NumberType

TelephoneNumber ActivationState NumberType
--------------- --------------- ----------
+495251304613   Activated       DirectRouting
+495251532398   Activated       CallingPlan

Allerdings sehen Sie nicht das entsprechende Objekt. Dazu müssten Sie dann noch das Feld "AssignedPstnTargetId" mit einem Get-CSOnlineUser in ein Objekt umwandeln.

[hashtable]$targetidlist=@{}
foreach ( $entry in (get-csonlineuser)) {
    Write-Host "Processing USER: $($entry.UserPrincipalName)"
    $targetidlist[$entry.identity] = "USER:$($entry.UserPrincipalName)"
}

foreach ( $entry in (Get-CsOnlineApplicationInstance)) {
    $targetidlist[$entry.objectid] = "AppInst:$($entry.UserPrincipalName)"
}

foreach ( $entry in (Get-CsOnlineDialInConferencingBridge)) {
    $targetidlist[$entry.objectid] = "ConfBridge:$($entry.UserPrincipalName)"
}


$phonenumberlist = Get-CsPhoneNumberAssignment | select TelephoneNumber,ActivationState,NumberType,AssignedPstnTargetId,PstnAssignmentStatus,UserPrincipalName
foreach ($entry in $phonenumberlist) {
    Write-Host "Matching $($entry.TelephoneNumber) and $($entry.AssignedPstnTargetId)"
    if ($entry.PstnAssignmentStatus -eq "unassigned") {
        $entry.UserPrincipalName = "unassigned"
    else {}
        $entry.UserPrincipalName = $targetidlist[$entry.AssignedPstnTargetId]
    }
}

Der Code ist noch nicht perfekt, denn es werden noch nicht alle möglichen Endpunkte vorab ermittelt. Für Benutzer und CallQueues ist es aber ein erster Anfang und die Ausgabe von "phonenumberlist" können Sie mit Convertto-html z.B. in eine Tabelle bringen oder anderweitig weiter verarbeiten.

Geduld ist gefragt

Wenn Sie mit dem Provisioning von Rufnummern in Teams zu tun haben, dann sollten Sie auch die Seite BVD - Business Voice Directory und Azure AD - Ein Verzeichnisdienst, oder zwei oder mehr kennen. Es kann nämlich sein, dass die Rufnummern "blockiert" sind oder eine Zuweisung nicht sofort aktiv wird. Das ist der erforderlichen Replikation im Backend geschuldet, bei der gleich mehrere Datentöpfe involviert sind. Microsoft legt dies nicht komplett offen aber ich habe folgende Datenspeicher bislang identifiziert:

  • Lokales AD und ADSync
    Wenn Sie SfB Hybrid sind oder ADSync mit lokaler Verwaltung nutzen, dann müssen/sollten Sie die Rufnummern im lokalen AD pflegen und es kann schon bis zu 30 Minuten (Default) dauern, bis die Rufnummer zur Cloud geschrieben wird.
  • AzureAD und Teams Backend
    ADSync schreibt die Daten an einen Identity-Service, der dann die Information aber erst in die Zielumgebung schreiben muss. Hier ist weniger das AzureAD relevant sondern das Teams-Verzeichnis.
  • Lizenz und BVD - Business Voice Directory
    Nur wenn der Benutzer eine Phone System-Lizenz hat, wird angeblich die Zuordnung von Benutzer und Rufnummer in das BVD übertragen. Danach sollte das Backend sehr schnell funktionieren. Die Änderungen durch eine Zuweisung der Phone System Lizenz kann aber einige Stunden dauern.
  • Teams Client
    Zuletzt muss natürlich der Teams Client all die Änderungen noch mitbekommen, ehe er letztlich dann auch ein Dialpad anzeigt.

Die Problematik der gesamten Replikation ist, dass große Änderungen manchmal sehr lange dauern und wenn Sie nicht sicher sind, dass Sie alles richtig gemacht haben, dann wird ein Administrator schon einmal nervös, hektisch und ungeduldig. Es gibt aber auch die Fälle, in denen wirklich im Backend etwas "klemmt" und dann hilft oft nur ein Support Ticket, bei dem Microsoft dann ein "SyncNow" oder "Force Full Sync" auslöst. Es kann nämlich schon passieren, dass Sie eine Rufnummer nicht zuweisen können, weil diese angeblich schon zugewiesen ist:

"Telephone Number +49xxxxx has already been assigned to another user"

Leider liefert Microsoft in der Fehlermeldung, die auch im Portal so erscheint, nicht das Konfliktobjekt mit. Sie können dann versuchen, die Nummer mit "Get-CsPhoneNumberAssignment" zu finden. In den meisten Fällen verweist die Zuweisung dann auf eine "AssignedPstnTargetId", zu der Sie aber kein Objekt finden. Theoretisch könnten Sie sogar die Rufnummernbindung mit Remove-CsPhoneNumberAssignment entfernen, denn hier kann neben dem UPN auch die AssignedPstnTargetId als Identity angegeben werden

# Aktuelle Zuweisung auslesen
$a=Get-CsPhoneNumberAssignment -telephonenumner xxxxx

# Versuch die Zuweisung zu entfernen
Remove-CsPhoneNumberAssignment -Identity $a.AssignedPstnTargetId -PhoneNumber $a.TelephoneNumber -PhoneNumberType $a.NumberType

Leider scheint das auch nicht immer "sofort" zu klappen. Vielleicht können Sie ja mit "Get-AzureADObjectByObjectId" und der ID aus dem Feld "AssignedPstnTargetId" ein Objekt finden

Get-AzureADObjectByObjectId -ObjectIds <System.Collections.Generic.List`1[System.String]>

Leider gibt es auch im Internet dazu nur einige Seiten mit der gleichen Frage aber keine Lösung.

Weitere Links