Migrate your Active Directory Users across tenants

Featured image

Many organisations use Hybrid environments to store their information. With the help of Azure AD Sync (also known as Azure AD Connect), they synchronize their user accounts, groups, and credentials from an on-premises Active Directory (AD) instance to Azure AD.

In current world, with the verge of mergers and acquisitions around the corner, it is vital to frame a mechanism to provision these on-premises Active Directory entities to the Target Environment.

Apps4.Pro Migration Manager which has been a key player in Migration of the Microsoft Workloads has figured a way to get the Key Active Directory entities(Users, Groups & Organizational units) provisioned via PowerShell scripts without the need of a TRUSTED NETWORK relationship.

In this BLOG we will find how to migrate the Active Directory Source Users from one on-premises environment to another in a jiffy with 2 simple steps.

Step 1 : Export the Active Directory Users from your Source Tenant

Step 2 : Import them to the Target Tenant

The Script exports the User Principal Name and Password along with the below details which gives the users the luxury to continue to use the same UPN and Password in the Migrated Environment too.

  • User Name
  • User Principal Name
  • Description
  • Display Name
  • Distinguished Name
  • Domain Name
  • Password along with properties
  •   PasswordNeverExpires
      PasswordNotRequired
      CannotChangePassword
  • Department
  • Country
  • Address
  • Telephone Number
  • Account Expiration Date
  • CodePage
  • Company
  • Division
  • Home Phone
  • Manager
  • memberOf
  • physicalDelivery OfficeName
  • postalCode
  • State
  • City
  • Street
  • Title
  • UserWorkstations
  • SmartcardLogon Required

Let’s get started !

Pre-requisites : Please install the Microsoft Graph PowerShell and the required modules before running this script.

All you need to do is :

  1. Execute the below scripts by feeding in
    • Path to the CSV to import / export the users
    • Fully qualified Domain Name
  2. Sign-in as Domain Admin / Enterprise Admin

Script to Export Active Directory Users

You can download the PowerShell script from location : https://cdn.apps4.pro/scripts/export-active-directory-users.ps1


