7 augusti 2026 12 min lästid

EXO-migrering utan Remote Move

Så här etableras lokala Exchange-postlådor kontrollerat som nya, tomma postlådor i Exchange Online: PST-säkerhetskopiering, CSV-godkännande, RemoteMailbox, synkronisering, validering och återställning.

En Hybrid Remote Move är den normala vägen för att flytta en lokal Exchange-postlåda med allt innehåll till Exchange Online. Alla organisationer tillåter inte denna migreringsväg. Om en säkerhetspolicy utesluter Remote Moves kan ett medvetet annorlunda tillvägagångssätt vara försvarbart: Den lokala postlådan säkerhetskopieras som PST, kopplas bort från den synkroniserade AD-användaren och en ny, tom postlåda i Exchange Online etableras för samma användare.

Denna väg är ingen postlådemigrering. Den överför varken meddelanden, kalendrar, regler eller behörigheter till molnet. PST-filen används uteslutande som säkerhetskopia och importeras inte i detta scenario. Därför är förfarandet endast lämpligt när en tom målpostlåda är verksamhetsmässigt acceptabel och förlusten av den aktiva postlådeskonfigurationen uttryckligen har godkänts.

Måltillstånd och hårda förutsättningar

Efter cutover finns samma AD-användare kvar. Lokalt hanteras den dock inte längre som UserMailbox, SharedMailbox, RoomMailbox eller EquipmentMailbox, utan som RemoteMailbox. Efter synkroniseringen representerar detta objekt den nya postlådan i Exchange Online.

Det önskade tillståndet ser ut så här:

  1. Den lokala postlådan är fullständigt säkerhetskopierad som PST.
  2. Den lokala postlådan är frånkopplad men ännu inte slutgiltigt raderad inom den konfigurerade kvarhållningstiden.
  3. Den befintliga AD-användaren är aktiverad som RemoteMailbox.
  4. Primär adress, alias och den gamla LegacyExchangeDN finns kvar.
  5. Entra Connect har synkroniserat ändringarna.
  6. En Exchange Online-tjänstplan är tilldelad för användarpostlådor.
  7. Exchange Online visar en verklig molnpostlåda och e-postflödet avslutas där.

Följande måste dessutom vara klarlagt före start:

  • PST-resursen är åtkomlig via UNC. Gruppen Exchange Trusted Subsystem har läs- och skrivbehörighet där.
  • Kontot som kör processen har hanteringsrollen Mailbox Import Export.
  • PST-filen är endast den överenskomna säkerhetskopian; ingen senare import planeras.
  • Kvarhållning, Litigation Hold, eDiscovery och regulatoriska krav har granskats separat.
  • Ombud, Send-As, Send-on-Behalf, vidarebefordringar, inkorgsregler, mobila enheter och applikationsåtkomst har inventerats.
  • Under export och omkoppling hålls inkommande meddelanden kontrollerat kvar vid den föregående gatewayen. Användare och applikationer får inte längre skriva till källpostlådan.
  • Kvarhållningen för den lokala postlådedatabasen täcker återställningsfönstret.

Varför en CSV-godkännandelista är oumbärlig

En direkt pipeline som Get-Mailbox | Disable-Mailbox är för riskabel för denna process. Den skulle även kunna omfatta system-, Discovery- eller andra ej godkända postlådor. Följande förfarande använder därför två uttryckliga godkännanden:

  • Action=CUTOVER avgör vilken rad som faktiskt får ställas om.
  • PstVerified=YES bekräftar att exportfilen har kontrollerats tekniskt och organisatoriskt.

Först skapas endast inventariet:

