Office365

GoDaddy Office365 to Microsoft Office365 Migration- Part 5

Gathering details from source tenant

As part of the assessment phase, Its required to collect the details from source tenant. Here is a quick guide on how we can export the required details from source tenant quickly.

Azure ActiveDirectory

  • User Objects
    • Use Get-AzuerADUser for exporting User Details
    • Use Get-AzureADUserManager for exporting user manager
    • Use Get-AzureADUserThumbnails for exporting user thumbnails

Here is a sample script which can be used for exporting the user details. As a prerequisite, Please install AzureAD module before executing the script.

Connect-AzureAD
If ((Test-Path C:\GoDaddyTenant\Export\AADUsers\Thumbs) -like  "False") {New-Item -ItemType Directory -Path "C:\GoDaddyTenant\Export\AADUsers\Thumbs"}
Get-AzureADUser -All $True |Export-Csv -Path "C:\GoDaddyTenant\Export\AADUsers\AllUsers.CSV"
[Array] $UserArray = Import-Csv "C:\GoDaddyTenant\Export\AADUsers\AllUsers.CSV"
[string] $UserManagerFile = "C:\GoDaddyTenant\Export\AADUsers\UserManager.CSV"
$Len = $UserArray.Count
For ($i = 0; $i -lt $Len ; $i++)
    {
    $oID = $UserArray.ObjectId[$i]
    Get-AzureADUserManager -ObjectId $oID |Select-Object @{Label="User"; Expression={$UserArray.UserPrincipalName[$i]}}, @{Label="Manager"; Expression={$_.UserPrincipalName}} |Export-Csv -LiteralPath $UserManagerFile -Append
    IF ($UserArray[$i].UserType -eq "Member")
        {
        [string] $FN = $UserArray[$i].UserPrincipalName
        [string] $FP = "C:\GoDaddyTenant\Export\AADUsers\Thumbs"
        Get-AzureADUserThumbnailPhoto -ObjectId $UserArray[$i].ObjectId -FilePath $FP -FileName $FN -ErrorAction SilentlyContinue
        }
    }
  • Groups and Group Membership
    • User Get-AzureADGroup for exporting groups
    • Use Get-AzureADGroupMember for exporting group members
    • Use Get-AzureADGroupOwner for exporting group owners

Here is a sample script which can be used for exporting the group details. As a prerequisite, Please install AzureAD module before executing the script.

Connect-AzureAD
If ((Test-Path C:\GoDaddyTenant\Export\AADGroups) -like  "False") {New-Item -ItemType Directory -Path "C:\GoDaddyTenant\Export\AADGroups"}
Get-AzureADGroup -All $True |Export-Csv -Path "C:\GoDaddyTenant\Export\AADGroups\AllGroups.CSV"
[Array] $GroupArray = Import-Csv "C:\GoDaddyTenant\Export\AADGroups\AllGroups.CSV"
[string] $GroupOwnerShip = "C:\GoDaddyTenant\Export\AADGroups\GroupOwnership.csv"
$Len = $GroupArray.Count
For ($i = 0; $i -lt $Len ; $i++)
    {
    $oID = $GroupArray.ObjectId[$i]
    [string] $TrimmedGroupName = $GroupArray[$i].DisplayName.Trim()
    [string] $FP = "C:\GoDaddyTenant\Export\AADGroups\"+$TrimmedGroupName+"_"+$GroupArray.ObjectId[$i]+".csv"
    $FP
    Get-AzureADGroupMember -ObjectId $GroupArray[$i].ObjectId |Export-Csv -LiteralPath $FP
    Get-AzureADGroupOwner -ObjectId $GroupArray[$i].ObjectId |Select-Object  @{Label="GroupName"; Expression={$GroupArray.DisplayName[$i]}}, UserPrincipalName | Export-Csv -LiteralPath $GroupOwnerShip -Append
    }
  • Devices
    • Get-AzureADDevice to export Azure AD registered / AAD joined devices

Here is a sample script which can be used for exporting the device details. As a prerequisite, Please install AzureAD module before executing the oneliner.

Get-AzureADDevice -All $true |Export-Csv -Path "C:\GoDaddyTenant\Export\AADDevices\AllDevices.csv"