function Export-UsersList
{  
     param (  
           $ExportPath,
           $FQDN
           )  
    process{
                #Check if Required Policy, Packages, Modules are Available
                [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
 
                $policy = Get-ExecutionPolicy
                If($policy -ne "RemoteSigned")
                {
                Set-ExecutionPolicy RemoteSigned -Force
                }
 
                $NuGet =  Get-PackageProvider -Name NuGet -Force
                IF($NuGet -eq $null)
                {
                Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
                }
                
                $ADPowerShell = Get-Module -Name DSInternals
                 if($ADPowerShell -eq $null)
                 {
                    #Install the module
                    Install-Module -Name DSInternals -RequiredVersion 4.7
                 }

                #Import ActiveDirectory, DSinternal Modules
                Import-Module -Name DSInternals
                Import-Module -Name ActiveDirectory

                #Connect Domain with username, password
                $credential = Get-Credential              

                
                $domainDN = (Get-ADDomain).DistinguishedName
                $domainFQDN = (Get-ADDomain).InfrastructureMaster
                $DCName = (Get-ADDomain).Name
                
                #Get All Users
                $Users = Get-ADUser -Filter * -Properties * -ResultSetSize $null
                $UsersList = @()

                #Loop users to export user details
                 foreach($user in $Users)
                    {
                            Write-Progress -Activity "ActivityName" -Status "Exporing User $($user.sAMAccountName)"
                            $passwordHash = Get-ADReplAccount -SamAccountName $user.sAMAccountName -Server $domainFQDN -Credential $credential
                            
                            #get user Url
                            $Url = '';
                            foreach ($value in $user.url)
                            {
                               $Url  += $value+","
                            }
                           
                            $Url = $Url -replace '.$'
                            
                            #Get user email Address
                            $emailAddress = '';

                            foreach ($email in $user.EmailAddress)
                            {
                               $emailAddress  += $email+","
                            }

                            $emailAddress = $emailAddress -replace '.$'

                            #Get user Password Hash
                            $NTHash
                            if($passwordHash.NTHash -ne $null)
                            {
                                $NTHash = [System.BitConverter]::ToString($passwordHash.NTHash) -replace '-', ''
                            }

                            $userPassword

                            #Check if password hash is empty
                            if($NTHash -ne $null)
                            {    
                                $userPassword = $NTHash.toLower()
                            }
                            
                            #Define properties to export
                            $properties = [PSCustomObject]@{
                            domainName = $domainDN
                            AccountExpirationDate = $user.AccountExpirationDate
                            #badPwdCound = $user.$badPwdCound
                            c = $user.c
                            cn = $user.cn
                            #co = $user.co
                            country = $user.Country
                            codePage = $user.codePage
                            company = $user.company
                            countryCode = $user.countryCode
                            department = $user.department
                            description = $user.description
                            displayName = $user.displayName
                            distinguishedName = $user.distinguishedName
                            division = $user.division
                            givenName = $user.givenName
                            homePhone = $user.homePhone
                            l = $user.l
                            mail = $user.mail
                            manager = $user.manager
                            memberOf = $user.memberOf
                            #msTSProperty01 = $msTerminal
                            #msTSWorkDirectory = $user.msTSWorkDirectory
                            name = $user.name
                            physicalDeliveryOfficeName = $user.physicalDeliveryOfficeName
                            postalCode = $user.postalCode
                            primaryGroupID = $user.primaryGroupID
                            sAMAccountName = $user.sAMAccountName
                            surname = $user.Surname
                            State = $user.State
                            street = $user.street
                            streetAddress = $user.streetAddress
                            telephoneNumber = $user.telephoneNumber
                            title = $user.title
                            url = $Url
                            userPassword = $userPassword
                            userPrincipalName = $user.userPrincipalName
                            #userWorkstations = $user.userWorkstations
                            wwwHomePage = $user.wwwHomePage
                            CannotChangePassword = $user.CannotChangePassword
                            City = $user.City
                            EmailAddress = $emailAddress
                            Fax = $user.Fax
                            info = $user.info
                            Initials = $user.Initials
                            ipPhone = $user.ipPhone
                            MobilePhone = $user.MobilePhone
                            OfficePhone = $user.OfficePhone
                            Office = $user.physicalDeliveryOfficeName
                            pager = $user.pager
                            PasswordNeverExpires = $user.PasswordNeverExpires
                            PasswordNotRequired = $user.PasswordNotRequired
                            POBox = $user.POBox
                            SmartcardLogonRequired = $user.SmartcardLogonRequired
                            }

                            $UsersList+= $properties 
                            $NTHash = $null
                            $passwordHash = $null  
                            $userPassword = $null
                            $emailAddress = $null 
                            
                    }
                                    
                    $UsersList | Export-csv $ExportPath -NoTypeInformation
            }
}

Export-UsersList -ExportPath "<Path of the CSV to Export Users>" -FQDN "<Fully Qualified Source Domain Name>"

# For example
# Export-UsersList -ExportPath "C:\Users\admin\users_exported.csv" -FQDN "contoso.com"

Snippet of the exported data

Script to Import Active Directory Users

You can download the PowerShell script from location : https://cdn.apps4.pro/scripts/import-active-directory-users.ps1


function Import-UsersList
{  
     param (  
           $csvPath,
           $FQDN
           )  
    process{

                #Check if Required Policy, Packages, Modules are Available
                [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
 
                $policy = Get-ExecutionPolicy
                If($policy -ne "RemoteSigned")
                {
                Set-ExecutionPolicy RemoteSigned -Force
                }
 
                $NuGet =  Get-PackageProvider -Name NuGet -Force
                IF($NuGet -eq $null)
                {
                Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
                }
                #Get All Modules
                $ADPowerShell = Get-Module -Name DSInternals
                 if($ADPowerShell -eq $null)
                 {
                    #Install the module
                    Install-Module -Name DSInternals -RequiredVersion 4.7
                 }

                
                #Import DSInternals, ActiveDirectory Modules
                Import-Module -Name DSInternals
                Import-Module -Name ActiveDirectory
                #Connect Domain
                $credential = Get-Credential
                $targetDN = (Get-ADDomain).DistinguishedName            
                $targetDomainFQDN = (Get-ADDomain).InfrastructureMaster.Tostring()
                $targetDomainFQDN
                $DCName = (Get-ADDomain).Name.Tostring()
                $DCName
            
                #Check if the CSV file exists
                if (Test-Path $csvPath)
                {
                    # Import data from CSV file
                    $userData = Import-Csv $csvPath

                    # Iterate through each row in the CSV
                    foreach ($user in $userData)
                    {
                        # Get the user by SamAccountName
                        try{
                        $adUser = Get-ADUser -Identity $user.SamAccountName
                        }
                        catch{
                            Write-Host $user.SamAccountName "User Not found in Target"
                        }
                        if($adUser -ne $null)
                        {
                            Write-Host $user.SamAccountName "User Already Exist"
                        }
                        else
                        {
                                
                                #create new AD Users in target
                                Write-Progress -Activity "ActivityName" -Status "Imporing User $($user.sAMAccountName)"
                                $split = $user.distinguishedName -split ','                
                                $parentDN = (($split | Select-Object -Skip 1) -join ",") -replace $user.domainName, $targetDN                
                                $userParams = @{
                                City = $user.City
                                Company = $user.Company
                                #Country = $user.Country
                                Department = $user.Department
                                Description = $user.Description
                                DisplayName = $user.DisplayName
                                Division =  $user.Division
                                EmailAddress = $user.EmailAddress
                                GivenName = $user.GivenName
                                HomePhone = $user.HomePhone
                                StreetAddress = $user.StreetAddress
                                PostalCode =  $user.PostalCode 
                                HomePage = $user.wwwHomePage 
                                SamAccountName = $user.SamAccountName
                                Name = $user.Name
                                Surname = $user.Surname
                                MobilePhone = $user.MobilePhone
                                Fax = $user.Fax
                                Initials = $user.Initials
                                OfficePhone = $user.OfficePhone
                                Office = $user.Office
                                POBox = $user.POBox
                                State = $user.State
                                Path = $parentDN
                                Title = $user.Title
                                }

                                New-ADUser @userParams
                                Write-Host $user.sAMAccountName "User Created Successfully"

                                #set user password hash
                                if($user.userPassword)
                                {
                                #Set-SamAccountPasswordHash -SamAccountName $user.sAMAccountName -Domain "testserver" -NTHash $user.userPassword -Server 'servervm.testserver.com' -Credential $credential
                                Set-SamAccountPasswordHash -SamAccountName $user.sAMAccountName -Domain $DCName -NTHash $user.userPassword -Server $targetDomainFQDN -Credential $credential
                                
                                }

                                #set propties country, primaryGroupId, Phone, Notes, expire date, etc..
                                Set-ADUser -Identity $user.SamAccountName -Replace @{c=$user.c} -ErrorAction SilentlyContinue 

                                Set-ADUser -Identity $user.SamAccountName -Replace @{primaryGroupID = $user.primaryGroupID} -ErrorAction SilentlyContinue
            
                                Set-ADUser -Identity $user.sAMAccountName -Replace @{ipPhone=$user.ipPhone} -ErrorAction SilentlyContinue

                                Set-ADUser -Identity $user.sAMAccountName -Replace @{info  = $user.info} -ErrorAction SilentlyContinue

                                
                                if($user.AccountExpirationDate -ne $null -and $user.AccountExpirationDate.GetType().FullName -eq 'System.DateTime')
                                {
                                    Set-ADUser -Identity $user.SamAccountName -AccountExpirationDate $user.AccountExpirationDate -ErrorAction SilentlyContinue
                                }
                                if($user.PasswordNeverExpires -eq "TRUE")
                                {
                                    Set-ADUser -Identity $user.SamAccountName -PasswordNeverExpires $true -ErrorAction SilentlyContinue
                                }
                                elseif($user.PasswordNeverExpires -eq "FALSE")
                                {
                                    Set-ADUser -Identity $user.SamAccountName -PasswordNeverExpires $false -ErrorAction SilentlyContinue
                                }
                                if($user.CannotChangePassword -eq "TRUE")
                                {
                                     Set-ADUser -Identity $user.SamAccountName -CannotChangePassword $true -ErrorAction SilentlyContinue
                                }
                                elseif($user.CannotChangePassword -eq "FALSE")
                                {
                                     Set-ADUser -Identity $user.SamAccountName -CannotChangePassword $false -ErrorAction SilentlyContinue
                                }

                                    #set Manager
                                    if($user.Manager -ne $null){
                                        $manager = $user.Manager -split ','
                                        $cnValue

                                        foreach ($part in $manager)
                                        {        
                                            if($part -match '^CN=(.*)')
                                            {
                                                $cnValue = $Matches[1]
                                                break
                                            }
                                        }
                                        Set-ADUser -Identity $user.SamAccountName -Manager $cnValue -ErrorAction SilentlyContinue
                                    }
                    
                            $adUser = $null
                     }
                        $adUser = $null
                   }
                    
                } 
                else
                {
                    Write-Host "CSV file not found at $csvPath"
                }
            }
}
Import-UsersList -csvPath "<Path of the exported CSV>" -FQDN "<Fully Qualified Target Domain Name>"

# For example
# Import-UsersList - csvPath "C:\Users\admin\users_exported.csv" -FQDN "fabricom.org"

Please refer our other BLOGs for the handy scripts to migrate the Active Directory Groups and Organizational units(OUs)

https://blog.jijitechnologies.com/migrate-your-active-directory-groups-across-tenants

https://blog.jijitechnologies.com/migrate-your-active-directory-ous-across-tenants

About Apps4.Pro Migration Manager

Apps4.Pro Migration Manager is the leading migration tool available in the market with unique migration features such as SharePoint, Exchange, Teams – channel & 1:1 chats, Whiteboard, Viva Engage(Yammer), Forms and Power Platform migrations.

To surf through the frequently asked questions, please visit the Support Portal

Write to us at sales@apps4.pro to know more.