Exchange 2003 のメールボックスをメールが有効なユーザーに変換する

段階的な移行を完了したら、メールボックスがクラウド メールボックスに自動的に接続されるように、メールボックスをメールが有効なユーザーに変換します。


Exchange の段階的な移行を完了して組織の Exchange 2003 オンプレミス メールボックスを Office 365 に移行し、オンプレミス組織から (Active Directory を使用して) クラウドベースのユーザーを管理する場合、オンプレミス メールボックスをメールが有効なユーザー (MEU) に変換する必要があります。

この記事では、クラウドベースのメールボックスから情報を収集する Windows PowerShell スクリプトと、Exchange 2003 メールボックスを MEU に変換できる Visual Basic (VB) スクリプトを紹介しています。このスクリプトを実行すると、クラウドベースのメールボックスのプロキシ アドレスは、Active Directory にある MEU にコピーされます。また、MEU のプロパティを使用すると、Microsoft Online Services ディレクトリ同期ツール (Azure Active Directory 同期ツール) で MEU と対応するクラウド メールボックスとをマッチングすることもできます。

移行バッチを実行するために、オンプレミス メールボックスを MEU に変換することをお勧めします。Exchange の段階的な移行バッチが完了した後、バッチ内のすべてのメールボックスが正常に移行され、メールボックス アイテムからクラウドへの初回の同期が完了したことを確認したら、移行バッチ内のメールボックスを MEU に変換します。

クラウド メールボックスのデータを収集する PowerShell スクリプト

次のスクリプトを使用して、クラウドベースのメールボックスに関する情報を収集し、Exchange 2007 メールボックスを MEU に変換することができます。

次のスクリプトは、クラウド メールボックスの情報を収集し、CSV ファイルに保存します。このスクリプトを最初に実行します。

次のスクリプトを .txt ファイルにコピーして保存してから、ExportO365UserInfo.ps1 という名前で保存します。

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 Office 365 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 Office 365 Powershell Session." -ForeGroundColor Green
$session | Remove-PSSession
Write-Host "Please enter your Office 365 credentials" -ForeGroundColor Green
$cred = Get-Credential
$s = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $cred -Authentication Basic -AllowRedirection
$importresults = Import-PSSession $s

function Main

#Verify the migration CSV file exists
if(!(Test-Path $migrationCSVFileName))
Write-Host "File $migrationCSVFileName does not exist." -ForegroundColor Red

#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-Mailbox
$Users = @()

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