Exchange Online

  • Use Get-Mailbox for exporting mailbox details
  • Use Get-EXORecipient for exporting all recipients
  • Use Get-MailContact for exporting all mail contacts
  • Use Get-Group for exporting all distribution groups
  • Use Get-UnifiedGroup for exporting all unified groups
  • Use Get-DynamicDistributionGroup for exporting Dynamic Distribution Groups

Here is a sample script which can be used for exporting the user details. As a prerequisite, Please install ExchangeOnline module before executing the script.

Connect-ExchangeOnline
If ((Test-Path C:\GoDaddyTenant\Export\ExchangeOnline) -like  "False") {New-Item -ItemType Directory -Path "C:\GoDaddyTenant\Export\ExchangeOnline"}
Get-Mailbox -ResultSize Unlimited|Export-Csv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\AllMailboxes.csv"
Get-EXORecipient -ResultSize Unlimited |Export-CSv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\AllRecipients.csv"
Get-MailContact -ResultSize Unlimited |Export-CSv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\AllContacts.csv"
Get-Group -RecipientTypeDetails MailUniversalDistributionGroup, MailUniversalSecurityGroup |Export-CSv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\AllDistributionGroups.csv"
Get-UnifiedGroup -IncludeAllProperties -ResultSize Unlimited|Export-CSv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\AllUnifiedGroups.csv"
Get-DynamicDistributionGroup -ResultSize Unlimited |Export-CSv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\AllDynamicDistributionGroups.csv"
[Array] $MailboxArray = Import-Csv "C:\GoDaddyTenant\Export\ExchangeOnline\AllMailboxes.csv"
[string] $MailboxUsageStatistics = "C:\GoDaddyTenant\Export\ExchangeOnline\MailboxUsageStatistics.csv"
$Len = $MailboxArray.Count
For ($i = 0; $i -lt $Len ; $i++)
    {
    [string] $MailboxFolderStatistics = "C:\GoDaddyTenant\Export\ExchangeOnline\"+$MailboxArray.UserPrincipalName[$i]+"_MailboxUsageStatistics.CSV"
    Get-EXOMailboxStatistics -Identity $MailboxArray.UserPrincipalName[$i] |Export-Csv -LiteralPath $MailboxUsageStatistics -Append
    Get-EXOMailboxFolderStatistics -Identity $MailboxArray.UserPrincipalName[$i] |Export-Csv -LiteralPath $MailboxFolderStatistics
    }
Get-AcceptedDomain |Export-CSv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\ExchangeOnlineConfiguration_AcceptedDomains.csv"
Get-TransportRule -ResultSize Unlimited |Export-CSv -Path "C:\GoDaddyTenant\Export\ExchangeOnline\ExchangeOnlineConfiguration_AllTransportRules.csv"

Teams

  • Use Get-Teams for exporting Teams details
  • Use Get-TeamUser for exporting Team Users
  • Use Get-TeamChannel for exporting Team Channels
  • Use Get-TeamChannelUser for exporting private channel users

Here is a sample script which can be used for exporting the user details. As a prerequisite, Please install MicrosoftTeams module before executing the script.

