Move-DominoGroupToAD: How to migrate SMTP addresses with groups

When attempting to migrate groups from Lotus Notes to Exchange 2007 with the Transporter for Lotus Notes, you may notice that Groups that contain SMTP addresses (non Exchange or Notes users) are not migrated with the group. I became aware of this issue recently when working with a customer and wrote a script to assist in getting these SMTP addresses migrated over cleanly.

 

So in the first screenshot we see a group in Domino that we want to migrate. By default the addresses highlighted below will not be migrated to AD.

 Move-DominoGroupToAD1
Above: The circled users will not be migrated to AD unless the contacts are created beforehand.

Enter Move-DominoGroupToADWithSMTP.ps1:

So the solution is to create a powershell script to come along beforehand and create the contacts. What we risk here is that the contacts will not be created and replicated in the time it takes to run the script, so we tell the script a Global Catalog Server to point to. In the first stage we use this server to write the contact to. In the second stage we call MoveDominoGroupToAD which expects the contact to be there.

In cases where we cannot do this or encounter problems with Move-DominoGroupToAD not detecting contacts in Active Directory, we can use the –CreateContactsOnly switch to create the contacts. Once these contacts replicate throughout Active Directory, we can continue on with the next step of running Move-DominoGroupToADWithSMTP.ps1 or just call Move-DominoGroupToAD directly.

The Script:

##################################################################################################
# Move-DominoGroupWithSMTP.ps1
#
# Written by Casey Spiller
#
#
# This script will move Domino Groups to Active Directory while preserving SMTP Addresses by
#  creating contacts in AD for these users. By default Move-DominoGroupToAD will drop SMTP  
#  addresses if they do not already exist in AD.
#
# For troubleshooting, please locate the transcript of the script which should be located
#  in your My Documents folder (by default).
#
# Known issues: If a user has an SMTP Address on a Domino Group that is also the SMTP Address used
#  of a MailUser, we will drop this address. Search the transcript for "SKIPPING" to locate any 
#  MailUsers who were dropped.
#
#
# Disclaimer:
# This script is not supported under any Microsoft standard support program or service. This
#  sample script are provided AS IS without warranty of any kind. Microsoft further disclaims
#  all implied warranties including, without limitation, any implied warranties of merchantability
#  or of fitness for a particular purpose. The entire risk arising out of the use or performance
#  of the sample scripts and documentation remains with you. In no event shall Microsoft, its
#  authors, or anyone else involved in the creation, production, or delivery of the scripts be
#  liable for any damages whatsoever (including, without limitation, damages for loss of business
#  profits, business interruption, loss of business information, or other pecuniary loss) arising
#  out of the use of or inability to use this script or documentation, even if Microsoft
#  has been advised of the possibility of such damages.
#
##################################################################################################

# Input Parameters
param ([string]$DominoGroup = "", [string]$GlobalCatalogServer = "", [string]$ADContainer = "", [switch]$help=$false, [switch]$All = $false,[switch]$CreateContactsOnly=$false);

#regex to identify SMTP addresses
$smtpregex = "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
$iAddress = 0;

Function ShowHelp
{

 Write-Host "Written by Casey Spiller" -foregroundcolor "White";
 Write-Host "This Script will Move Domino Groups to Active Directory while preserving SMTP";
 Write-Host "Addresses by creating Contacts in AD for these users.";
 Write-Host "";
 
 Write-Host "Options:" -foregroundcolor "White";
 Write-Host "-DominoGroup          : Used to specify the Domino Group we wish to migrate for";
 Write-Host "                        migrating groups one at a time";
 Write-Host "";
 Write-Host "-All                  : Used to migrate all Domino Groups at once. This option";
 Write-Host "                        overrides the -DominoGroup option";
 Write-Host "";
 Write-Host "-GlobalCatalogServer  : Used to specify the GC/DC";
 Write-Host "";
 Write-Host "-ADContainer          : Used to specify the Container in AD to write contacts to";
 Write-Host "";
 Write-Host "-CreateContactsOnly   : Used to Create Contacts in AD and NOT Move Groups";
 Write-Host "";
 Write-Host "Usage: " -foregroundcolor "White";
 Write-Host "Move-DominoGroupwithSMTP.ps1 -DominoGroup ContosoAll -GlobalCatalogServer dc.contoso.com -ADContainer Users" -foregroundcolor "Green";
 Write-Host "";

}

