Import/Export Distribution Groups when performing an Exchange cross-forest migration/upgrade | Phy2Vir

An IT Blog covering anything from Physical to Virtual in I.T

Import/Export Distribution Groups when performing an Exchange cross-forest migration/upgrade

Recently we needed to upgrade a customer from Exchange Server 2003 to Exchange 2016.

As you may know there are two ways you can perform this.

One way is to do incremental upgrades from Exchange 2003 to Exchange 2007/2010, from 2007/2010 to 2013 and then from 2013 to 2016. This is because exchange 2016 cannot co-exist with Exchange Server 2003.

The second way is to perform a cross-forest migration by creating a new active directory forest and configure Exchange 2016 in that forest. Using 3rd Party tools like CodeTwo Exchange Migration you can then migrate users’ mailboxes from one side to the other in the background before doing the changeover.

NOTE:
I was approached by Migration Monster and they mentioned that they have a product which can also help in migrating your exchange mailboxes. As they put it:

Migration Monster is an easy, super-fast & secure cloud based Office 365 & MS Exchange migration tool suited for all types of businesses. It’s a highly affordable solution designed by an experienced cloud entrepreneurs to solve the problem of migrating mailboxes of any size.

I haven’t used this product yet but if I do I will let you know how it goes. I am putting this information here as I’d like my readers to have multiple options. I am not affiliated or sponsored by Migration Monster but I am happy to mention them since they reached out. If you try them out before me let us know how it goes in the comments below.

This setup and set of tools helped a lot in migrating the users to the new exchange server with minimum downtime. One of the few catches we had was that Distribution Groups were not migrated and thus we needed to recreate them in the new AD forest.

Exchange 2003 does not include a PowerShell module, so we had to think of other ways to export groups and members from it. In the process of migrating, we also migrated the domain controllers Windows Server 2003 to Windows Server 2012 R2. This was required for the cross-forest migration to work properly.

Using the Active Directory Module (ADM) for Windows PowerShell we exported the Distribution Groups and then we exported the members of the Distribution Groups to be later imported in Exchange Server 2016.

To Export the Distribution Groups we opened an elevated  ADM PowerShell window and executed the command below:

Get-ADGroup -Filter {GroupCategory -eq "Distribution"}|select Name | Export-Csv -Path "c:\Export\DGList.csv"

The exported csv file, which contains a single column with the Heading “Name”, was copied to the Exchange 2016 server and using an Elevated Exchange Management Shell we imported the distribution groups using the command:

Import-Csv "C:\Export\DGList.csv" | ForEach {New-DistributionGroup -Name "$_.Name"}

Now that the distribution groups have been created on the target exchange server we needed to export the members of each group from the source server and add them to the groups in the target server.

This needs to be done by using the exchange PS command Add-DistributionGroupMember which requires the parameters -Identity, which is the group name, and -Member, which is the name of the Member you want to add. Only one member can be added at a time so we need to create a csv file where each line contains the Distribution Group name and the username.

To do this we used the below script which was executed in an elevated admin Powershell ISE console:

Get-ADGroup -Filter {GroupCategory -eq "Distribution"}| ForEach-Object{ $group=$_ 
$users=Get-ADGroupMember -Identity $group 
Foreach ($dguser in $users){ New-Object -TypeName PSobject -Property @{ SAM=$dguser.SamAccountName Group=$group.name 
} 
} 
}|Export-Csv -Path "c:\Export\DGusers.csv"

The below is a sample of the contents of the csv generated:

#TYPE System.Management.Automation.PSCustomObject 
"SAM","Group" 
"user1","DG1" 
"user2","DG1" 
"user3","DG2" 
"user3","DG2" 
"user1","DG3" 
"user3","DG3" etc ...

We needed to edit the csv file and remove the first line to be able to import the users properly.
Therefore,

#TYPE System.Management.Automation.PSCustomObject

was removed.

The file was copied to the target exchange server and from within the Exchange Management Shell we imported the members using the command:

Import-Csv "C:\Export\DGusers.csv" | ForEach{Add-DistributionGroupMember -Identity $_.Group -Member $_.SAM}

These little scripts helped me in migrating over 50 distribution groups effortlessly.

Hope someone finds them useful.


2 Comments

  • Get-ADGroup -Filter {GroupCategory -eq “Distribution”}| ForEach-Object{ $group=$_ $users=Get-ADGroupMember -Identity $group foreach ($dguser in $users){ New-Object -TypeName PSobject -Property @{ SAM=$dguser.SamAccountName Group=$group.name } } }|Export-Csv -Path “c:\Export\DGusers.csv”

    The below script doesn’t work !

    We get the Following error when executing it

    Au caractère Ligne:1 : 83
    + … ect{ $group=$_ $users=Get-ADGroupMember -Identity $group foreach ($dguser in $us …
    + ~~~~~~~~~~~~~~~~~~~~~~~~
    Jeton inattendu « $users=Get-ADGroupMember » dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 142
    + … reach ($dguser in $users){ New-Object -TypeName PSobject -Property @{ SAM=$dguse …
    + ~~
    Jeton inattendu « in » dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 141
    + … oreach ($dguser in $users){ New-Object -TypeName PSobject -Property @{ SAM=$dgus …
    + ~
    Parenthèse fermante « ) » manquante dans l’expression.
    Au caractère Ligne:1 : 71
    + Get-ADGroup -Filter {GroupCategory -eq “Distribution”}| ForEach-Object{ $group=$ …
    + ~
    Accolade fermante « } » manquante dans le bloc d’instruction.
    Au caractère Ligne:1 : 151
    + … guser in $users){ New-Object -TypeName PSobject -Property @{ SAM=$dguser.SamAcco …
    + ~
    Jeton inattendu « ) » dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 224
    + … SamAccountName Group=$group.name } } }|Export-Csv -Path “c:\Export\DGusers.csv”
    + ~~~~~~~~~~~~~~~~~
    Jeton inattendu « Group=$group.name » dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 223
    + … .SamAccountName Group=$group.name } } }|Export-Csv -Path “c:\Export\DGusers.csv”
    + ~
    Le littéral de hachage est incomplet.
    Au caractère Ligne:1 : 244
    + … =$group.name } } }|Export-Csv -Path “c:\Export\DGusers.csv”
    + ~
    Jeton inattendu « } » dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 246
    + … group.name } } }|Export-Csv -Path “c:\Export\DGusers.csv”
    + ~
    Jeton inattendu « } » dans l’expression ou l’instruction.
    Au caractère Ligne:1 : 247
    + … roup.name } } }|Export-Csv -Path “c:\Export\DGusers.csv”
    + ~
    Un élément de canal vide n’est pas autorisé.
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

    • Hi,
      I have checked and indeed the script works. The issue is that for some reason the script lost its formatting.
      I have redone it and ideally use Powershell ISE with Admin to run in.
      Paste it in the script pane and execute.
      I also noticed that when copying the script and pasting it the ” were being changed to “ which it appears that powershell does not recognise.

      Please have another go and let us know 🙂
      Thanks for visiting

Post a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • Free Advertisement

    Advertisements
    hostifi.net
  • Advertisements
    Microsoft Office 365 Backup
  • Advertisements
  • Google Ads

    Advertisements
  • Connect with me

  • Site Menu

  • Follow me on Twitter

  • Advertisements