$CloudEmailAddress = $user.EmailAddresses | ?{($_ -match 'onmicrosoft') -and ($_ -cmatch '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
$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()

$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"
Write-Host "Will NOT delete current cloud.csv file. Exiting script." -ForeGroundColor Green
$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



次の Visual Basic スクリプトは、オンプレミス Exchange 2003 メールボックスを MEU に変換します。クラウド メールボックスの情報を収集するスクリプトを実行してから、このスクリプトを実行してください。

次のスクリプトを .txt ファイルにコピーしてから、Exchange2003MBtoMEU.vbs という名前で保存します。


Dim UserDN
Dim remoteSMTPAddress
Dim remoteLegacyDN
Dim domainController
Dim csvMode
csvMode = FALSE
Dim csvFileName
Dim lastADLookupFailed

Class UserInfo
public OnPremiseEmailAddress
public CloudEmailAddress
public CloudLegacyDN
public LegacyDN
public ProxyAddresses
public Mail
public MailboxGUID
public DistinguishedName

Public Sub Class_Initialize()
Set ProxyAddresses = CreateObject("Scripting.Dictionary")
End Sub
End Class

'Command Line Parameters
If WScript.Arguments.Count = 0 Then
'No parameters passed
WScript.Echo("No parameters were passed.")
ElseIf StrComp(WScript.Arguments(0), "-c", vbTextCompare) = 0 And WScript.Arguments.Count = 2 Then
WScript.Echo("Missing DC Name.")
ElseIf StrComp(WScript.Arguments(0), "-c", vbTextCompare) = 0 Then
'CSV Mode
csvFileName = WScript.Arguments(1)
domainController = WScript.Arguments(2)
csvMode = TRUE
WScript.Echo("CSV mode detected. Filename: " & WScript.Arguments(1) & vbCrLf)
ElseIf wscript.Arguments.Count <> 4 Then
'Invalid Arguments
WScript.Echo WScript.Arguments.Count
Call ShowHelp()
'Manual Mode
UserDN = wscript.Arguments(0)
remoteSMTPAddress = wscript.Arguments(1)
remoteLegacyDN = wscript.Arguments(2)
domainController = wscript.Arguments(3)
End If


'Main entry point
Sub Main

'Check for CSV Mode
If csvMode = TRUE Then
UserInfoArray = GetUserInfoFromCSVFile()
WScript.Echo "Manual Mode Detected" & vbCrLf
Set info = New UserInfo
info.CloudEmailAddress = remoteSMTPAddress
info.DistinguishedName = UserDN
info.CloudLegacyDN = remoteLegacyDN
End If

End Sub

'Process a single user (manual mode)
Sub ProcessSingleUser(ByRef UserInfo)

userADSIPath = "LDAP://" & domainController & "/" & UserInfo.DistinguishedName
WScript.Echo "Processing user " & userADSIPath
Set MyUser = GetObject(userADSIPath)
proxyCounter = 1
For Each address in MyUser.Get("proxyAddresses")
UserInfo.ProxyAddresses.Add proxyCounter, address
proxyCounter = proxyCounter + 1
UserInfo.OnPremiseEmailAddress = GetPrimarySMTPAddress(UserInfo.ProxyAddresses)
UserInfo.Mail = MyUser.Get("mail")
UserInfo.MailboxGUID = MyUser.Get("msExchMailboxGUID")
UserInfo.LegacyDN = MyUser.Get("legacyExchangeDN")

End Sub

'Populate user info from CSV data
Function GetUserInfoFromCSVFile()

CSVInfo = ReadCSVFile()
For i = 0 To (UBound(CSVInfo)-1)
lastADLookupFailed = false
Set info = New UserInfo
info.CloudLegacyDN = Split(CSVInfo(i+1), ",")(0)
info.CloudEmailAddress = Split(CSVInfo(i+1), ",")(1)
info.OnPremiseEmailAddress = Split(CSVInfo(i+1), ",")(2)
WScript.Echo "Processing user " & info.OnPremiseEmailAddress
WScript.Echo "Calling LookupADInformationFromSMTPAddress"
If lastADLookupFailed = false Then
WScript.Echo "Calling ProcessMailbox"
End If
set info = nothing

End Function

'Populate user info from AD
Sub LookupADInformationFromSMTPAddress(ByRef info)

'Lookup the rest of the info in AD using the SMTP address
Set objRootDSE = GetObject("LDAP://RootDSE")
strDomain = objRootDSE.Get("DefaultNamingContext")
Set objRootDSE = nothing
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand = CreateObject("ADODB.Command")
BaseDN = "<LDAP://" & domainController & "/" & strDomain & ">"
adFilter = "(&(proxyAddresses=SMTP:" & info.OnPremiseEmailAddress & "))"
Attributes = "distinguishedName,msExchMailboxGUID,mail,proxyAddresses,legacyExchangeDN"
Query = BaseDN & ";" & adFilter & ";" & Attributes & ";subtree"
objCommand.CommandText = Query
Set objCommand.ActiveConnection = objConnection
On Error Resume Next
Set objRecordSet = objCommand.Execute

'Handle any errors that result from the query
If Err.Number <> 0 Then
WScript.Echo "Error encountered on query " & Query & ". Skipping user."
lastADLookupFailed = true
End If

'Handle zero or ambiguous search results
If objRecordSet.RecordCount = 0 Then
WScript.Echo "No users found for address " & info.OnPremiseEmailAddress
lastADLookupFailed = true
ElseIf objRecordSet.RecordCount > 1 Then
WScript.Echo "Ambiguous search results for email address " & info.OnPremiseEmailAddress
lastADLookupFailed = true
ElseIf Not objRecordSet.EOF Then
info.LegacyDN = objRecordSet.Fields("legacyExchangeDN").Value
info.Mail = objRecordSet.Fields("mail").Value
info.MailboxGUID = objRecordSet.Fields("msExchMailboxGUID").Value
proxyCounter = 1
For Each address in objRecordSet.Fields("proxyAddresses").Value
info.ProxyAddresses.Add proxyCounter, address
proxyCounter = proxyCounter + 1
info.DistinguishedName = objRecordSet.Fields("distinguishedName").Value
End If

objConnection = nothing
objCommand = nothing
objRecordSet = nothing
On Error Goto 0

End Sub

'Populate data from the CSV file
Function ReadCSVFile()

'Open file
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFS.OpenTextFile(csvFileName, 1, false, -1)

'Loop through each line, putting each line of the CSV file into an array to be returned to the caller
counter = 0
Dim CSVArray()
Do While NOT objTextFile.AtEndOfStream
ReDim Preserve CSVArray(counter)
CSVArray(counter) = objTextFile.ReadLine
counter = counter + 1

'Close and return
Set objTextFile = nothing
Set objFS = nothing
ReadCSVFile = CSVArray

End Function

'Process the migration
Sub ProcessMailbox(User)

'Get user properties
userADSIPath = "LDAP://" & domainController & "/" & User.DistinguishedName
Set MyUser = GetObject(userADSIPath)

'Add x.500 address to list of existing proxies
existingLegDnFound = FALSE
newLegDnFound = FALSE

'Loop through each address in User.ProxyAddresses
For i = 1 To User.ProxyAddresses.Count
If StrComp(address, "x500:" & User.LegacyDN, vbTextCompare) = 0 Then
WScript.Echo "x500 proxy " & User.LegacyDN & " already exists"
existingLegDNFound = true
End If
If StrComp(address, "x500:" & User.CloudLegacyDN, vbTextCompare) = 0 Then
WScript.Echo "x500 proxy " & User.CloudLegacyDN & " already exists"
newLegDnFound = true
End If

'Add existing leg DN to proxy list
If existingLegDnFound = FALSE Then
WScript.Echo "Adding existing legacy DN " & User.LegacyDN & " to proxy addresses"
User.ProxyAddresses.Add (User.ProxyAddresses.Count+1),("x500:" & User.LegacyDN)
End If

'Add new leg DN to proxy list
If newLegDnFound = FALSE Then
'Add new leg DN to proxy addresses
WScript.Echo "Adding new legacy DN " & User.CloudLegacyDN & " to existing proxy addresses"
User.ProxyAddresses.Add (User.ProxyAddresses.Count+1),("x500:" & User.CloudLegacyDN)
End If

'Dump out new list of addresses
WScript.Echo "Original proxy addresses updated count: " & User.ProxyAddresses.Count
For i = 1 to User.ProxyAddresses.Count
WScript.Echo " proxyAddress " & i & ": " & User.ProxyAddresses(i)

'Delete the Mailbox
WScript.Echo "Opening " & userADSIPath & " as CDOEXM::IMailboxStore object"
Set Mailbox = MyUser
Wscript.Echo "Deleting Mailbox"
On Error Resume Next

'Handle any errors deleting the mailbox
If Err.Number <> 0 Then
WScript.Echo "Error " & Err.number & ". Skipping User." & vbCrLf & "Description: " & Err.Description & vbCrLf
Exit Sub
End If
On Error Goto 0

'Save and continue
WScript.Echo "Saving Changes"
WScript.Echo "Refeshing ADSI Cache"
Set Mailbox = nothing

'Mail Enable the User
WScript.Echo "Opening " & userADSIPath & " as CDOEXM::IMailRecipient"
Set MailUser = MyUser
WScript.Echo "Mail Enabling user using targetAddress " & User.CloudEmailAddress
MailUser.MailEnable User.CloudEmailAddress
WScript.Echo "Disabling Recipient Update Service for user"
MyUser.PutEx ADS_PROPERTY_APPEND, "msExchPoliciesExcluded", Array("{26491CFC-9E50-4857-861B-0CB8DF22B5D7}")
WScript.Echo "Saving Changes"
WScript.Echo "Refreshing ADSI Cache"

'Add Legacy DN back on to the user
WScript.Echo "Writing legacyExchangeDN as " & User.LegacyDN
MyUser.Put "legacyExchangeDN", User.LegacyDN

'Add old proxies list back on to the MEU
WScript.Echo "Writing proxyAddresses back to the user"
For j=1 To User.ProxyAddresses.Count
MyUser.PutEx ADS_PROPERTY_APPEND, "proxyAddresses", Array(User.ProxyAddresses(j))

'Add mail attribute back on to the MEU
WScript.Echo "Writing mail attribute as " & User.Mail
MyUser.Put "mail", User.Mail

'Add msExchMailboxGUID back on to the MEU
WScript.Echo "Converting mailbox GUID to writable format"
Dim mbxGUIDByteArray
Call ConvertHexStringToByteArray(OctetToHexString(User.MailboxGUID), mbxGUIDByteArray)
WScript.Echo "Writing property msExchMailboxGUID to user object with value " & OctetToHexString(User.MailboxGUID)
MyUser.Put "msExchMailboxGUID", mbxGUIDByteArray

WScript.Echo "Saving Changes"
WScript.Echo "Migration Complete!" & vbCrLf

End Sub

'Returns the primary SMTP address of a user
Function GetPrimarySMTPAddress(Addresses)
For Each address in Addresses
If Left(address, 4) = "SMTP" Then GetPrimarySMTPAddress = address
End Function

'Converts Hex string to byte array for writing to AD
Sub ConvertHexStringToByteArray(ByVal strHexString, ByRef pByteArray)

Set FSO = CreateObject("Scripting.FileSystemObject")
Set Stream = CreateObject("ADODB.Stream")

Temp = FSO.GetTempName()
Set TS = FSO.CreateTextFile(Temp)

For i = 1 To (Len (strHexString) -1) Step 2
TS.Write Chr("&h" & Mid (strHexString, i, 2))


Stream.Type = 1
Stream.LoadFromFile Temp

pByteArray = Stream.Read

FSO.DeleteFile Temp

Set Stream = nothing
Set FSO = Nothing

End Sub

'Converts raw bytes from AD GUID to readable string
Function OctetToHexString (arrbytOctet)

OctetToHexStr = ""
For k = 1 To Lenb (arrbytOctet)
OctetToHexString = OctetToHexString & Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2)

End Function

Sub ShowHelp()

WScript.Echo("This script runs in two modes, CSV Mode and Manual Mode." & vbCrLf & "CSV Mode allows you to specify a CSV file from which to pull user names." & vbCrLf& "Manual mode allows you to run the script against a single user.")
WSCript.Echo("Both modes require you to specify the name of a DC to use in the local domain." & vbCrLf & "To run the script in CSV Mode, use the following syntax:")
WScript.Echo(" cscript Exchange2003MBtoMEU.vbs -c x:\csv\csvfilename.csv")
WScript.Echo("To run the script in Manual Mode, you must specify the users AD Distinguished Name, Remote SMTP Address, Remote Legacy Exchange DN, and Domain Controller Name.")
WSCript.Echo(" cscript Exchange2003MBtoMEU.vbs " & chr(34) & "CN=UserName,CN=Users,DC=domain,DC=com" & chr(34) & " " & chr(34) & "" & chr(34) & " " & chr(34) & "/o=Cloud Org/ou=Cloud Site/ou=Recipients/cn=CloudUser" &
chr(34) & "")

End Sub



クラウドベースの組織が、Exchange の段階的な移行で移行したクラウド メールボックスに関する情報を収集するために実行する Windows PowerShell スクリプトです。このスクリプトでは、CSV ファイルを使用してユーザーのバッチの範囲を指定します。ユーザーのバッチを移行するときに使用したものと同じ移行用 CSV を使用することをお勧めします。

ExportO365UserInfo スクリプトを実行する場合:

  • 入力 CSV ファイルに記載されているユーザーについて、次のプロパティがクラウド メールボックスから収集されます。

    • プライマリ SMTP アドレス

    • 対応するオンプレミス メールボックスのプライマリ SMTP アドレス

    • クラウド メールボックスのその他のプロキシ アドレス

    • LegacyExchangeDN

  • 収集されたプロパティは Cloud.csv という CSV ファイルに保存されます。


オンプレミス Exchange 2003 組織が、メールボックスを MEU に変換するために実行する VB スクリプトです。このスクリプトでは Cloud.csv ファイルを使用します。Cloud.csv は、ExportO365UserInfo スクリプトの出力ファイルです。

Exchange2003MBtoMEU.vbs スクリプトを実行すると、入力 CSV ファイルに記載されている各メールボックスに対して次の処理が実行されます。

  • 入力 CSV ファイルと、オンプレミス メールボックスの情報を収集します。

  • オンプレミスとクラウド メールボックスのプロキシ アドレス一覧を作成し、MEU に追加します。

  • オンプレミス メールボックスを削除します。

  • MEU を作成し、次のプロパティを設定します。

    • legacyExchangeDN - オンプレミス メールボックスの値。

    • mail - クラウド メールボックスのプライマリ SMTP。

    • msExchMailboxGuid - オンプレミス メールボックスの値。

    • proxyAddresses - オンプレミス メールボックスとクラウド メールボックス両方の値。

    • targetAddress - オンプレミス メールボックスから読み取ります。値はクラウド メールボックスのプライマリ SMTP です。

      重要: Office 365 から Exchange 2003 への移行を有効にするには、MEU の msExchMailboxGuid 値をクラウド メールボックスの GUID と置き換える必要があります。クラウド組織のメールボックスの GUID を取得し、CSV ファイルに保存するには、次の PowerShell コマンドを実行します。

      Get-Mailbox | Select PrimarySmtpAddress, Guid | Export-csv -Path .\guid.csv

      このコマンドで、すべてのクラウド メールボックスのプライマリ SMTP アドレスと GUID が guid.csv ファイルに抽出され、現在のディレクトリに保存されます。

入力 CSV ファイルを使用してメールボックスのバッチを変換せずに、手動モードで Exchange2003MBtoMEU.vbs スクリプトを実行してメールボックスを 1 つずつ変換することもできます。この場合、次の入力パラメーターを指定する必要があります。

  • オンプレミス メールボックスの識別名 (DN)。

  • クラウド メールボックスのプライマリ SMTP アドレス。

  • クラウド メールボックスの Exchange レガシ DN。

  • Exchange 2003 組織のドメイン コントローラー名。

オンプレミス メールボックスを MEU に変換する手順

  1. クラウド組織で ExportO365UserInfo を実行します。入力ファイルとして移行バッチの CSV ファイルを使用します。このスクリプトを実行すると、Cloud.csv という CSV ファイルが作成されます。

    .\ExportO365UserInfo.ps1 <CSV input file>


    .\ExportO365UserInfo.ps1 .\MigrationBatch1.csv

    この例では、スクリプトと入力 CSV ファイルが同じディレクトリにあることを前提としています。

  2. Exchange2003MBtoMEU.vbs と Cloud.csv をオンプレミス組織の同じディレクトリにコピーします。

  3. オンプレミス組織で、次のコマンドを実行します。

    cscript Exchange2003MBtoMEU.vbs –c .\Cloud.csv <FQDN of on-premises domain controller>


    cscript Exchange2003MBtoMEU.vbs –c .\Cloud.csv


    cscript Exchange2003MBtoMEU.vbs “<DN of on-premises mailbox>” “
    <Primary SMTP of cloud mailbox>” “<ExchangeLegacyDN of cloud mailbox>”
    <FQDN of on-premises domain controller>


    cscript Exchange2003MBtoMEU.vbs “CN=Ann Beebe,
    “” “/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=d808d014cec5411ea6de1f70cc116e7b-annb”
  4. 新しい MEU が作成されたことを確認します。Active Directory ユーザーとコンピューターで、次の操作を行います。

    1. [アクション]、[検索] の順にクリックします。

    2. [Exchange] タブをクリックします。

    3. [Exchange 受信者のみを表示する] を選び、[外部メール アドレスを持つユーザー] を選びます。

    4. [検索開始] をクリックします。

    MEU に変換されたメールボックスの一覧が [検索結果] に表示されます。

  5. Active Directory ユーザーとコンピューター、ADSI エディター、または Ldp.exe を使用して、次の MEU プロパティに適切な情報が設定されていることを確認します。

    • legacyExchangeDN

    • mail

    • msExchMailboxGuid*

    • proxyAddresses

    • targetAddress

    * 前述のように、Exchange2003MBtoMEU.vbs は、オンプレミス メールボックスの msExchMailboxGuid 値を保持します。Office 365 から Exchange 2003 への移行を有効にするには、MEU の msExchMailboxGuid プロパティの値をクラウド メールボックスの GUID と置き換える必要があります。

Office Insider に参加する



フィードバックをお寄せいただき、ありがとうございます。Office サポートの担当者におつなぎいたします。