Teams Direct Routing zu STARFACE: Sterncodes unverändert durchreichen

Problem und Lösung

Eine Tenant-Wählplanregel reicht alles, was mit * beginnt, unverändert an die STARFACE durch. Ohne diese Regel normalisiert Teams Sterncodes wie *011997 mit dem deutschen Standard-Wählplan und setzt +49 davor – die STARFACE kann damit nichts anfangen.

Normale Rufnummern und Notrufe (110, 112) bleiben unberührt, weil die Regel nur auf * am Anfang greift.

Voraussetzungen

  • Teams Direct Routing zur STARFACE läuft bereits (SBC-Eintrag, z. B. teams.starface.kunde.de, Port 5061).
  • Voice Route mit Muster ^.*$ oder ^\* auf dieses Gateway – sonst werden Sterncodes abgewiesen.
  • Windows PowerShell 5.1 mit dem Modul MicrosoftTeams (Install-Module MicrosoftTeams -Scope CurrentUser).
  • Konto mit Rolle Teams-Administrator im Kunden-Tenant.
  • Ein Testnutzer mit Teams-Telefonie (Telefonnummer + Voice Routing Policy zugewiesen).

Einrichtung (ca. 10 Min)

  1. Vorhandene Wählpläne prüfen: Get-CsTenantDialPlan. Gibt es nur Global ohne Regeln, DP-Starface als Namen lassen. Gibt es schon einen zugewiesenen Plan, dessen Namen eintragen – das Skript hängt die Regel an, statt den Plan zu ersetzen.
  2. Die drei Variablen im Skript anpassen und das Skript ausführen.
  3. Am Ende muss die Kontrolle TranslatedNumber : *011997 zeigen.
#Requires -Version 5.1
<#
    Teams Direct Routing -> STARFACE
    Sterncodes (*...) unverändert an die STARFACE durchreichen.
    Ohne Regel macht Teams aus *011997 eine +49...-Nummer.
#>

# --- Anpassen ------------------------------------------------------------
$TestUser = "vorname.nachname@kunde.de"   # Testnutzer mit Teams-Telefonie
$DialPlan = "DP-Starface"                 # Name des Wählplans (neu oder vorhanden)
$TestNr   = "*011997"                     # Sterncode zum Testen

# --- Verbinden ------------------------------------------------------------
Connect-MicrosoftTeams | Out-Null

# --- Regel im Speicher bauen ----------------------------------------------
# Alles, was mit * beginnt (Ziffern, *, #), wird 1:1 zurückgegeben
$nrPass = New-CsVoiceNormalizationRule -Parent Global -Name "Starface-Sternpassthrough" `
    -Description "Sterncodes unveraendert an Starface" `
    -Pattern '^(\*[\d\*#]+)$' `
    -Translation '$1' `
    -IsInternalExtension $false -InMemory

# --- Wählplan anlegen oder ergänzen ---------------------------------------
$dp = Get-CsTenantDialPlan -Identity $DialPlan -ErrorAction SilentlyContinue
if (-not $dp) {
    New-CsTenantDialPlan -Identity $DialPlan -NormalizationRules @{Add = $nrPass} | Out-Null
    Write-Host "Wählplan $DialPlan neu angelegt." -ForegroundColor Green
}
elseif ($dp.NormalizationRules.Name -notcontains "Starface-Sternpassthrough") {
    # Regel nach VORNE setzen, damit sie vor allen anderen Regeln greift
    $regeln = @($nrPass) + @($dp.NormalizationRules)
    Set-CsTenantDialPlan -Identity $DialPlan -NormalizationRules $regeln
    Write-Host "Regel in vorhandenen Wählplan $DialPlan eingefügt." -ForegroundColor Green
}
else {
    Write-Host "Regel ist in $DialPlan schon vorhanden." -ForegroundColor Yellow
}

# --- Testnutzer zuweisen --------------------------------------------------
Grant-CsTenantDialPlan -Identity $TestUser -PolicyName $DialPlan

# --- Kontrolle (Format-List, damit die Ausgabe nicht verschluckt wird) ----
Test-CsEffectiveTenantDialPlan -DialedNumber $TestNr -Identity $TestUser |
    Format-List TranslatedNumber, MatchingRule

Wenn der Kunde bereits eine Regel hat, die * umschreibt, muss unsere Regel davor stehen – deshalb setzt das Skript sie an Position 1.

Prüfskript: Routing-Simulation

Das Skript spielt den Weg eines Anrufs durch (Wählplan → Voice Routing Policy → Voice Route → Gateway), ohne wirklich anzurufen. Alles Cyan/Grün = Teams-Seite fertig; eine rote Zeile zeigt, wo es hängt.

