7 min to read
Migrate your Active Directory Users across tenants
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.
PasswordNotRequired CannotChangePassword |
|
|
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 :
- Execute the below scripts by feeding in
- Path to the CSV to import / export the users
- Fully qualified Domain Name
- 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.apps4.pro/migrate-your-active-directory-groups-across-tenants https://blog.apps4.pro/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.