tetranet

Exchange Hybrid - von on-prem Public Folders zu Shared Mailboxes mit Kategorie-Problemen

Hallo Community,

im Rahmen eines Migrationsprojekts versuche ich öffentliche Ordner von einem Exchange 2019 CU14 on-premise auf den Exchange Online zu verschieben. Bei den öffentlichen Ordnern handelt es sich um einige Kalender und eine Anzahl von Adress-Verzeichnissen.
Mittels Azure AD Sync wurde eines Synchronisation der Benutzerkonten mit aktivierter Option "öffentliche Exchange Email-Ordner" aktiviert. Der Ordner "Microsoft Exchange System Objects" ist bei den zu synchronisierenden OUs ebenfalls enthalten.

Die beiden Exchange Server (on-premise und Online) sind mittels einer Full-Hybrid Konfiguration (ausgeführt mittels HCW) miteinander verbunden und es wurden bereits einige Postfächer erfolgreich in die Cloud umgezogen.

Bei der Public-Folder Migration habe ich mich an learn.microsoft.com/en-us/exchange/hybrid-deployment/set-up-mode ... gehalten.

Die Postfach für öffentliche Ordner wurde erfolgreich mit dem EXO synchronisiert, das CMDlet "Get-Mailbox -PublicFolder" führt jedoch zu einer leeren Ausgabe.

Bei der Prüfung einer Email-Adressen der öfffentlichen Ordner fiel mir auf, dass diese noch auf die Active Directory-Domäne <name>.local lauten, weshalb ich für einige Ordner diese manuell auf eine routbare Domäne die auf dem on-premise und dem EXO als aktzeptierte Domäne vorhanden ist geändert.

In der Organisations-Config des EXO habe ich die Einstellungen für öffentliche Ordner mittels "Set-OrganizationConfig -PublicFoldersEnabled Remote" von Local auf Remote geändert.

Zudem habe ich das Sync-Script "Sync-ModernMailPublicFolders.ps1" mit dem Parameter -WhatIf ausgeführt, was zu folgendem Ergebnis führt:
Checking for mail-enabled System folders...
Found 0 mail-enabled System folders.
Getting all public folders. This might take a while...
Found 70 public folders. 6 of those are mail-enabled. 0 folders are mail-enabled with no AD object. 6 folders are mail-enabled and are properly linked to an existing AD object. Getting all MailPublicFolder objects... 0 MailPublicFolders are orphaned. Building EntryId HashSets... 0 orphaned MailPublicFolder objects. 0 of those orphans point to mail-enabled folders that point to some other object. 0 of those orphans point to mail-disabled folders. No folders need to be mail-disabled. No orphaned MailPublicFolders were found. No duplicate MailPublicFolders were found. No mail-disabled public folders with proxy GUIDs were found. No disconnected MailPublicFolders were found. Done! [10.06.2025 10:20:55] Creating an Exchange Online remote session...
[10.06.2025 10:21:48] Exchange Online remote session created successfully.
[10.06.2025 10:21:48] Enumerating local mail enabled public folders...
[10.06.2025 10:21:50] Mail public folders enumeration completed: 6 local folder(s) found.
[10.06.2025 10:21:50] Enumerating Exchange Online mail enabled public folders...
[10.06.2025 10:21:50] Mail public folders enumeration completed: 0 Exchange Online folder(s) found.

Sync local changes to Exchange Online
The following local mail public folder changes were detected and will be applied to Exchange Online: 6 object(s)
created, 0 updated and 0 deleted. Do you really want to proceed?
[N] No [Y] Yes [?] Hilfe (Standard ist "N"): Y
WhatIf: Öffentliche E-Mail-Ordner –Identität:"Name1" wird aktiviert.
WhatIf: Öffentliche E-Mail-Ordner –Identität:"Name 2" wird aktiviert.
...
[10.06.2025 10:22:09] Syncing of mail public folder objects into Active Directory completed: 0 objects created, 0 objects updated and 0 objects deleted.

Für mich sieht das so aus, als müsste die Migration der öffentlichen Ordner möglich sein, trotz manueller Synhjronisation von "Azure AD Connect" und langem Warte ist die Aiusgabe von "Get-Mailbox -PublicFolder" immer noch leer.

