Move-CSUser 365

Das Commandlet verschiebt Skype for Business Benutzer zwischen Servern und auch Office 365. Es arbeitet aber anders als z.B.: Exchange Mailbox Move-Request. Diese Seite beschreibt die Zusammenhänge und mögliche Fehler und deren Ansätze. Benutzer können per PowerShell oder CSCP zwischen den Welten verschoben werden.

Auslöser

Wie so oft entstand diese Seite aufgrund einer mühsamen Fehlersuche einer Kundensituation, deren Erkenntnisse ich nicht vergessen wollte. Hier war es die Verlagerung eines Benutzers von Skype for Business nach Office 365. Nachdem alle Befehle richtig angegeben wurden, konnte Move-CSUser den Benutzer dennoch nicht umziehen. Auch ein "-Verbose" hat erst mal keine zusätzlichen Informationen geliefert. Ich musste also wohl oder übel wieder Tracen und Debuggen.

Der Normalfall

Wenn alles richtig funktioniert, dann sind die Befehle sehr einfach. Sie bauen eine CSOnline Session auf. Dazu brauchen Sie lokal natürlich das passende Modul.

Windows PowerShell-Modul für Skype for Business Online
https://www.microsoft.com/de-de/download/details.aspx?id=39366

Der einfachste Weg ist folgender:

# Start der Online Session
$session = New-CsOnlineSession
Import-PSSession $session -AllowClobber

Sie können optional natürlich auch gleich die Anmeldenamen mit angeben oder abfragen. Damit unterbinden Sie dann die Rückfrage aber verhindern auch die Nutzung von MFA

# Start der Online Session
$session = New-CsOnlineSession -Credential (get-credential) -verbose
Import-PSSession $session -AllowClobber

Mit Verbose sehen Sie dann auch die Details der Anmeldung

Hier sehen Sie auch den Name der URL. Sie können diese aber auch über $session.computername immer wieder in Erfahrung bringen. Manchmal ist es der PowerShell nicht möglich den richtigen Tenant zu finden. Oder ihr Benutzer ist sogar auf mehrere Tenants berechtigt. Dann hilft die Angabe des TargetTenants

    -OverrideAdminDomain <tenantname>.onmicrosoft.com `

Danach geht es relativ einfach weiter

Verschieben zu Office 365

Einen Benutzer kann ich wie folgt einfach in die Cloud verschieben.

Move-CsUser `
   -Identity sip:user1@uclabor.de `
   -Target sipfed.online.lync.com `
   -HostedMigrationOverrideURL "https://$($$session.ComputerName)/HostedMigration/hostedmigrationservice.svc 

Verschieben eines Benutzers von SfB Online nach On-Prem

Umgekehrt muss ich den lokalen Server als Ziel eingeben