Connect-MicrosoftTeams
[array] $TeamChannelsDetails = $()
If ((Test-Path C:\GoDaddyTenant\Export\Teams\Permissions) -like  "False") {New-Item -ItemType Directory -Path "C:\GoDaddyTenant\Export\Teams\Permissions"}
$TeamsDetails = Get-Team
$TeamsDetails |Export-Csv -path "C:\GoDaddyTenant\Export\Teams\TeamsDetails.csv"
$TeamsCount = $TeamsDetails.Count
For ($i=0; $i -lt $TeamsCount; $i++)
    {
    [int] $tempCount = $i+1
    [array] $tn = $TeamsDetails[$i]
    Write-Host "Processing $tempcount out of $TeamsCount Teams... Now processing" $Tn.DisplayName -ForegroundColor DarkYellow
    [string] $PermissionGID = "C:\GoDaddyTenant\Export\Teams\Permissions\TeamPermission_"+$TeamsDetails.GroupID[$i]+".csv" 
    [string] $PermissionFriendlyName = "C:\GoDaddyTenant\Export\Teams\TeamPermission_"+$tn.displayname+".csv"
    $TeamChannelsDetails += Get-TeamChannel -GroupId $TeamsDetails[$i].GroupID |Select-Object @{Label="TeamName"; Expression={$tn.DisplayName}}, @{Label="TeamGroupID"; Expression={$tn.groupid}}, ID, DisplayName, MembershipType, Description
    $TeamsUserPermission = Get-TeamUser -GroupId $TeamsDetails[$i].GroupID |Select-Object User, UserID, Name, Role, @{Label="MailID"; Expression={$_.User}}
    IF ($TeamsUserPermission.Role.Contains("guest") -eq "True")
        {
        Write-Host "Guest User Detected in Team Permission"
        $TLenght = $TeamsUserPermission.Length
        For ($j=0; $j -lt $TLenght; $j++)
            {
            IF ($TeamsUserPermission.Role[$j] -like "Guest")
                {
                $extractedMail = $TeamsUserPermission.user[$j].Split("#")[0]
                $indexofdash = $extractedMail.LastIndexOf("_")
                $TeamsUserPermission[$j].MailID = $extractedMail.Remove($indexofdash,1).Insert($indexofdash,"@")
                }
            }
        }
    $TeamsUserPermission | Export-Csv $PermissionFriendlyName
    Get-TeamUser -GroupId $TeamsDetails[$i].GroupID |Export-Csv $PermissionGID
    Write-Host Checking for Private Channels -ForegroundColor Red
    $TeamPriviateChannels = Get-TeamChannel -GroupId $tn.GroupID -MembershipType "Private"
    If ($TeamPriviateChannels.Count -gt 0)
        {
        Write-Host $TeamPriviateChannels.Count "Priviate Channels Identified" -ForegroundColor Magenta
            Foreach ($PriviateChannel in $TeamPriviateChannels)
                {
                Write-Host "Exporting Priviate Channel Permission - " $PriviateChannel.DisplayName -ForegroundColor DarkYellow
                [string] $TeamPriviateChannelPermissionFile = "C:\GoDaddyTenant\Export\Teams\TeamsPrivateChannelPermission_"+$tn.DisplayName+"_"+$PriviateChannel.DisplayName+".csv"
                [string] $TeamPriviateChannelPermissionFileGID = "C:\GoDaddyTenant\Export\Teams\Permissions\TeamsPrivateChannelPermission_"+$tn.GroupID+"_"+$PriviateChannel.DisplayName+".csv"
                [array] $priviateChannelPermission = Get-TeamChannelUser  -GroupId $TeamsDetails[$i].GroupID -DisplayName $PriviateChannel.DisplayName |Select-Object User, UserID, Name, Role, @{Label="MailID"; Expression={$_.User}}
                IF ($priviateChannelPermission.Role.Contains("Guest") -eq "True")
                    {
                    Write-Host "Guest User Detected"
                    [int] $PCPCount = $priviateChannelPermission.length
                    For ($k=0; $k -lt $PCPCount; $k++)
                        {
                        IF ($priviateChannelPermission.Role[$k] -like "Guest")
                            {
                            $extractedUname = $priviateChannelPermission.user[$k].Split("#")[0]
                            $indexofdash = $extracteduname.LastIndexOf("_")
                            $priviateChannelPermission[$k].MailID = $extractedUname.Remove($indexofdash,1).Insert($indexofdash,"@")
                            }
                       }
                    }
                Else
                    {
                    Write-Host "Guest User Not Detected"
                    }
                $priviateChannelPermission |Export-CSV $TeamPriviateChannelPermissionFile
                Get-TeamChannelUser  -GroupId $TeamsDetails[$i].GroupID -DisplayName $PriviateChannel.DisplayName |Export-Csv $TeamPriviateChannelPermissionFileGID 
                }
        }
    Else
        {
        Write-Host "No Priviate Group Identified" -ForegroundColor Green
        }
    }
Write-Host "Exiting For Loop" -BackgroundColor White -ForegroundColor Gray
$TeamChannelsDetails |Export-Csv "C:\GoDaddyTenant\Export\Teams\TeamChannelDetails.csv"

SharePoint Online

  • Use Get-SPOSite for exporting SharePoint Online sites

