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)
- Vorhandene Wählpläne prüfen:
Get-CsTenantDialPlan. Gibt es nurGlobalohne Regeln,DP-Starfaceals Namen lassen. Gibt es schon einen zugewiesenen Plan, dessen Namen eintragen – das Skript hängt die Regel an, statt den Plan zu ersetzen. - Die drei Variablen im Skript anpassen und das Skript ausführen.
- Am Ende muss die Kontrolle
TranslatedNumber : *011997zeigen.
#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
- 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.
- Ausrollen auf alle: erst nach erfolgreichem Test.
- 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
| Symptom | Ursache | Fix |
|---|---|---|
| Skriptausgabe zeigt nur Leerzeilen | Erste 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 übernommen | Bis zu 1 h warten, Teams komplett neu starten |
| Anruf bricht sofort ab | Keine Voice Route trifft *… (z. B. nur ^\+49) | Route mit -NumberPattern '^\*' auf dasselbe Gateway und dieselbe PSTN-Usage anlegen |
Starface-Protokoll zeigt *011…, aber nichts passiert | STARFACE behandelt Sterncodes auf der Teams-Leitung nicht | Konfiguration 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 ab | Nur auf echten Durchwahlbereich einschränken, z. B. ^([2-9]\d{2})$, nie pauschal \d{2,4} |