Ich habe die Anleitung so verstanden, dass die öffentlichen Ordner bereits vor der Ausführung des Sync-Scripts dem EXO bekannt sein müssten.
Liege da falsch? Habe ich sonst etwas übersehen?

Bin für jeden Hinweis dankbar.

Grüße
Tobias
Auf Facebook teilen
Auf X (Twitter) teilen
Auf Reddit teilen
Auf Linkedin teilen

Content-ID: 673287

Url: https://administrator.de/forum/exchange-hybrid-migration-public-folder-673287.html

Ausgedruckt am: 08.07.2025 um 08:07 Uhr

tetranet
tetranet 11.06.2025 um 15:42:43 Uhr
Edit: Habe den Titel angepasst um der Entwicklung Rechnung zu tragen

Nachdem bereits nach EXO migrierte Benutzer Zugriff auf die Daten in den öffentlichen Ordnern benötigen habe ich die Flucht nach vorne angetreten:

- Export der Inhalte der öffentlichen Ordner in PST-Dateien
- Erstellung eines Postfachs in EXO und Import der PSTs unter Kalender bzw. Kontakte
- Einbindung des Postfachs in das Outlook der betroffenen Anwender

Die Benutzer können nun auf die Kalender bzw. die Adressbücher zugriffen und die Daten sind vorhanden. Bisher wurde in einem der Kalender viel mit Kategorien gearbeitet und dies führt nun zu Probleme die sich wie folgt äußern:

- Beim erstmaligen Öffnen des Kalenders ist alles in Ordnung, d.h. die grüne Kategorie ist grün, die blaue Kategorie wird in blau dargestellt, die violette Kategorien ist violett und die orangefarbene Kategorie erstrahlt in orange, usw.
- wird nun auf einen Kalendereintrag (ie übrigens alle als ungelesen gekennzeichnet sind) geklickt fange die Farben der Kalendereinträge an sich zu ändern, d.h. die grüne und orangefarbene Kategorie sind beide orange, beim öffnen eines weiteren Eintrags ändern sich dann wieder die Farben und die grüne und orangefarbene Kategorie sind nun beide grün.
- Es gibt allerdings Kategorien die immer ihre Farbe behalten (blau und violett)
- manchmal (aber nicht immer) führt das ausblenden des Kalenders (also das Entfernen des Hakens beim Kalender des Ziel-Postfachs dazu, dass sich die Kategoriefarben auf die korrekten Werte zurücksetzen.

Ich hatte zwischendurch den Verdacht, dass die "ungelesen"-Markierung der Kalender-Einträge die Ursache der Farbwechsel sein könnte, bin mir aber inzwischen nicht mehr sicher.
Die Idee alle Einträge durch manuelles Anklicken auf "gelesen" zu setzen habe ich wieder verworfen, da es sich um über 10000 Einträge handelt..

Hat jemand schon einmal einen derartigen Effekt beobachtet, und weiß wie die Farbgebung von Kategorien wieder uter Kontrolle gebracht werden kann, so dass die Kalendereinträge ihre korrekte Farbe behalten?

Grüße

Tobias
tetranet
Lösung tetranet 23.06.2025 um 16:55:20 Uhr
Um die unterschiedlichen Kategorien auf den einzelnen Clients unter Kontrolle zu bekommen habe ich in Zusammenarbeit mit dem Kunden in einem Outlook die korrekten Kategorien erstellt, mittels eines Makros exportiert und sie in die andere Outlooks importiert. Das Makro habe ich vor längerer Zeit von der Webseite outlook-stuff.com heruntergeladen, wo es aber nicht mehr zum Download verfügbar ist. Ich nehme mir deshalb die Freiheit den Quellcode hier zu posten:

Option Explicit
 
'-------------------------------------------------------------------------  
' API-Deklarationen zum Lesen von Binär-Werten aus der Registrierung  
' Nur für Outlook 2002/2003 erforderlich  
'-------------------------------------------------------------------------  
Private Const KEY_READ As Long = &H20019
Private Const HKEY_CURRENT_USER As Long = &H80000001
 
Private Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias _  
        "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, _  
        ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As _
        Long) As Long
 