Move-CsUser `
   -Identity sip:user1@uclabor.de `
   -Target fe01.uclabor.de `
   -HostedMigrationOverrideURL https://$($session.ComputerName)/HostedMigration/hostedmigrationservice.svc

Wenn diese Verlagerung aber nicht funktioniert, dann sind in der Regel zwei Fehler möglich.

AADConnect - Einstellung

Eigentlich sollte es jedem klar sein, dass für die Verlagerung eines Benutzers einer lokalen Skype for Business Installation in die Cloud auch der AzureADConnect nicht nur installiert und betrieben wird, sondern auch die Skype for Business Felder synchronisiert werden.

Oft ist es nicht mal Absicht, dass die Lync/Skype for Business Attribute nicht repliziert werden. Gerade beim Neuaufbau von Office 365 ohne lokale Installationen hat das lokale Active Directory noch gar nicht die Schemaerweiterungen und Das AADConnect-Setup bietet daher diese Konfiguration gar nicht an. Wenn dann später doch ein Skype for Business Server lokal installiert und damit das Schema erweitert wird, wird AADConnect einfach vergessen.

 Das können Sie natürlich mit einer PowerShell gegen Skype for Business Online auch einfach testen. Sie sollten die Benutzer in der Cloud entsprechend als Objekte mit einem Verweis nach "On Premises" finden. Sie können dies einfach per Skype for Business Online PowerShell ermitteln.

# Start der Online Session
$session = New-CsOnlineSession
Import-PSSession $session -AllowClobber

Get-CsOnlineUser user1@uclabor.de | fl onpre*

OnPremHideFromAddressLists : False
OnPremHostingProvider : SRV:
OnPremOptionFlags : 385
OnPremEnterpriseVoiceEnabled : True
OnPremSIPEnabled : True
OnPremSipAddress : sip:user1@uclabor.de
OnPremLineURI :
OnPremLineURIManuallySet : False

# Anzeige der Liste
Get-CsOnlineUser | ft sipaddress,OnPremSIPEnabled,OnPremHostingProvider
SipAddress                                   OnPremSIPEnabled OnPremHostingProvider
----------                                   ---------------- ---------------------
sip:user1@uclabor.de                         True             SRV:
sip:sfbonline1@uclabor.de                    True             sipfed.online.lync.com
sip:cloudonlylicense@uclabor.de

In meinem Tenant gibt es also einen user1, der OnPremises ist, einen User "sfbonline1", der in der Cloud ist und einen "cloudonlylicense", der in der Cloud ist aber kein passenden Objekte On--Premises hat oder eben der User nicht repliziert wurde. Die Tatsache aber, dass "OnPremHostingProvider" gepflegt ist, ist ein Zeichen, dass zumindest irgendwann einmal ein AADConnect die Skype for Business Fehler repliziert hat.

AzureADConnect sorgt dafür, dass einige Felder im AzureAD anhand der lokalen "msrtc"-AD-Felder gepflegt werden. Wenn diese Felder in Office 365 nicht vorhanden sind, dann schlägt der Move mit folgender Meldung fehlt

Move-CsUser `
   -Identity user1@uclabor.de 