$CsvPath = "C:\Migration\mailboxes.csv"
$RemoteRoutingDomain = "contoso.mail.onmicrosoft.com"

Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails `
    UserMailbox,SharedMailbox,RoomMailbox,EquipmentMailbox |
    Sort-Object PrimarySmtpAddress |
    ForEach-Object {
        [pscustomobject]@{
            Identity             = $_.Identity
            DisplayName          = $_.DisplayName
            PrimarySmtpAddress   = $_.PrimarySmtpAddress.ToString()
            Alias                = $_.Alias
            SourceType           = $_.RecipientTypeDetails.ToString()
            ArchiveStatus        = $_.ArchiveStatus.ToString()
            ServerName           = $_.ServerName
            Database             = $_.Database.ToString()
            RemoteRoutingAddress = "$($_.Alias)@$RemoteRoutingDomain"
            Action               = "REVIEW"
            PstVerified          = "NO"
        }
    } |
    Export-Csv -Path $CsvPath -NoTypeInformation -Encoding UTF8
Förklarade alternativ
AlternativEffekt
Get-Mailbox -ResultSize UnlimitedTar bort standardgränsen på 1 000 resultat; utan denna parameter saknas postlådor i inventariet i stora miljöer
-RecipientTypeDetails UserMailbox,SharedMailbox,RoomMailbox,EquipmentMailboxBegränsar frågan till de fyra postlådetyper som ska ställas om; system- och Discovery-postlådor lämnas utanför
Sort-Object PrimarySmtpAddressSorterar utdata efter den primära SMTP-adressen så att CSV-filen är stabilt ordnad vid verksamhetsgranskningen
Export-Csv -PathMålsökväg för CSV-filen
-NoTypeInformationUndertrycker typrubriken #TYPE ..., som äldre PowerShell-versioner annars skriver som första rad
-Encoding UTF8Skriver filen UTF-8-kodad så att diakritiska tecken i visningsnamn bevaras korrekt

Filen rensas därefter verksamhetsmässigt. Endast faktiskt godkända postlådor får Action=CUTOVER. Systempostlådor och specialobjekt hör inte hemma i denna lista.

Fas 1: Säkerhetskopiera primär postlåda och arkiv som PST

New-MailboxExportRequest skriver endast till en UNC-sökväg. Ett unikt filnamn skapas för varje postlåda. Ett aktivt onlinearkiv i lokala Exchange exporteras separat:

$CsvPath = "C:\Migration\mailboxes.csv"
$PstShare = "\\fileserver\exchange-pst$"
$BatchName = "EXO-NewMailbox-20260807"

$targets = Import-Csv $CsvPath | Where-Object Action -eq "CUTOVER"

foreach ($row in $targets) {
    $safeName = ($row.PrimarySmtpAddress -replace '[^a-zA-Z0-9@._-]', '_')
    $primaryPath = "$PstShare\$safeName.pst"

    New-MailboxExportRequest `
        -Mailbox $row.Identity `
        -FilePath $primaryPath `
        -Name "Primary-$safeName" `
        -BatchName $BatchName

    if ($row.ArchiveStatus -eq "Active") {
        New-MailboxExportRequest `
            -Mailbox $row.Identity `
            -IsArchive `
            -FilePath "$PstShare\$safeName-archive.pst" `
            -Name "Archive-$safeName" `
            -BatchName $BatchName
    }
}
Förklarade alternativ
AlternativEffekt
Import-Csv $CsvPathLäser in godkännandelistan; varje rad blir ett objekt med CSV-kolumnerna som egenskaper
Where-Object Action -eq "CUTOVER"Bearbetar endast uttryckligen godkända rader
New-MailboxExportRequest -MailboxKällpostlåda för exporten (här Identity från CSV-raden)
-FilePathMålsökväg för PST-filen; måste vara en UNC-sökväg, eftersom cmdleten avvisar lokala sökvägar
-NameUnikt namn på begäran; möjliggör senare specifik koppling av export av primär postlåda och arkiv
-BatchNameSamlar alla begäranden från en körning under ett batchnamn; grund för statusfråga och rensning
-IsArchiveExporterar onlinearkivet i stället för den primära postlådan; därför den andra begäran per postlåda med aktivt arkiv

Exporten är inte godkänd förrän varje begäran har statusen Completed:

Get-MailboxExportRequest -BatchName $BatchName |
    Get-MailboxExportRequestStatistics -IncludeReport |
    Format-Table DisplayName,Status,PercentComplete,FailureCode,Message -AutoSize

Get-MailboxExportRequest -BatchName $BatchName |
    Where-Object Status -ne "Completed"