Function VerifyParams
{
 if (!$DominoGroup -and $All -eq $false)
  {
  ShowHelp;
  Write-Host "Missing 'DominoGroup' or 'All' Parameter. Either 'DominoGroup' or 'All' is required" -foregroundcolor "Red";
  Write-Host "";
  stop-transcript;
  exit;
  }
 
 if (!$GlobalCatalogServer)
  {
  ShowHelp;
  Write-Host "Missing 'GlobalCatalogServer' Parameter" -foregroundcolor "Red";
  Write-Host "";
  stop-transcript;
  exit
  }

 if (!$ADContainer)
  {
  ShowHelp;
  Write-Host "Missing 'ADContainer' Parameter" -foregroundcolor "Red";
  Write-Host "";
  stop-transcript;
  exit
  }

}
Function CheckForAddress
{
 #initialize integer

 #Write-Host $member.ToString();
 if (Get-MailContact $member.ToString() -ErrorAction SilentlyContinue)
  {
   $iAddress++;
   Write-Host "Contact detected for" $member  "SKIPPING" -foregroundcolor "Blue" ;
  }
 
 #Detect if we've found a Contact with the Address already for performance
 
 if ($iAddress -eq 0)
 {

  if (Get-MailBox $member.ToString() -ErrorAction SilentlyContinue)
   {
    $iAddress++;
    Write-Host "Mailbox detected for" $member "SKIPPING" -foregroundcolor "Blue";
   }

 }
 #Detect if we've found a Contact with the Address already for performance
 
 if ($iAddress -eq 0)
 {

  if (Get-MailUser $member.ToString() -ErrorAction SilentlyContinue)
   {
    $iAddress++;
    Write-Host "MailUser detected:" $member "SKIPPING" -foregroundcolor "Blue";
    Write-Host "Move-DominoGroupToAD will not move this user as it is a MailUser" -foregroundcolor "Blue";
   }

 }
 return $iAddress;
}

#
#Begin actual script
#

start-transcript -Verbose;
# Display help if -help is specified
if ($help -eq $true)
 {ShowHelp; exit }
else { }

#Check for params
VerifyParams;

Write-Host "";
Write-Host "Using the folling regex to detect what a valid SMTP Address is: " $smtpregex
Write-Host "-----------------------";

#Set DominoGroup to null if we are doing all DominoGroups
if ($All)
 {$DominoGroup = $null}

foreach ($group in (Get-DominoGroup $DominoGroup))
{
 Write-Host "Domino Group: " $group.Name;

 foreach ($member in ($group.Members))
 {
 

  # we need to parse through the members to look for smtp addresses.
  # ie user@domain.com. We need both the @ and the "."

  if ($member -match $smtpregex)
   { 
  
    
    # Call CheckForAddress to verify if the address already exists in AD, set iAddress if we find the Address in AD
    $iAddress = CheckForAddress;
    
     if ($iAddress -eq 0)
      {

      #create a new alias, we will change "@" to "_"
      $alias = $member.ToString().Replace("@","_");
      Write-Host "-----------------------";
      Write-Host "Domino Group contains member identified with an SMTP Address:" $member
      Write-Host "New-MailContact -Name" $member "-ExternalEmailAddress" $member "-OrganizationalUnit" $ADContainer "-DomainController" $GlobalCatalogServer -foregroundcolor "Green";
      New-MailContact -Name $alias -ExternalEmailAddress $member.ToString() -OrganizationalUnit $ADContainer -DomainController $GlobalCatalogServer
      Write-Host "-----------------------";

      }
   }
  
  
 }
 Write-Host "----------------------------------------------";
 
}

Write-Host "----------------------------------------------";
Write-Host "";
Write-Host "";

if (!$CreateContactsOnly -eq $true)
 {
 Write-Host "Now calling Move-DominoGroupToAD ";
 Write-Host "MoveDominoGroupToAD" $DominoGroup "-TargetOU" $ADContainer "-GlobalCatalog" $GlobalCatalogServer -foregroundcolor "Green";
 Move-DominoGroupToAD $DominoGroup -TargetOU $ADContainer -GlobalCatalog $GlobalCatalogServer -verbose;
 }
else {
 Write-Host "Contact Only mode, No DominoGroups will be created in ActiveDirectory";
 } 
 
Write-Host "";
stop-transcript;
############
# End Script #
############

Casey Spiller