`  -target sipfed.online.lync.com `
   -Credential $cred `
   -Verbose

VERBOSE: CN=Lync-Test,OU=users,DC=uclabor,DC=de
Confirm
Move-CsUser
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): Y
VERBOSE: Validating parameters for move operation.
VERBOSE: Calculating new server information for user [sipfed.online.lync.com].
VERBOSE: Moving user [sip:user1@uclabor.de] across deployments.
VERBOSE: Initializing source external move endpoint.
VERBOSE: Creating target external move endpoint.
VERBOSE: Auto discovering hosted migration service URL based on discovery service URL
[https://webdir2e.online.lync.com/Autodiscover/AutodiscoverService.svc/root] and user sip address
[sip:user1@uclabor.de]
VERBOSE: Found auto discover URL [https://admin2e.online.lync.com/HostedMigration/HostedMigrationService.svc].
VERBOSE: Retrieving web ticket URL.
VERBOSE: Retrieving live id token.
VERBOSE: Initializing source external move endpoint.
VERBOSE: Validating user [sip:user1@uclabor.de] online, for on premises to online move.
Move-CsUser : HostedMigration fault: Error=(506), Description=(The user could not be moved because there appears to be a
problem with this user account. Please verify the attribute settings on the account and then try again.)
At line:1 char:1
+ Move-CsUser -Identity user1@uclabor.de -target sipfed.online ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (CN=Lync-Test\, ...uclabor,DC=com:OCSADUser) [Move-CsUser], MoveUserException
    + FullyQualifiedErrorId : MoveError,Microsoft.Rtc.Management.AD.Cmdlets.MoveOcsUserCmdlet

Die Ergebnisse aus diesem Vorgang befinden sich hier: "C:\Users\admin\AppData\Local\Temp\MoveResults-12345678-abcd-1234-5678-1234567890ab.csv".
PS C:\>

Ein anderer Fehler mit oft der gleichen Ursache ist

VERBOSE: Validating user [sip:user2@uclabor.de] online, for on premises to online move.
move-csuser : Index was outside the bounds of the array.

Auch hier fehlen meist die entsprechenden Felder im AzureAD.

HTTP Upload statt Download

In der obigen Fehlermeldung sehen Sie schon, dass Move-CSUser ein Commandlet ist, welches Sie On Premises ausführen und welches sich dann mit einem Office 365-WebService verbindet. Die genaue URL hängt davon ab, auf welcher Umgebung ihr Tenant gehostet ist. Beim "New-CSOnlineSession" wird ihnen das auch angezeigt und Move-CSUser findet die Adresse auch heraus. Folgende Adressen habe ich selbst schon gesehen. Sie können ihre Adresse aus "$session.computername" erhalten, die Sie beim New-CSOnlineSession angegeben haben.

https://admin2e.online.lync.com/HostedMigration/HostedMigrationService.svc
https://admin2a.online.lync.com/HostedMigration/HostedMigrationService.svc
https://admin1e.online.lync.com/HostedMigration/HostedMigrationService.svc
https://admin0a.online.lync.com/HostedMigration/HostedMigrationService.svc

Damit ist aber auch klar, dass die Aktionen diesmal die lokale PowerShell durchführt. Es ist ja ein "Move-CSUser" und kein "Move-CSOnlineUser". Das System, auf dem mit Move-CSUser die Umstellung und Übertragung der Daten erfolgt, muss Zugriff auf die Cloud haben. Und hier kommen dann wieder Firewalls und Proxy-Server gerne mal in die Quere

Bei einer Umgebung habe ich Fiddler zur Fehlersuche gestartet und der Fehler war weg. Sobald ich aber Fiddler wieder deaktiviert habe, war der Fehler wieder da. Also allein der Umweg über Fiddler als Debugger hat den Request so verändert, dass die Firewall wieder zufrieden war. Es hat etwas gedauert, bis wir den Filter auf der Firewall angepasst haben.

Denn Move-CSUser spricht nicht nur mit dem Skype for Business Online URL, sondern durchaus noch mit anderen URLs. Leider sehen Sie dies nicht mit "-verbose"

#

Result Protocol Host URL Body Caching Content-Type

1

200

HTTP

clientconfig.microsoftonline-p.net

/fplist.xml

3,631

private

text/xml; charset=utf-8

4

200

HTTPS

admin1e.online.lync.com

/WebTicket/WebTicketService.svc/Mex

13,108

private

text/xml; charset=UTF-8

8

200

HTTPS

login.microsoftonline.com

/getuserrealm.srf?login=admin@uclabor.com&xml=1

2,225

private

text/xml; charset=utf-8

11

200

HTTPS

adfs.uclabor.de

/adfs/services/trust/mex

36,523

application/soap+xml; charset=utf-8

13

200

HTTPS

adfs.uclabor.de

/adfs/services/trust/2005/usernamemixed

6,538

application/soap+xml; charset=utf-8

15

200

HTTPS

login.microsoftonline.com

/rst2.srf

12,723

private

application/soap+xml; charset=utf-8

16

200

HTTPS

admin1e.online.lync.com

/WebTicket/WebTicketService.svc/WsFed_bearer?s=ad

2,402

private

text/xml; charset=utf-8

17

200

HTTPS

admin1e.online.lync.com

/WebTicket/WebTicketService.svc/WsFed_bearer?s=ad

2,404

private

text/xml; charset=utf-8

18

500

HTTPS

admin1e.online.lync.com

/HostedMigration/hostedmigrationservice.svc/Webticket_bearer?s=ad

1,012

private

text/xml; charset=utf-8

Am Anfang holt er sich von http://clientconfig.microsoftonline-p.net/fplist.xml wohl die Liste der Authentication Provider um dann über ADFS ein Ticket zu erhalten. Aber am Ende hat die PowerShell doch einen 500er Fehler geliefert:

Bei einer erfolgreichen Migration werden natürlich viel mehr Daten übertragen. Maßgeblich ist hier aber immer die lokale PowerShell, die auch nicht einmal direkt auf dem Skype for Business Server ausgeführt werden muss.

Berechtigungen in Office 365

Natürlich kann nicht jeder einfach mal einen User in die Cloud verschieben. Entsprechenden Berechtigungen sollten Sie schon haben, damit ihnen dieser Fehler erspart bleibt:

Move-CsUser : HostedMigration fault: Error=(0), Description=(You do not appear to be authorized to move this user.
Please verify the credentials you are running this command under and then try again.)

Solution – Minimum required permissions
Clearly the Skype for Business Admin role is not sufficient to perform this operation. At a minimum, both the Skype for Business Admin Role and the User Management Role are required to perform this operation. As well the single Global Administrator Role will obviously have the appropriate permissions to do this. I’m hoping Microsoft will consider changing this with larger organizations in mind given the User Management Role allows for things like password resets which may not be desirable for certain team. If you consider Exchange Online, all that is required to enable unified messaging (voicemail) for a Skype for Business user is the UM Management Role. The User Management Role is not required for this operation.
Quelle: Permissions Required to Move Users to Skype for Business Online
http://www.ucguys.com/2017/07/permissions-required-to-move-users-to-skype-for-business-online.html

Andere Fehler waren

Move-CsUser : Failed to connect live id servers. Make sure proxy is enabled or machine has network connection to live id servers.

Meeting URLs und Konferenzeinwahl

Wenn Sie Benutzer zwischen Server in der gleichen Skype for Business Umgebung verlagern, dann ist das für den Anwender ohne merkliche Auswirkungen. Wird der Benutzer aber zwischen On-Premises und Office 365 verlagert, dann ändern sich zwangsweise bestimmte Einträge für den Anwender. Es sind nämlich zwei unterschiedliche Topologien mit eigenem Namensraum und Rufnummernbereich

  • MeetingURL
    Die MeetingURL enthält einen Hostnamen wie z.B. "meet.lync.com" oder "meet.firmenname.tld", der sich vom der Topologie des Anwenders ableitet. Wird der Anwender zwischen zwei Welten umgezogen, sind die alten Meeting-URLs nicht mehr gültig. Alle schon ausgesprochenen Meeting-Einladungen in der Zukunft sind davon betroffen
  • Konferenz Dialin-Nummer
    Auch die Rufnummer zur Einwahl per Telefon ändert ich mit dem Umzug des Anwenders, da die Rufnummern ebenfalls an die Plattform gebunden sind.

Der Anwender kann also sofort wieder weiter arbeiten aber seine bestehenden Meetings muss er aktualisieren. von Microsoft gibt es dazu ein Tool, welches jeder Anwender selbst aufrufen muss. Es verbindet sich mit dem Postfach des Anwenders und sendet für alle zukünftigen Termine eine Aktualisierung auf den Weg

Skype for Business (Lync) Meeting Update Tool
https://support.office.com/de-de/article/Skype-for-Business-Lync-Meeting-Update-Tool-2b525fe6-ed0f-4331-b533-c31546fcf4d4

Das ist natürlich nur bedingt benutzerfreundlich. Allerdings "merkt" Exchange erst einmal nichts von dem Skype-Umzug und der Skype Server konnte lange Zeit auch nicht auf die Exchange Umgebung zugreifen um das Update stellvertretend für den Benutzers zu machen. Das ist zumindest in Office 365 mittlerweile anders, wenn Der Benutzer die Dienste Skype und Exchange beide aus der Cloud bezieht.

Standardmäßig ist die Migration von Meetings eingeschaltet

PS C:\> Get-CsTenantMigrationConfiguration

Identity                           : Global
MeetingMigrationEnabled            : True
ACPMeetingMigrationTriggerEnabled  : True
MeetingMigrationSourceMeetingTypes : Sfb
MeetingMigrationTargetMeetingTypes : Current

Welche Migrationen bereits gelaufen sind, können Sie wie folgt ermitteln

PS C:\> Get-CsMeetingMigrationStatus | ft *date,state,*meeting*,lastmessage

CreateDate          ModifiedDate        State     TotalMeetings SucceededMeetings FailedMeetings LastMessage
----------          ------------        -----     ------------- ----------------- -------------- -----------
05.02.2018 08:55:47 05.02.2018 10:38:54 Succeeded             0                 0              0 Meeting migration completed.
09.01.2018 08:09:44 09.01.2018 10:34:54 Succeeded             0                 0              0 Meeting migration completed.
11.04.2018 20:33:20 11.04.2018 23:07:37 Succeeded             0                 0              0 Meeting migration completed.
16.04.2018 14:57:45 16.04.2018 16:28:37 Succeeded             0                 0              0 Meeting migration completed.
20.03.2018 11:37:33 20.03.2018 13:34:12 Succeeded             0                 0              0 Meeting migration completed.

Der Prozess selbst läuft komplett im Hintergrund ab. Sie könne ihn aber auch für ihren Tenant deaktivieren.

Set-CsTenantMigrationConfiguration -MeetingMigrationEnabled $false 

Weitere Links