Förklarade alternativ
AlternativEffekt
Get-MailboxExportRequest -BatchNameListar alla exportbegäranden i angiven batch
Get-MailboxExportRequestStatistics -IncludeReportKompletterar statistiken med den detaljerade historikrapporten där felorsaker för enskilda begäranden visas
Format-Table ... -AutoSizeVisar angivna egenskaper i tabellform; -AutoSize anpassar kolumnbredderna efter innehållet
Where-Object Status -ne "Completed"Filtrerar alla ännu ej slutförda eller misslyckade begäranden; utdata måste vara tom innan processen fortsätter

Dessutom ska filernas existens, storlek, läsbarhet, övertagande av säkerhetskopian och åtkomstskydd kontrolleras. Först därefter sätts PstVerified=YES för motsvarande CSV-rad.

Fas 2: Säkerhetskopiera postlådedata och Exchange-attribut

Före den första ändringen skapas en maskinläsbar ögonblicksbild per postlåda. Den är viktigare än en skärmbild eftersom alias, GUID:er och LegacyExchangeDN senare kan rekonstrueras exakt:

$SnapshotPath = "C:\Migration\Snapshots"
New-Item -ItemType Directory -Path $SnapshotPath -Force | Out-Null

Import-Csv "C:\Migration\mailboxes.csv" |
    Where-Object { $_.Action -eq "CUTOVER" -and $_.PstVerified -eq "YES" } |
    ForEach-Object {
        $mailbox = Get-Mailbox -Identity $_.Identity
        $safeName = ($_.PrimarySmtpAddress -replace '[^a-zA-Z0-9@._-]', '_')

        $mailbox |
            Select-Object Identity,DistinguishedName,ExchangeGuid,ArchiveGuid,
                RecipientTypeDetails,PrimarySmtpAddress,EmailAddresses,
                LegacyExchangeDN,Alias,Database,ServerName |
            Export-Clixml "$SnapshotPath\$safeName.xml"
    }
Förklarade alternativ
AlternativEffekt
New-Item -ItemType Directory -Path ... -ForceSkapar katalogen för ögonblicksbilden; -Force undertrycker felet om den redan finns
Get-Mailbox -IdentityHämtar det aktuella postlådeobjektet för respektive CSV-rad
Select-Object Identity,...,ServerNameReducerar objektet till de attribut som krävs för senare rekonstruktion (GUID:er, adresser, LegacyExchangeDN, databas)
Export-ClixmlSerialiserar objektet som typbevarande CLIXML; till skillnad från CSV bevaras flervärdesfält som EmailAddresses fullständigt och kan läsas in igen med Import-Clixml

Delegeringar och vidarebefordringar kräver separata exporter. Minst följande information bör säkerhetskopieras separat:

$mailbox = Get-Mailbox -Identity user01@contoso.com

$mailbox | Format-List ForwardingAddress,ForwardingSmtpAddress,DeliverToMailboxAndForward
Get-MailboxPermission -Identity $mailbox.Identity
Get-ADPermission -Identity $mailbox.DistinguishedName
Get-InboxRule -Mailbox $mailbox.Identity
Get-CalendarProcessing -Identity $mailbox.Identity -ErrorAction SilentlyContinue
Förklarade alternativ
AlternativEffekt
Format-List ForwardingAddress,ForwardingSmtpAddress,DeliverToMailboxAndForwardVisar postlådans tre vidarebefordringsattribut i listformat
Get-MailboxPermission -IdentityListar postlådebehörigheter som Full Access
Get-ADPermission -IdentityListar AD-behörigheter på användarobjektet, däribland Send-As; förväntar sig Distinguished Name här
Get-InboxRule -MailboxListar postlådans serverbaserade inkorgsregler
Get-CalendarProcessing -IdentityVisar bokningskonfigurationen; relevant för rums- och utrustningspostlådor
-ErrorAction SilentlyContinueUndertrycker felet för postlådetyper utan bokningskonfiguration så att säkerhetskopieringen inte avbryts

Dessa konfigurationer flyttas inte automatiskt till den nya molnpostlådan.

Fas 3: Koppla bort lokal postlåda och aktivera RemoteMailbox

Själva cutovern är kort men betydelsefull. Disable-Mailbox tar bort Exchange-attributen från AD-användaren och kopplar bort den lokala postlådan. Postlådedata finns kvar som disconnected mailbox tills databasens kvarhållningstid löper ut. Direkt därefter aktiverar Enable-RemoteMailbox samma AD-användare för Exchange Online.

