在 Exchange Online 中将 Exchange 2007 邮箱转换为已启用邮件的用户

完成暂存迁移后,将本地邮箱转换为已启用邮件的用户,以便本地用户可以自动连接到其云邮箱。

为什么要将邮箱转换为启用邮件的用户?

需要将迁移的本地邮箱转换为) (MEU 启用邮件的用户,以便可以使用 Active Directory 管理本地组织中的基于云的用户。

在暂存 Exchange 迁移中,邮箱迁移到云后会发生以下两种情况:

  • 用户具有本地邮箱和云邮箱。
  • 发送到用户本地邮箱的邮件转发到云邮箱中。 这是因为在迁移过程中,本地邮箱上的 TargetAddress 属性包含云邮箱的远程路由地址。 用户需要连接到其云邮箱才能访问其电子邮件。

此行为会导致以下问题:

  • 用户无法在 Microsoft Outlook 中连接到其云邮箱。 本地组织中的自动发现服务仍尝试连接到其本地邮箱。 在迁移所有用户之前,无法将本地自动发现 CNAME 记录指向云。

  • 如果在将所有邮箱迁移到云后解除 Exchange 授权,云邮箱上与消息传送相关的用户信息将丢失。 目录同步会从云邮箱对象中删除数据, (例如代理地址) ,因为本地邮箱不再存在。 目录同步无法将数据与相应的云邮箱匹配。

解决方案是在邮箱迁移到云后,将用户的本地邮箱转换为启用邮件的用户, (MEU) 。 将本地邮箱转换为 MEU 时,将执行以下操作:

  • 基于云的邮箱中的代理地址将复制到新的 MEU。 如果解除 Exchange 的授权,这些代理地址仍保留在 Active Directory 中。
  • MEU 的属性使目录同步能够将 MEU 与其相应的云邮箱进行匹配。
  • 用户创建新的 Outlook 配置文件后,自动发现服务使用 MEU 将 Outlook 连接到云邮箱。

用于创建 MEU 的 PowerShell 脚本

使用本部分中的脚本收集有关基于云的邮箱的信息,并将 Exchange 2007 邮箱转换为 MEU。

PowerShell 脚本从云邮箱收集信息并将其保存到 CSV 文件中。 先运行该脚本。

将脚本复制到记事本,并将文件另存为ExportO365UserInfo.ps1。

注意

  • 在运行 PowerShell 脚本之前,需要安装 Exchange Online PowerShell 模块。 有关说明,请参阅安装和维护 Exchange Online PowerShell 模块。 该模块使用新式身份验证。

  • 通常情况下,如果组织是 Microsoft 365 或 Microsoft 365 GCC,则可按原样使用该脚本。 如果组织是 Office 365 德国、Microsoft 365 GCC 高或 Microsoft 365 DoD,则需编辑脚本中的 Connect-ExchangeOnline 行。 具体来说,你需要为组织类型使用 ExchangeEnvironmentName 参数和适当的值。 有关更多信息,请参阅连接到 Exchange Online PowerShell中的示例。

Param($migrationCSVFileName = "migration.csv")
function O365Logon
{
    #Check for current open O365 sessions and allow the admin to either use the existing session or create a new one
    $session = Get-PSSession | ?{$_.ConfigurationName -eq 'Microsoft.Exchange'}
    if($session -ne $null)
    {
        $a = Read-Host "An open session to Exchange Online PowerShell already exists. Do you want to use this session?  Enter y to use the open session, anything else to close and open a fresh session."
        if($a.ToLower() -eq 'y')
        {
            Write-Host "Using existing Exchange Online Powershell session." -ForeGroundColor Green
            return
        }
        Disconnect-ExchangeOnline -Confirm:$false
    }
    Import-Module ExchangeOnlineManagement
    Connect-ExchangeOnline -Prefix "Cloud"
}
function Main
{
    #Verify the migration CSV file exists
    if(!(Test-Path $migrationCSVFileName))
    {
        Write-Host "File $migrationCSVFileName does not exist." -ForegroundColor Red
        Exit
    }
    #Import user list from migration.csv file
    $MigrationCSV = Import-Csv $migrationCSVFileName

    #Get mailbox list based on email addresses from CSV file
    $MailBoxList = $MigrationCSV | %{$_.EmailAddress} | Get-CloudMailbox
    $Users = @()

    #Get LegacyDN, Tenant, and On-Premises Email addresses for the users
    foreach($user in $MailBoxList)
    {
        $UserInfo = New-Object System.Object

        $CloudEmailAddress = $user.EmailAddresses | ?{($_ -match 'onmicrosoft') -and ($_ -match 'smtp:')}
        if ($CloudEmailAddress.Count -gt 1)
        {
            $CloudEmailAddress = $CloudEmailAddress[0].ToString().ToLower().Replace('smtp:', '')
            Write-Host "$user returned more than one cloud email address. Using $CloudEmailAddress" -ForegroundColor Yellow
        }
        else
        {
            $CloudEmailAddress = $CloudEmailAddress.ToString().ToLower().Replace('smtp:', '')
        }

        $UserInfo | Add-Member -Type NoteProperty -Name LegacyExchangeDN -Value $user.LegacyExchangeDN
        $UserInfo | Add-Member -Type NoteProperty -Name CloudEmailAddress -Value $CloudEmailAddress
        $UserInfo | Add-Member -Type NoteProperty -Name OnPremiseEmailAddress -Value $user.PrimarySMTPAddress.ToString()
        $UserInfo | Add-Member -Type NoteProperty -Name MailboxGUID -Value $user.ExchangeGUID
        $Users += $UserInfo
    }
    #Check for existing csv file and overwrite if needed
    if(Test-Path ".\cloud.csv")
    {
        $delete = Read-Host "The file cloud.csv already exists in the current directory. Do you want to delete it?  Enter y to delete, anything else to exit this script."
        if($delete.ToString().ToLower() -eq 'y')
        {
            Write-Host "Deleting existing cloud.csv file" -ForeGroundColor Red
            Remove-Item ".\cloud.csv"
        }
        else
        {
            Write-Host "Will NOT delete current cloud.csv file. Exiting script." -ForeGroundColor Green
            Exit
        }
    }
    $Users | Export-CSV -Path ".\cloud.csv" -notype
    (Get-Content ".\cloud.csv") | %{$_ -replace '"', ''} | Set-Content ".\cloud.csv" -Encoding Unicode
    Write-Host "CSV File Successfully Exported to cloud.csv" -ForeGroundColor Green
}
O365Logon
Main

Visual Basic 脚本将本地 Exchange 2003 邮箱转换为 MEU。 运行 PowerShell 脚本以从云邮箱收集信息后运行此脚本。

将脚本复制到记事本,并将文件另存为Exchange2007MBtoMEU.vbs。

param($DomainController = [String]::Empty)
function Main
{
    #Script Logic flow
    #1. Pull User Info from cloud.csv file in the current directory
    #2. Lookup AD Info (DN, mail, proxyAddresses, and legacyExchangeDN) using the SMTP address from the CSV file
    #3. Save existing proxyAddresses
    #4. Add existing legacyExchangeDN's to proxyAddresses
    #5. Delete Mailbox
    #6. Mail-Enable the user using the cloud email address as the targetAddress
    #7. Disable RUS processing
    #8. Add proxyAddresses and mail attribute back to the object
    #9. Add msExchMailboxGUID from cloud.csv to the user object (for offboarding support)

    if($DomainController -eq [String]::Empty)
    {
        Write-Host "You must supply a value for the -DomainController switch" -ForegroundColor Red
        Exit
    }

    $CSVInfo = Import-Csv ".\cloud.csv"
    foreach($User in $CSVInfo)
    {
        Write-Host "Processing user" $User.OnPremiseEmailAddress -ForegroundColor Green
        Write-Host "Calling LookupADInformationFromSMTPAddress" -ForegroundColor Green
        $UserInfo = LookupADInformationFromSMTPAddress($User)

        #Check existing proxies for On-Premises and Cloud Legacy DN's as x500 proxies. If not present add them.
        if($UserInfo.ProxyAddresses -notcontains ("X500:"+$UserInfo.CloudLegacyDN))
        {
            $X500Proxy = "x500:" + $UserInfo.CloudLegacyDN
            Write-Host "Adding $X500Proxy to EmailAddresses" -ForegroundColor Green
            $UserInfo.ProxyAddresses.Add($X500Proxy)
        }
        if($UserInfo.ProxyAddresses -notcontains ("X500:"+$UserInfo.LegacyDN))
        {
            $X500Proxy = "x500:" + $UserInfo.LegacyDN
            Write-Host "Adding $X500Proxy to EmailAddresses" -ForegroundColor Green
            $UserInfo.ProxyAddresses.Add($X500Proxy)
        }

        #Disable Mailbox
        Write-Host "Disabling Mailbox" -ForegroundColor Green
        Disable-Mailbox -Identity $UserInfo.OnPremiseEmailAddress -DomainController $DomainController -Confirm:$false

        #Mail Enable
        Write-Host "Enabling Mailbox" -ForegroundColor Green
        Enable-MailUser  -Identity $UserInfo.Identity -ExternalEmailAddress $UserInfo.CloudEmailAddress -DomainController $DomainController

        #Disable RUS
        Write-Host "Disabling RUS" -ForegroundColor Green
        Set-MailUser -Identity $UserInfo.Identity -EmailAddressPolicyEnabled $false -DomainController $DomainController

        #Add Proxies and Mail
        Write-Host "Adding EmailAddresses and WindowsEmailAddress" -ForegroundColor Green
        Set-MailUser -Identity $UserInfo.Identity -EmailAddresses $UserInfo.ProxyAddresses -WindowsEmailAddress $UserInfo.Mail -DomainController $DomainController

        #Set Mailbox GUID. Need to do this via S.DS as Set-MailUser doesn't expose this property.
        $ADPath = "LDAP://" + $DomainController + "/" + $UserInfo.DistinguishedName
        $ADUser = New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList $ADPath
        $MailboxGUID = New-Object -TypeName System.Guid -ArgumentList $UserInfo.MailboxGUID
        [Void]$ADUser.psbase.invokeset('msExchMailboxGUID',$MailboxGUID.ToByteArray())
        Write-Host "Setting Mailbox GUID" $UserInfo.MailboxGUID -ForegroundColor Green
        $ADUser.psbase.CommitChanges()

        Write-Host "Migration Complete for" $UserInfo.OnPremiseEmailAddress -ForegroundColor Green
        Write-Host ""
        Write-Host ""
    }
}

function LookupADInformationFromSMTPAddress($CSV)
{
    $Mailbox = Get-Mailbox $CSV.OnPremiseEmailAddress -ErrorAction SilentlyContinue

    if($Mailbox -eq $null)
    {
        Write-Host "Get-Mailbox failed for" $CSV.OnPremiseEmailAddress -ForegroundColor Red
        continue
    }

    $UserInfo = New-Object System.Object

    $UserInfo | Add-Member -Type NoteProperty -Name OnPremiseEmailAddress -Value $CSV.OnPremiseEmailAddress
    $UserInfo | Add-Member -Type NoteProperty -Name CloudEmailAddress -Value $CSV.CloudEmailAddress
    $UserInfo | Add-Member -Type NoteProperty -Name CloudLegacyDN -Value $CSV.LegacyExchangeDN
    $UserInfo | Add-Member -Type NoteProperty -Name LegacyDN -Value $Mailbox.LegacyExchangeDN
    $ProxyAddresses = New-Object Microsoft.Exchange.Data.ProxyAddressCollection
    $ProxyAddresses = $Mailbox.EmailAddresses
    $UserInfo | Add-Member -Type NoteProperty -Name ProxyAddresses -Value $ProxyAddresses
    $UserInfo | Add-Member -Type NoteProperty -Name Mail -Value $Mailbox.WindowsEmailAddress
    $UserInfo | Add-Member -Type NoteProperty -Name MailboxGUID -Value $CSV.MailboxGUID
    $UserInfo | Add-Member -Type NoteProperty -Name Identity -Value $Mailbox.Identity
    $UserInfo | Add-Member -Type NoteProperty -Name DistinguishedName -Value (Get-User $Mailbox.Identity).DistinguishedName

    $UserInfo
}
Main

将本地邮箱转换为 MEU 的设置步骤

按照下列步骤完成此过程。

  1. 将用于运行迁移批处理的 ExportO365UserInfo.ps1、Exchange2007MBtoMEU.ps1 和 CSV 文件复制到本地服务器的相同目录中。

  2. 将迁移 CSV 文件重命名为 migration.csv。

  3. 在 Exchange 命令行管理程序中运行以下命令。 脚本假定 CSV 文件位于相同目录中,且名为 migration.csv。

    .\ExportO365UserInfo.ps1
    

    系统会提示使用现有会话或打开新的会话。

  4. 键入 n 并按 Enter,打开新的会话。

    此时脚本运行,然后将 Cloud.csv 文件保存到当前工作目录。

  5. 输入基于云的组织的管理员凭据,然后单击" 确定"。

  6. 在新的 Exchange 命令行管理程序会话中运行以下命令。 此命令假定 ExportO365UserInfo.ps1 和 Cloud.csv 位于相同目录中。

    .\Exchange2007MBtoMEU.ps1 <FQDN of on-premises domain controller>
    

    例如:

    .\Exchange2007MBtoMEU.ps1 DC1.contoso.com
    

    该脚本为 Cloud.csv 中包含的所有用户将本地邮箱转换为 MEU。

  7. 验证是否已创建新的 MEU。 在 Active Directory 用户和计算机 中,执行以下步骤:

    1. 单击“ 操作>查找”。

    2. 单击“ Exchange ”选项卡。

    3. 选择" 仅显示 Exchange 收件人",然后选择" 具有外部电子邮件地址的用户"。

    4. 单击" 立即查找"。

      " 搜索结果"下列出已转换为 MEU 的邮箱。

  8. 使用 Active Directory 用户和计算机ADSI EditLdp.exe 验证以下 MEU 属性是否填充了正确的信息。

    • legacyExchangeDN
    • mail
    • msExchMailboxGuid
    • proxyAddresses
    • targetAddress