#Requires -Version 5.1
<#
    Routing-Simulation Teams -> STARFACE
    Löst KEINEN echten Anruf aus.
#>

$User   = "vorname.nachname@kunde.de"
$Nummer = "*011997"

# 1) Wählplan: Was macht Teams aus der gewählten Nummer?
$dp   = Test-CsEffectiveTenantDialPlan -DialedNumber $Nummer -Identity $User
$ziel = if ($dp.TranslatedNumber) { $dp.TranslatedNumber } else { $Nummer }
Write-Host "1) Gewählt: $Nummer  ->  an Routing übergeben: $ziel" -ForegroundColor Cyan

# 2) Voice Routing Policy des Nutzers ermitteln
$u       = Get-CsOnlineUser -Identity $User
$polName = if ($u.OnlineVoiceRoutingPolicy) { $u.OnlineVoiceRoutingPolicy.Name } else { "Global" }
$pol     = Get-CsOnlineVoiceRoutingPolicy -Identity $polName
Write-Host "2) Voice Routing Policy: $polName  (Usages: $($pol.OnlinePstnUsages -join ', '))" -ForegroundColor Cyan

# 3) Passende Voice Route suchen (Usage passt UND Pattern trifft)
$route = Get-CsOnlineVoiceRoute | Sort-Object Priority | Where-Object {
    ($_.OnlinePstnUsages | Where-Object { $pol.OnlinePstnUsages -contains $_ }) -and
    ($ziel -match $_.NumberPattern)
} | Select-Object -First 1

if (-not $route) {
    Write-Host "3) KEINE passende Route -> Teams würde den Anruf abweisen" -ForegroundColor Red
    return
}
Write-Host "3) Route: $($route.Name)  Pattern: $($route.NumberPattern)  Gateway: $($route.OnlinePstnGatewayList -join ', ')" -ForegroundColor Cyan

# 4) Gateway (STARFACE) prüfen
foreach ($gw in $route.OnlinePstnGatewayList) {
    $g     = Get-CsOnlinePSTNGateway -Identity $gw
    $farbe = if ($g.Enabled) { "Green" } else { "Red" }
    Write-Host "4) Gateway $gw  Aktiv: $($g.Enabled)  Port: $($g.SipSignalingPort)" -ForegroundColor $farbe
}

Write-Host "`nErgebnis: Teams schickt '$ziel' an die Starface." -ForegroundColor Green

Erwartete Ausgabe bei Kunden: Route TeamStarConnect, Pattern ^.*$, Gateway aktiv auf Port 5061, Ergebnis *011997.

Test, Ausrollen, Rollback

  1. Testanruf: Teams beim Testnutzer komplett beenden (auch im Infobereich), neu starten, Sterncode wählen. Die Regel kann bis zu 1 h brauchen, bis der Client sie übernimmt.
  2. Ausrollen auf alle: erst nach erfolgreichem Test.
  3. Rollback: bei Problemen die globale Zuweisung zurücknehmen; die Einzelzuweisung des Testnutzers bleibt.
# Ausrollen: Wählplan als Standard für alle Nutzer im Tenant
Grant-CsTenantDialPlan -Global -PolicyName "DP-Starface"

# Rollback: globale Zuweisung zurücknehmen
Grant-CsTenantDialPlan -Global -PolicyName $null

# Rollback Testnutzer
Grant-CsTenantDialPlan -Identity "vorname.nachname@kunde.de" -PolicyName $null

Nutzer mit einer eigenen Wählplan-Zuweisung sind von -Global nicht betroffen. Prüfen mit Get-CsOnlineUser -Filter {TenantDialPlan -ne $null} | Select-Object UserPrincipalName, TenantDialPlan.

Typische Fehler

SymptomUrsacheFix
Skriptausgabe zeigt nur LeerzeilenErste Ausgabe (Connect-MicrosoftTeams) legt das Tabellenformat fest, spätere Objekte werden verschluckt| Format-List bzw. | Out-Null anhängen
Simulation ok, Client wählt noch +49…Teams-Client hat die Regel noch nicht übernommenBis zu 1 h warten, Teams komplett neu starten
Anruf bricht sofort abKeine Voice Route trifft *… (z. B. nur ^\+49)Route mit -NumberPattern '^\*' auf dasselbe Gateway und dieselbe PSTN-Usage anlegen
Starface-Protokoll zeigt *011…, aber nichts passiertSTARFACE behandelt Sterncodes auf der Teams-Leitung nichtKonfiguration der Teams-Leitung in der STARFACE prüfen
Kurzwahl-Idee (nur Durchwahl wählen)Regel für 2–4 Ziffern fängt auch 110/112 abNur auf echten Durchwahlbereich einschränken, z. B. ^([2-9]\d{2})$, nie pauschal \d{2,4}