Följande skript bearbetar endast dubbelt godkända rader. Det bevarar den primära SMTP-adressen, alla befintliga proxyadresser och den gamla LegacyExchangeDN som X500-adress. X500-posten förhindrar NDR:er vid svar på äldre meddelanden eller gamla poster i Outlooks autoslutförande.

$CsvPath = "C:\Migration\mailboxes.csv"
$PstShare = "\\fileserver\exchange-pst$"

$targets = Import-Csv $CsvPath |
    Where-Object { $_.Action -eq "CUTOVER" -and $_.PstVerified -eq "YES" }

foreach ($row in $targets) {
    $safeName = ($row.PrimarySmtpAddress -replace '[^a-zA-Z0-9@._-]', '_')
    $pstPath = "$PstShare\$safeName.pst"

    if (-not (Test-Path $pstPath)) {
        throw "PST fehlt: $pstPath"
    }

    if ((Get-Item $pstPath).Length -eq 0) {
        throw "PST ist leer: $pstPath"
    }

    $mailbox = Get-Mailbox -Identity $row.Identity -ErrorAction Stop
    $primary = $mailbox.PrimarySmtpAddress.ToString()
    $legacyDn = $mailbox.LegacyExchangeDN

    if ($primary -ine $row.PrimarySmtpAddress) {
        throw "Primaere SMTP-Adresse stimmt nicht mit der Freigabeliste ueberein: $($row.Identity)"
    }

    $preservedAddresses = @($mailbox.EmailAddresses | ForEach-Object ToString)

    Disable-Mailbox -Identity $row.Identity -Confirm:$false

    $enableParams = @{
        Identity             = $row.Identity
        Alias                = $row.Alias
        PrimarySmtpAddress   = $primary
        RemoteRoutingAddress = $row.RemoteRoutingAddress
        ACLableSyncedObjectEnabled = $true
    }

    switch ($row.SourceType) {
        "SharedMailbox"    { $enableParams.Shared = $true }
        "RoomMailbox"      { $enableParams.Room = $true }
        "EquipmentMailbox" { $enableParams.Equipment = $true }
        "UserMailbox"      { }
        default             { throw "Nicht unterstuetzter Mailbox-Typ: $($row.SourceType)" }
    }

    Enable-RemoteMailbox @enableParams

    $orderedAddresses = @(
        "SMTP:$primary"
        $preservedAddresses |
            Where-Object { $_ -notmatch '^SMTP:' -or $_.Substring(5) -ine $primary }
        "smtp:$($row.RemoteRoutingAddress)"
        "X500:$legacyDn"
    )

    $seen = [System.Collections.Generic.HashSet[string]]::new(
        [System.StringComparer]::OrdinalIgnoreCase
    )
    $finalAddresses = foreach ($address in $orderedAddresses) {
        if ($seen.Add($address)) { $address }
    }

    Set-RemoteMailbox -Identity $row.Identity -EmailAddressPolicyEnabled $false
    Set-RemoteMailbox -Identity $row.Identity -EmailAddresses $finalAddresses
    Set-RemoteMailbox -Identity $row.Identity -PrimarySmtpAddress $primary

    Get-RemoteMailbox -Identity $row.Identity |
        Format-List DisplayName,RecipientTypeDetails,PrimarySmtpAddress,
            RemoteRoutingAddress,EmailAddresses
}
Förklarade alternativ
AlternativEffekt
Get-Mailbox -Identity ... -ErrorAction StopHämtar källpostlådan; -ErrorAction Stop gör ett uppslagsfel till ett avbrytande fel i stället för att fortsätta tyst
Disable-Mailbox -IdentityTar bort Exchange-attributen från AD-användaren och kopplar bort den lokala postlådan; data finns kvar som disconnected mailbox i databasen
-Confirm:$falseUndertrycker den interaktiva frågan; godkännande sker här via CSV-listan, inte vid prompten
Enable-RemoteMailbox -IdentityAktiverar samma AD-användare som RemoteMailbox för Exchange Online
-AliasÅterställer Exchange-aliaset till värdet från godkännandelistan
-PrimarySmtpAddressBehåller den tidigare primära SMTP-adressen
-RemoteRoutingAddressMåladress i routningsdomänen mail.onmicrosoft.com, genom vilken lokala Exchange når molnpostlådan
-ACLableSyncedObjectEnabledMarkerar objektet som ACL-kompatibelt så att behörigheter som Full Access kan utvärderas i Exchange Online efter synkroniseringen
-Shared / -Room / -EquipmentSkapar respektive specialtyp i stället för en användarpostlåda; skriptet anger exakt en växel som matchar källtypen
Set-RemoteMailbox -EmailAddressPolicyEnabled $falseUndantar objektet från e-postadressprincipen så att den inte skriver över manuellt angivna adresser
-EmailAddressesAnger den fullständiga, deduplicerade adresslistan inklusive gamla proxyadresser, routningsadress och X500-post
Get-RemoteMailbox -IdentityKontrollfråga av resultatet direkt efter omställningen