Get started with the SharePoint Online Management Shell | Microsoft Docs

As a prerequisite, Please install SharePointOnline module before executing the script.

Posted by Shabarinath in Office365Migration, 0 comments

GoDaddy Office365 to Microsoft Office365 Migration- Part 4

Migration Tools

Office365 Tenant to Tenant migration is a supported scenarios for most of the leading migration tools.

Third Party Paid Tools

Quest - On Demand Migration

Code Two - Office365 Migration

BitTitan - MigrationWiz

Cloudiway - Migration between Office365 Tenants

BinaryTree - Power365 Migration

I have listed few of the leading tools available for a Cross tenant migration. However, each tool needs to be evaluated specifically with the requirement. The capability of each tool vary and sometimes needs proper evaluation to confirm which one suits your requirement.

Free Tools

Not every organization can afford the third party tools, especially smaller companies. Few of the third party tools needs a minimum user count for them to consider. Lets look at the different options available within Microsoft which are offered without any additional cost.

Mover.io - Acquired by Microsoft in 2019 and now one of the key tool to help with SharePoint migration

Cross Tenant Mailbox Migration - Capable of migrating mailboxes from one tenant to another

Backups and Restore - Manually or using scripts/native tools

If the migration needs to be done using Free Tools, Its also important to have

  • Experts on Mover and Cross Tenant Migrator
  • Experts on PowerShell as half of the activities needs to be scripted
  • Good planning on sequencing multiple activities which needs to be moving in parallel

Third Party tools can provide a single console for all different migration activates happening in parallel and help to properly sequence the activities.

Posted by Shabarinath in Office365Migration, 0 comments

GoDaddy Office365 to Microsoft Office365 Migration- Part 3

Planning

Once assessment phase is over, Its the time for Migration to plan on how the migration should be executed.

The key points to be answered here is

  • What all services needs to be migrated?
  • What all data needs to be migrated?
  • How data needs to be migrated?
  • Is it going to be a cut over migrating or a staged migration with co-existence?

Service migration is comparatively easy as its only the configurations to be migrated. For example, if the GoDaddy Office365 tenant has configured to use Teams, Teams as a service needs to be configured and made available to the end users for chat, calls as well as collaboration platform.

Data migration is more complex. Data needs to be migrated from Source to the Target Office365 tenant. Beyond that, Data should be made available on the same location from the end user perspective to ensure that user experience is good. For example, if the Finance team is using a private channel in teams and has a SharePoint storage used as document library, Users expect the same document library available in teams once they start using the new Office365 environment.

The next point is on how the data needs to be migrated. Multiple options are available to migrate the data. Third part tools offer much more flexibility and more coverage with an additional cost overhead. Custom Scripts and free tools are available from Microsoft if there is a budget constrain to spend on third party tools, however has lesser flexibility and coverage. If no data transfer is required or end users can take care of their own data backup/restore, the service migration is going to be a straight cutover - however user experience will not be that good and has a risk that some data can get missed.

The final point is on the migration approach. Cut over migration is much more straight approach where the service will be migrated along with the data on a prescheduled cutover window. During the cutover window, services will be unavailable and once done, Users can access their services as well as data from the new Office365 tenant. Another approach is to perform migration in multiple batches, keeping both environment active. Once all users are migrated to the new environment, GoDaddy environment can be deleted. This require co-existence, where a partial set of users will be on the target tenant and will be using services from the target tenant once users are migrated.

Migration strategy is purely depending on the total number of users to be migrated and the volume of data to be migrated. I suggest that if the environment has more than 500 users, Staged migration will be better. If the users are less than 100, Definitely go for a cutover migration.

Lets make a plan for a small environment with less than 50 users and see how we can do a cutover migration with minimal downtime in the next part.

Posted by Shabarinath in Office365Migration, 0 comments

GoDaddy Office365 to Microsoft Office365 Migration- Part 2

Initial Assessment

This should be the starting point for Migration Team.

On a high level, Migration team should have clarity on what all needs to be migrated and what volume of data needs to be migrated. The different segments and the respective areas are listed below.