Private Declare PtrSafe Function RegQueryValueEx Lib "advapi32.dll" Alias _  
        "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _  
        ByVal lpReserved As Long, lpType As Long, lpData As Any, _
        lpcbData As Long) As Long
 
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long  
 
'-------------------------------------------------------------------------  
' Datei zum Speichern und Wiederherstellen der Kategorien  
'-------------------------------------------------------------------------  
' XP:  
'Private Const CATFILE As String = _  
    "C:\Temp\CategoriesTransfer.txt"  
' Vista / 7:  
Private Const CATFILE As String = _
    "C:\Temp\CategoriesTransfer.txt"  
 
Public Sub ExportCategories()
 
    '=====================================================================  
    ' Exportiert alle Kategorien aus der Standard-PST-Datei ab Outlook® 2007  
    ' in eine Textdatei  
    ' (c) Peter Marchert - http://www.outlook-stuff.com  
    ' 2008-11-21 Version 1.0.0  
    '=====================================================================  
 
    Dim objCategories As Object
    Dim objCategory As Object
    Dim lngFF As Long
 
    '---------------------------------------------------------------------  
    ' Eventuell bereits vorhandene Export-Datei löschen  
    '---------------------------------------------------------------------  
    If Dir(CATFILE) <> "" Then Call Kill(CATFILE)  
 
    '---------------------------------------------------------------------  
    ' Freie Dateinummer ermitteln  
    '---------------------------------------------------------------------  
    lngFF = FreeFile
 
    '---------------------------------------------------------------------  
    ' Export-Datei schreibend öffnen  
    '---------------------------------------------------------------------  
    Open CATFILE For Output As #lngFF
 
    '---------------------------------------------------------------------  
    ' Verweis auf Kategorien-Objekt setzen  
    '---------------------------------------------------------------------  
    Set objCategories = Outlook.GetNamespace("Mapi").Categories  
 
    '---------------------------------------------------------------------  
    ' Alle Kategorien bearbeiten  
    '---------------------------------------------------------------------  
    For Each objCategory In objCategories
 
        With objCategory
 
            '-------------------------------------------------------------  
            ' Haupteigenschaften in Export-Datei schreiben (Name, Farbe  
            ' und Tastaturzugriff)  
            '-------------------------------------------------------------  
            Print #lngFF, .Name & ";" & .Color & ";" & .ShortcutKey  
 
        End With
 
    Next
 
    '---------------------------------------------------------------------  
    ' Export-Datei wieder schliessen  
    '---------------------------------------------------------------------  
    Close #lngFF
 
    '---------------------------------------------------------------------  
    ' Meldung an Benutzer ausgeben  
    '---------------------------------------------------------------------  
    MsgBox "Exportierte Kategorien: " & objCategories.Count _  
        , vbInformation + vbOKOnly
 
    '---------------------------------------------------------------------  
    ' Objekte löschen  
    '---------------------------------------------------------------------  
    Set objCategories = Nothing
    Set objCategory = Nothing
 
End Sub
 