Skriptet är med avsikt inte ett helautomatiskt migreringsverktyg. Det avbryter körningen vid den första motsägelsen så att en administratör kan bedöma orsak och tillstånd. Före en produktionsbatch bör koden valideras med några få testpostlådor och de Exchange-versioner som används.

Fas 4: Synkronisera, licensiera och verifiera

Efter den lokala ändringen startas en deltacykel på Entra Connect-servern:

Start-ADSyncSyncCycle -PolicyType Delta
Förklarade alternativ
AlternativEffekt
-PolicyType DeltaSynkroniserar endast objekt som ändrats sedan den senaste cykeln; alternativet Initial skulle vara en fullständig och betydligt längre körning

För användarpostlådor måste därefter en giltig Exchange Online-tjänstplan vara tilldelad, exempelvis via gruppbaserad licensiering. Delade postlådor samt rums- och utrustningspostlådor ska bedömas enligt aktuella licensvillkor från Microsoft och de funktioner som behövs.

Etableringen är asynkron. Microsoft anger för normala ändringar vanligtvis mindre än 30 minuter, men i enskilda fall upp till 24 timmar. Under denna tid bör det föregående e-postflödet hålla kvar meddelanden kontrollerat i stället för att leverera dem till ett mål som ännu inte är klart.

Den lokala kontrollen måste nu visa en RemoteMailbox:

Get-RemoteMailbox -Identity user01@contoso.com |
    Format-List RecipientTypeDetails,PrimarySmtpAddress,RemoteRoutingAddress,EmailAddresses

Get-Mailbox -Identity user01@contoso.com -ErrorAction SilentlyContinue
Förklarade alternativ
AlternativEffekt
Get-RemoteMailbox -IdentityMåste returnera det omställda objektet som RemoteMailbox
Format-List RecipientTypeDetails,...Visar typ, adresser och routningsadress för kontroll i listformat
Get-Mailbox -Identity ... -ErrorAction SilentlyContinueMotkontroll: anropet får inte längre returnera något, eftersom det inte längre finns någon ansluten lokal postlåda; -ErrorAction SilentlyContinue undertrycker det förväntade felmeddelandet

I Exchange Online kontrolleras om den tidigare MailUser har blivit en verklig postlåda:

Get-EXORecipient -Identity user01@contoso.com |
    Format-List RecipientTypeDetails,PrimarySmtpAddress,EmailAddresses

Get-EXOMailbox -Identity user01@contoso.com |
    Format-List RecipientTypeDetails,PrimarySmtpAddress,ExchangeGuid
Förklarade alternativ
AlternativEffekt
Get-EXORecipient -IdentityVisar mottagartypen i Exchange Online; förväntat är UserMailbox respektive specialtypen, inte längre MailUser
Get-EXOMailbox -IdentityReturnerar endast verkliga molnpostlådor; en träff bekräftar slutförd etablering
Format-List ...,ExchangeGuidListar kontrollattributen; ExchangeGuid identifierar den nya molnpostlådan entydigt

