Retain Meetings, Contacts (Buddylist) and Forwarding information post Cutover Migration to Skype for Business Online

In a Cutover Migration from Skype for Business on-premises or Lync 2013 the following data are Expected to be lost:

  • Contacts cannot be exported, so users will have to repopulate their contact lists manually in Skype for Business Online.
  • Forwarding and Simultaneous ringing will be lost
  • Invitation for the existent meetings (Sent from on-premises Lync/Skype for Business) will need to be resent.

As per the blog https://blogs.technet.microsoft.com/fasttracktips/2017/08/24/skype-online-cutover-migration/

Well that is not the case anymore ; in this blog we will address all three points mentioned above.

Meetings Will be Migrated!:

First The Meetings WILL be Migrated and updated by the MMS service; as long as you have all the MMS requirements met as per this article

https://docs.microsoft.com/en-us/skypeforbusiness/audio-conferencing-in-office-365/setting-up-the-meeting-migration-service-mms

 

Contacts (Buddy list) and Forwarding Information:

I re-wrote a script that was provided before  (Note Credits in Script)  that will Export these information from the UserData to a CSV and HTML file so you can re-add your Buddylist or Forwardings manually.

You will have to export all User data by the following :

# Lync 2010 export using dbimpexp.exe in command line

Dbimpexp.exe /hrxmlfile:c:\temp\userdata.xml /restype:user /sqlserver:SQLserver\instance

# Lync 2013 export using powershell

Export-CsUserData -LegacyFormat -PoolFqdn pool.fqdn -FileName c:\temp\userdata.xml

The Script will use the Path of the Filename specified as the Output Directory

then Use the Following script :

 #--------------------------------------------------------------------------------------------------------------
# Copyright © 2018 Microsoft Corporation. All rights reserved.
#
# THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED “AS IS” WITHOUT
# WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
# LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
# FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR 
# RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
# ======================================================================= 
## Description: Script Excract Buddylist and Forwarding information from the Lync/Skype Userdata
## Mahmoud Badran
## mbadran@microsoft.com
## Credits
#AdamToth- [O365] Exporting Buddy List https://answers.microsoft.com/en-us/profile/cb5754e4-4b8a-49ee-beaf-aab3ba5b59b6 
#Boe Prox - Function to Convert HTML https://gallery.technet.microsoft.com/scriptcenter/Convert-OutoutForCSV-6e552fc6 


param( [string] $ContentFilename = $(Read-Host -prompt "Please enter a file name"))

$ContentFolder = (Get-Item -Path $ContentFilename -Verbose).DirectoryName



[void] [Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.IO.Compression.ZipFile]::ExtractToDirectory($ContentFilename, $ContentFolder)

"Unzip Done..."

[xml]$contact = Get-Content "$ContentFolder\userdata.xml"
$outputfile = $ContentFolder + "\Lync_SfB_Info.csv" 
$output = $contact.HomedResources.homedresource
$resultsarray =@()
$fwdinfo =@()
$tegt=@()

Function Convert-OutputForCSV {
 
 #Requires -Version 3.0
 [cmdletbinding()]
 Param (
 [parameter(ValueFromPipeline)]
 [psobject]$InputObject,
 [parameter()]
 [ValidateSet('Stack','Comma')]
 [string]$OutputPropertyType = 'Stack'
 )
 Begin {
 $PSBoundParameters.GetEnumerator() | ForEach {
 Write-Verbose "$($_)"
 }
 $FirstRun = $True
 }
 Process {
 If ($FirstRun) {
 $OutputOrder = $InputObject.psobject.properties.name
 Write-Verbose "Output Order:`n $($OutputOrder -join ', ' )"
 $FirstRun = $False
 #Get properties to process
 $Properties = Get-Member -InputObject $InputObject -MemberType *Property
 #Get properties that hold a collection
 $Properties_Collection = @(($Properties | Where-Object {
 $_.Definition -match "Collection|\[\]"
 }).Name)
 #Get properties that do not hold a collection
 $Properties_NoCollection = @(($Properties | Where-Object {
 $_.Definition -notmatch "Collection|\[\]"
 }).Name)
 Write-Verbose "Properties Found that have collections:`n $(($Properties_Collection) -join ', ')"
 Write-Verbose "Properties Found that have no collections:`n $(($Properties_NoCollection) -join ', ')"
 }
 
 $InputObject | ForEach {
 $Line = $_
 $stringBuilder = New-Object Text.StringBuilder
 $Null = $stringBuilder.AppendLine("[pscustomobject] @{")

$OutputOrder | ForEach {
 If ($OutputPropertyType -eq 'Stack') {
 $Null = $stringBuilder.AppendLine("`"$($_)`" = `"$(($line.$($_) | Out-String).Trim())`"")
 } ElseIf ($OutputPropertyType -eq "Comma") {
 $Null = $stringBuilder.AppendLine("`"$($_)`" = `"$($line.$($_) -join ', ')`"") 
 }
 }
 $Null = $stringBuilder.AppendLine("}")
 
 Invoke-Expression $stringBuilder.ToString()
 }
 }
 End {}
}

foreach ($user in $output)
{
$contactlist = “”
$contactObject = new-object PSObject
$sipaddress=$user.userathost
$user_contacts=$user.contacts.contact
$fwdinfo = $user.Containers.container.publication.data.routing.preamble.list 
$tegt= $user.Containers.container.publication.data.routing.preamble.list.target

foreach($buddy in $user_contacts)
{$contactlist = $contactlist + $buddy.buddy+”, ”}
$contactObject | add-member -membertype NoteProperty -name “SIP Address” -Value $sipaddress
$contactObject | add-member -membertype NoteProperty -name “Contacts” -Value $contactlist
$contactObject | add-member -membertype NoteProperty -name “FWD” -Value $fwdinfo
$contactObject | add-member -membertype NoteProperty -name “Target” -Value $tegt 
$resultsarray += $contactObject



}

$resultsarray| Convert-OutputForCSV |Export-csv $outputfile -notypeinformation

$outputfileml = $ContentFolder + "\Lync_SfB_Info.html"
$htmlformat = '<title>Table</title>'
$htmlformat += '<style type="text/css">'
$htmlformat += 'BODY{background-color:#663300;color:#FFCC00;font-family:Arial Narrow,sans-serif;font-size:17px;}'
$htmlformat += 'TABLE{border-width: 3px;border-style: solid;border-color: white;border-collapse: collapse;width: 100%;}'
$htmlformat += 'TH{border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:#663333;}'
$htmlformat += 'TD{border-width: 1px;padding: 8px;border-style: solid;border-color: black;background-color:#660033;}'
$htmlformat += '</style>'
$bodyformat = '<h1>Lync/Skype for Business User Contacts and Forwarding Info</h1>'
$resultsarray| Convert-OutputForCSV| ConvertTo-Html -Head $htmlformat -Body $bodyformat | Out-File $outputfileml