Public Sub ImportCategories()
 
    '=====================================================================  
    ' Importiert Kategorien aus einer Textdatei (ab Outlook® 2007)  
    ' (c) Peter Marchert - http://www.outlook-stuff.com  
    ' 2012-11-28 Version 1.1.0  
    ' 2008-11-21 Version 1.0.0  
    '=====================================================================  
 
    Dim objCategories As Outlook.Categories
    Dim vbResult As VbMsgBoxResult
    Dim strCategory As String
    Dim aryCategory() As String
    Dim lngFF As Long
    Dim lngCategories As Long
 
    '---------------------------------------------------------------------  
    ' Verweis auf Kategorien-Objekt setzen  
    '---------------------------------------------------------------------  
    Set objCategories = Outlook.GetNamespace("Mapi").Categories  
 
    '---------------------------------------------------------------------  
    ' Sind Kategorien vorhanden?  
    '---------------------------------------------------------------------  
    If objCategories.Count > 0 Then
 
        '-----------------------------------------------------------------  
        ' Vorhandene Kategorien löschen?  
        '-----------------------------------------------------------------  
        vbResult = MsgBox("Sollen die vorhandenen Kategorien gelöscht werden?", _  
            vbQuestion + vbYesNoCancel + vbDefaultButton2, "Kategorien importieren")  
 
        '-----------------------------------------------------------------  
        ' Antwort auswerten  
        '-----------------------------------------------------------------  
        Select Case vbResult
            Case vbYes:
                If Not DeleteCategories(objCategories) Then GoTo ExitProc
            Case vbNo:
                ' Nichts machen  
            Case vbCancel:
                GoTo ExitProc
        End Select
 
    End If
 
    '---------------------------------------------------------------------  
    ' Freie Dateinummer ermitteln  
    '---------------------------------------------------------------------  
    lngFF = FreeFile
 
    '---------------------------------------------------------------------  
    ' Import-Datei nicht vorhanden?  
    '---------------------------------------------------------------------  
    If Dir(CATFILE) = "" Then  
        MsgBox "Die Importdatei """ & CATFILE & """ wurde nicht gefunden." _  
            , vbCritical + vbOKOnly
        GoTo ExitProc
    End If
 
    '---------------------------------------------------------------------  
    ' Import-Datei zum Lesen öffnen  
    '---------------------------------------------------------------------  
    Open CATFILE For Input As #lngFF
 
    '---------------------------------------------------------------------  
    ' Import-Datei abarbeiten  
    '---------------------------------------------------------------------  
    Do While Not EOF(lngFF)
 
        '-----------------------------------------------------------------  
        ' 1 Zeile der Import-Datei einlesen  
        '-----------------------------------------------------------------  
        Line Input #lngFF, strCategory
 
        '-----------------------------------------------------------------  
        ' Zeileninhalt in ein Feld laden  
        '-----------------------------------------------------------------  
        aryCategory() = Split(strCategory, ";")  
 
        '-----------------------------------------------------------------  
        ' Prüfen, ob die Kategorie schon vorhanden ist (0=Name)  
        '-----------------------------------------------------------------  
        If Not CategoryExists(aryCategory(0)) Then
 
            '-------------------------------------------------------------  
            ' Anzahl importierter Kategorien erhöhen  
            '-------------------------------------------------------------  
            lngCategories = lngCategories + 1
 
            '-------------------------------------------------------------  
            ' Kategorie importieren (0=Name, 1=Farbe, 2=Tastaturzugriff)  
            '-------------------------------------------------------------  
            objCategories.Add aryCategory(0), aryCategory(1), aryCategory(2)
 
        End If
 
    Loop
 
    '---------------------------------------------------------------------  
    ' Import-Datei wieder schliessen  
    '---------------------------------------------------------------------  
    Close #lngFF
 
    '---------------------------------------------------------------------  
    ' Meldung an Benutzer ausgeben  
    '---------------------------------------------------------------------  
    If MsgBox("Importierte Kategorien: " & lngCategories & vbCrLf & _  
        vbCrLf & "Importdatei jetzt löschen?", vbInformation _  
        + vbYesNo + vbDefaultButton2) = vbYes Then Call Kill(CATFILE)
 
ExitProc:
 
    '---------------------------------------------------------------------  
    ' Objekte löschen  
    '---------------------------------------------------------------------  
    Set objCategories = Nothing
 
End Sub
 
Private Function DeleteCategories(ByVal objCategories As Outlook.Categories) As Boolean
 
    '=====================================================================  
    ' Löscht vorhandene Kategorien  
    ' Ab Outlook 2007  
    ' (c) Peter Marchert - http://www.outlook-stuff.com  
    ' 2012-11-28 Version 1.0.0  
    '=====================================================================  
    
    Dim intCategories As Integer
    Dim intIndex As Integer
    Dim intDeleted As Integer
    Dim intErrors As Integer
 
    On Error Resume Next
 
    '---------------------------------------------------------------------  
    ' Anzahl Kategorien ermitteln  
    '---------------------------------------------------------------------  
    intCategories = objCategories.Count
 
    '---------------------------------------------------------------------  
    ' Alle Kategorien durchlaufen und löschen  
    '---------------------------------------------------------------------  
    For intIndex = intCategories To 1 Step -1
 
        '-----------------------------------------------------------------  
        ' Fehler zurücksetzen  
        '-----------------------------------------------------------------  
        Err.Clear
 
        '-----------------------------------------------------------------  
        ' Kategorie löschen  
        '-----------------------------------------------------------------  
        Call objCategories.Remove(intIndex)
 
        '-----------------------------------------------------------------  
        ' OK?  
        '-----------------------------------------------------------------  
        If Err.Number = 0 Then
            intDeleted = intDeleted + 1
        Else
            intErrors = intErrors + 1
        End If
 
    Next
 
    '---------------------------------------------------------------------  
    ' Meldung an Benutzer  
    '---------------------------------------------------------------------  
    If MsgBox("Kategorien vorher: " & intCategories & vbCrLf & vbCrLf & _  
           "Gelöscht: " & intDeleted & vbCrLf & _  
           "Fehler: " & intErrors & vbCrLf & vbCrLf & _  
           "Kategorien nachher: " & objCategories.Count, _  
           vbInformation + vbOKCancel, "Kategorien löschen") = vbOK Then  
        DeleteCategories = True
    Else
        DeleteCategories = False
    End If
 
    '---------------------------------------------------------------------  
    ' Objekte löschen  
    '---------------------------------------------------------------------  
    Set objCategories = Nothing
 
End Function
 
Private Function CategoryExists(ByVal strName As String) As Boolean
 
    '=====================================================================  
    ' Prüft, ob die Kategorie "strName" schon vorhanden ist  
    ' (c) Peter Marchert - http://www.outlook-stuff.com  
    ' 2008-11-21 Version 1.0.0  
    '=====================================================================  
 
    Dim objCategories As Object
    Dim objCategory As Object
 
    '---------------------------------------------------------------------  
    ' Verweis auf Kategorien-Objekt setzen  
    '---------------------------------------------------------------------  
    Set objCategories = Outlook.GetNamespace("Mapi").Categories  
 
    '---------------------------------------------------------------------  
    ' Alle Kategorien durchlaufen  
    '---------------------------------------------------------------------  
    For Each objCategory In objCategories
 
        '-----------------------------------------------------------------  
        ' Kategoriename schon vorhanden?  
        '-----------------------------------------------------------------  
        If objCategory.Name = strName Then
            CategoryExists = True
            Exit For
        End If
 
    Next
 
    '---------------------------------------------------------------------  
    ' Objekte löschen  
    '---------------------------------------------------------------------  
    Set objCategories = Nothing
    Set objCategory = Nothing
 
End Function
 
Public Sub Export200XCategories()
 
    '=====================================================================  
    ' Schreibt alle Kategorien aus der Registrierung in eine Textdatei.  
    ' Nur für Outlook 2002/2003 erforderlich  
    ' (c) Peter Marchert - http://www.outlook-stuff.com  
    ' 2008-11-21 Version 1.0.0  
    '=====================================================================  
 
    Dim aryCategories() As String
    Dim strMasterList As String
    Dim strCategory As String
    Dim strVer As String
    Dim strRegKey As String
    Dim lngIndex As Long
    Dim lngFF As Long
 
    '---------------------------------------------------------------------  
    ' Eventuell bereits vorhandene Datei löschen  
    '---------------------------------------------------------------------  
    If Dir(CATFILE) <> "" Then Call Kill(CATFILE)  
 
    '---------------------------------------------------------------------  
    ' Freie Dateinummer ermitteln  
    '---------------------------------------------------------------------  
    lngFF = FreeFile
 
    '---------------------------------------------------------------------  
    ' Datei schreibend öffnen  
    '---------------------------------------------------------------------  
    Open CATFILE For Output As #lngFF
 
    '---------------------------------------------------------------------  
    ' Outlook®-Version ermitteln  
    '---------------------------------------------------------------------  
    Select Case Left(Outlook.Version, 2)
        Case "10": strVer = "10.0"   ' Outlook® 2002  
        Case "11": strVer = "11.0"   ' Outlook® 2003  
    End Select
 
    '---------------------------------------------------------------------  
    ' Registrierungsschlüssel zusammensetzen  
    '---------------------------------------------------------------------  
    strRegKey = "Software\Microsoft\Office\" & strVer & "\Outlook\Categories"  
 
    '---------------------------------------------------------------------  
    ' Hauptkategorieliste aus Registrierung lesen  
    '---------------------------------------------------------------------  
    strMasterList = RegRead(strRegKey)
 
    '---------------------------------------------------------------------  
    ' Hauptkategorieliste in ein Feld laden  
    '---------------------------------------------------------------------  
    aryCategories() = Split(strMasterList, ";")  
 
    '---------------------------------------------------------------------  
    ' Alle Kategorien in die Textdatei schreiben  
    '---------------------------------------------------------------------  
    For lngIndex = 0 To UBound(aryCategories())
 
        If Asc(aryCategories(lngIndex)) <> 0 Then
 
            '-------------------------------------------------------------  
            ' Name wird in die Datei geschrieben. -1 = Keine Farbe festlegen  
            ' (macht Outlook beim Importieren). 0 = Kein Tastaturzugriff.  
            '-------------------------------------------------------------  
            Print #lngFF, aryCategories(lngIndex) & ";-1;0"  
 
        End If
 
    Next
 
    '---------------------------------------------------------------------  
    ' Textdatei wieder schliessen  
    '---------------------------------------------------------------------  
    Close #lngFF
 
    '---------------------------------------------------------------------  
    ' Meldung an Benutzer ausgeben  
    '---------------------------------------------------------------------  
    MsgBox "Exportierte Kategorien: " & UBound(aryCategories()) + 1 _  
        , vbInformation + vbOKOnly
 
    '---------------------------------------------------------------------  
    ' Objekte löschen  
    '---------------------------------------------------------------------  
    Erase aryCategories()
 
End Sub
 
Private Function RegRead(ByVal strSection As String) As String
 
    '=====================================================================  
    ' Liest Binär-Daten aus der Registry  
    ' Nur für Outlook 2002/2003 erforderlich  
    ' (c) Peter Marchert - http://www.outlook-stuff.com  
    ' 2008-11-21 Version 1.0.0  
    '=====================================================================  
 
    Dim lngHandle As Long
    Dim lngReturn As Long
    Dim bytData() As Byte
    Dim lngDataType As Long
    Dim lngBufferSize As Long
 
    On Error Resume Next
 
    '---------------------------------------------------------------------  
    ' Registryschlüssel öffnen  
    '---------------------------------------------------------------------  
    Call RegOpenKeyEx(HKEY_CURRENT_USER, strSection, 0&, KEY_READ, lngHandle)
 
    '---------------------------------------------------------------------  
    ' Datengröße bestimmen  
    '---------------------------------------------------------------------  
    Call RegQueryValueEx(lngHandle, "MasterList", 0&, 3, ByVal 0&, lngBufferSize)  
 
    '---------------------------------------------------------------------  
    ' Daten lesen  
    '---------------------------------------------------------------------  
    ReDim bytData(lngBufferSize - 1) As Byte
    Call RegQueryValueEx(lngHandle, "MasterList", 0&, 3, bytData(0), lngBufferSize)  
 
    '---------------------------------------------------------------------  
    ' Daten als String zurückgeben  
    '---------------------------------------------------------------------  
    RegRead = CStr(bytData)
 
    '---------------------------------------------------------------------  
    ' Schlüssel wieder schliessen  
    '---------------------------------------------------------------------  
    Call RegCloseKey(lngHandle)
 
End Function

Im Code ist viel von Outlook 2003/2007 und ähnlichen Versionen die Rede, es funktionierte bei mir aber auch unter Office 365.

Hinweis:
Das Original-Makro läuft nur auf 32-Bit Systemen. Ich habe deshalb in den Deklarationen der Funktionen "PtrSafe" hinzugefügt, was ausreicht um das Makro "64-Bit tauglich" zu machen.

Grüße
Tobias