Batchen räknas som slutförd först när även följande tester har lyckats:

  • Leverans externt och internt
  • Skickande externt och internt
  • Svar på ett gammalt meddelande för att kontrollera X500-adressen
  • Inloggning med Outlook och Outlook på webben
  • Delegeringar och Send-As
  • Vidarebefordringar och transportregler
  • Rums- och utrustningsbokningar
  • Applikationer, skannrar och SMTP-reläer
  • Message Trace med leverans till den nya molnpostlådan

Återställning och rensning

Den lokala källpostlådan får inte raderas med Remove-StoreMailbox under valideringsfasen. Så länge den finns som disconnected mailbox inom postlådekvarhållningen finns fortfarande en teknisk återställningsmöjlighet. En återställning kräver dock en kontrollerad återställning av RemoteMailbox-attributen och återanslutning av den lokala postlådan; samtidigt måste det förhindras att två aktiva leveransmål uppstår.

Före en återställning ska därför e-postflöde, synkroniseringsstatus och meddelanden som redan mottagits i molnet säkras. Att växla tillbaka är ingen enkel enradare och ska ingå som ett testat runbook i ändringen.

Efter godkänd acceptans rensas exportbegäranden, PST-filer arkiveras enligt skydds- och kvarhållningskonceptet och tillfälliga behörigheter på exportresursen tas bort:

Get-MailboxExportRequest -BatchName $BatchName |
    Remove-MailboxExportRequest -Confirm:$false
Förklarade alternativ
AlternativEffekt
Get-MailboxExportRequest -BatchNameVäljer exakt exportbegärandena för den slutförda batchen
Remove-MailboxExportRequest -Confirm:$falseTar bort begärandena utan fråga; själva PST-filerna påverkas inte

De disconnected mailboxes bör inte rensas slutgiltigt förrän det överenskomna återställningsfönstret har löpt ut och enligt kvarhållningskonceptet.

Slutsats

Om Hybrid Remote Moves inte är tillåtna och inga postlådedata behöver flyttas till Exchange Online kan en befintlig synkroniserad AD-användare kontrollerat ställas om från en lokal postlåda till en ny molnpostlåda. Den kritiska delen är inte Enable-RemoteMailbox, utan processkontrollen runt den: fullständig inventering, verifierad PST-säkerhetskopiering, uttryckliga godkännanden, bevarande av proxy- och X500-adresser, kontrollerat e-postflöde samt ett verkligt återställningsfönster.

Källor

  1. Microsoft Learn – Enable-RemoteMailbox

    Aktiverar en befintlig lokal AD-användare för en postlåda i den molnbaserade tjänsten och dokumenterar växlarna för användar-, delade, rums- och utrustningspostlådor.

    https://learn.microsoft.com/en-us/powershell/module/exchange/enable-remotemailbox?view=exchange-ps
  2. Microsoft Learn – New-MailboxExportRequest

    Referens för export av primära och arkiverade lokala postlådor till PST-filer.

    https://learn.microsoft.com/en-us/powershell/module/exchangepowershell/new-mailboxexportrequest?view=exchange-ps
  3. Microsoft Learn – Mailbox import and export requests

    Förutsättningar för exportresurs, behörigheter och Exchange Trusted Subsystem.

    https://learn.microsoft.com/en-us/exchange/mailbox-import-and-export-requests-exchange-2013-help
  4. Microsoft Learn – Disable or delete a mailbox in Exchange Server

    Beteendet hos Disable-Mailbox, borttagning av Exchange-attribut och kvarhållning av den frånkopplade postlådan.

    https://learn.microsoft.com/en-us/exchange/recipients/disconnected-mailboxes/disable-or-delete-mailboxes
  5. Microsoft Learn – Disconnected mailboxes

    Återanslutning, återställning och slutgiltig radering av frånkopplade postlådor.

    https://learn.microsoft.com/en-us/exchange/recipients/disconnected-mailboxes/disconnected-mailboxes
  6. Microsoft Learn – Delays in provisioning of a user or mailbox
  7. Microsoft Learn – Move mailboxes between on-premises and Exchange Online organizations

    Den vanliga Hybrid Remote Move som referens och avgränsning mot den nyetablering som beskrivs här.

    https://learn.microsoft.com/en-us/exchange/hybrid-deployment/move-mailboxes

Kommentarer

Kommentarerna hämtas från GitHub / Giscus.