Azure AD

  1. User Objects
  2. Groups and Group Memberships
  3. Azure AD Register Devices
  4. Azure AD Joined Devices
  5. Policies on Password expiry, Lockout, MFA etc
  6. External Identities
  7. Enterprise Applications using Azure AD for authentication
  8. External Applications using Azure AD for authentication
  9. On-premise AD Sync

Exchange Online

  1. User Mailboxes along with SMTP domains used
  2. Any delegation on user mailbox
  3. Shared Mailboxes along with SMTP domains used
  4. Shared Mailbox Access and Send As Access
  5. Resource Mailboxes
  6. M365 Groups with membership details
  7. Distribution Groups / Security Groups with membership details
  8. Any Application Integrations
  9. Mailbox size of User Mailboxes as well as Shared Mailboxes
  10. Policies specific to email address
  11. Transport Rules
  12. Accepted Domains
  13. Inbound and Outbound email routing
  14. Mx Records

SharePoint Online

  1. SharePoint Sites with URLs and Size
  2. OneDrive for Business URLs and Size

Teams

  1. Teams with membership details
  2. Team Channels on each Team
  3. Private Team Channels with membership details
  4. SharePoint URL for backend SharePoint document library - For Teams as well as each private channels
  5. Any additional applications used within Teams channels

DNS

  1. How public DNS is hosted
  2. Who can update the DNS records

This is the minimum list and team can expand further.

Once the assessment phase is over, We can move on to the planning phase.

Posted by Shabarinath in Office365Migration, 0 comments

GoDaddy Office365 to Microsoft Office365 Migration- Part 1

Is it possible to migrate?

One of my friend was asking if its possible for migrate Office365 services availed from their hosting provider - GoDaddy to a direct Microsoft Office365 tenant. Since I had an opportunity to work on multiple Office365 migration projects including cross tenant migration, I thought of writing a series on how to migrate from one tenant to another, with minimal downtime. Most importantly, How to migrate from one tenant to another without using paid tools.

An Overview on Office365 Service

Office365 Service Includes a wide spectrum of services and is rapidly expanding. In this context of migration, lets differentiate the services into two segments. Services which doesn't have any user data and services which has user data. Services without user data is comparatively easy to migrate as its just the configuration to be migrated. End users can avail the service from the new tenant as if moving from one taxi to another. However, services with user data is different as the data is important as moving the service and the data should be available in the new tenant for the user to user once the service is getting migrated. Its like travelling on a connected flight, where our baggage will also get moved as we move from one flight to another. And at the destination, We expect that the baggage will be ready to collect at the pickup point to resume the journey.

The key services in Office365 which has user data are listed below.

  1. Azure Active Directory - Holding identities, groups etc
  2. Exchange Online - Emails
  3. SharePoint Online - SharePoint Sites and document libraries
  4. Microsoft Teams - Collaboration System with SharePoint and Exchange Online as the key data storage location

I will be detailing on each of these section in the upcoming posts. With an objective of having the critical data migrated to a new tenant, You should be in a position to handle at least these four components to make the migration successful.

Defining Migration

Migration can be defined as the process of moving from one environment to another for a reason. As part of the initial assessment, The project team involved in migration will definitely look at the data to be migrated if any. Services which are getting migrated will resume from the new environment for sure. The question is - Is that really enough? From an end user stand point, Migration experience will be great only if the migration team can give everything as is. Be it an email, SharePoint document, teams channel or even an item kept of Outlook Draft folder for sending at a later stage. The data laying at different places from Source Tenant needs to be migrated to the Destination tenant. Just migrating to the new environment is not enough, it should should be available to users at the same location they used to access earlier. To be more specific, if the users are accessing a document library through teams channel which has multiple documents with different level of access restrictions, The destination tenant also should have the same teams channel, with all the documents and their respective access restrictions. Instead, If the data is only getting migrated to a different location without metadata and asking users to copy the data back will not provide a good user experience.

Is it possible to migrate from one Office365 tenant to another with out using any third-party paid tools?

My answer to that question is a partial YES.

When I say partially yes - The fact is that we have options to migrate the data to certain extend. However, some other data can be migrated but cannot be restored to the same location or make it available on the same interface in the exact way it was on the source tenant. However, the most critical user data of any organization is Email and SharePoint document library - which can be moved without loosing data or user experience.

Posted by Shabarinath in Office365Migration