Umwandeln einer Exchange Verteilergruppe zu Office 365 Cloudverteiler

Posted on: January 19, 2016 Posted by: Philipp Comments: 0

Umwandeln einer Exchange Verteilergruppe zu Office 365 Cloudverteiler

Im Zuge der Exchange-Hybrid Migration zu Office365 mit der Implementierung von AADConnect können die Exchange Verteiler unter Office365 nicht bearbeitet werden. Der Grund hierfür ist, dass das führende System das Active Directory ist, da die Gruppen aus diesem synchronisiert werden. Erkennbar ist das am Status
“Mit Active Directory synchronisiert”

Während der Migrationsphase finde ich diesen Zustand, das Anwender die Verteilerlisten mittels Outlook nicht bearbeiten können, vertretbar. Nach Abschluss sollte der Umstand aufgelöst werden.

Voraussetzung damit die Gruppen im Office365 neu erstellt werden können ist, dass die Synchronisierung der Gruppe beendet wird. Je nach Konfiguration des AADConnect durch das entziehen des Sync Attribut oder durch das Verschieben in eine andere Organisationseinheit. Hierdurch löscht der AADConnect die Gruppe aus Office365. Unter dem Active Directory ist diese weiterhin verfügbar. Das entwickelte Skript überprüft anhand der primären SMTP Adresse die Existenz im Office 365 und Active Directory. Wenn eine Gruppe nur im Active Directory existiert wird die Verteilergruppe als Cloud Verteiler mit allen Eigenschaften und allen Mitgliedern angelegt.

Das Skript lasse ich alle 15 Minuten starten. Der Abgleich von 1000 Gruppen dauert 110 Sekunden. Die X500 Adresse wird aus Kompatibilität zu alten E-Mails  aus der ExchangeLegacyDN generiert und übernommen.

Wenn eine Gruppe migriert werden soll, entzieht der Helpdesk das Sync Attribut. Das Skript läuft:

Spätestens nach 15 Minuten ist die Gruppe migriert und “in Cloud”

Optimierungspotential:

Statt mittels der primären SMTP Adresse die Gruppen zu vergleichen könnte dies auch mit der immutableID erfolgen. Hierdurch können SMTP Konflikte umgangen werden. Das Skript könnte auch Office365 Cloud Gruppen und Exchange Gruppen Synchronisieren wenn der Timestamp oder die USN geprüft wird. Hierdurch könnte man statt die Gruppen mittels AADConnect bereitzustellen diese direkt über das Skript bereitstellen. Somit könnten diese sowohl unter Exchange als auch Office365 über Outlook bearbeitet werden.

#Constant
$Domain = "semi-precious.de"
$defaultManagedby = "dl_user@semi-precious" #Dieser User wird benötigt da beim anlegen einer Verteiler-Gruppe ein Besitzer gesetzt werden muss
$ErrorActionPreference = "silentlycontinue"

function main{
# Import O365 Shell
. C:\Scripts\CredMan.ps1 #Laden der Zugangsdaten aus dem Windows Tresor --> https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Credentials-d44c3cde
$cred = Read-Creds O365
$pass = $cred.CredentialBlob.tostring()
$secpass = $pass | ConvertTo-SecureString -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential `
     -argumentlist $cred.UserName, $secpass
$o365Session= New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $Credentials -Authentication Basic -AllowRedirection
        Import-PSSession $o365Session -Prefix "Cloud_" -DisableNameChecking
# Import Exchange Shell
. $env:ExchangeInstallPath\bin\RemoteExchange.ps1
        Connect-ExchangeServer –auto

# Check AD Settings to view the entire forest
if ((get-ADServerSettings).ViewEntireForest -like $false){Set-ADServerSettings -ViewEntireForest $true}

"Get onprem Distribution Groups"
$onpremDistributionGroup = Get-DistributionGroup -ResultSize unlimited -ErrorAction silentlycontinue
"Get O365 Distribution Groups"
$cloudDistributionGroup = Get-Cloud_DistributionGroup -ResultSize unlimited -ErrorAction silentlycontinue
"Compare Results"
#Possibilities
$compare =  Compare-Object $onpremDistributionGroup.PrimarySmtpAddress $cloudDistributionGroup.PrimarySmtpAddress -IncludeEqual
$onlyinAD = $compare | where {$_.SideIndicator -eq "<=" -and $_.InputObject -like "*@$($Domain)"} $onlyinCloud = $compare | where {$_.SideIndicator -eq "=>"} #for future use
$presentinADandCloud = $compare | where {$_.SideIndicator -eq "=="} #for future use
#Create O365 Group
foreach ($obj in $onlyinAD.InputObject)
    {
    foreach ($Group in $onpremDistributionGroup)
        {
        if ($Group.PrimarySmtpAddress -eq $obj.ToString())
            {
            "Processing $($obj.ToString())"
            [Array]$ManagedBy = $Group.ManagedBy
            $ManagedBy = $ManagedBy | foreach {(get-recipient $_)}
            if (!($ManagedBy)){$ManagedBy=$defaultManagedby
                       "Create Group with default ManagedBy"
            New-Cloud_DistributionGroup -Name $Group.Name -DisplayName $Group.DisplayName -PrimarySmtpAddress $Group.PrimarySmtpAddress.ToString() -ManagedBy $ManagedBy
            Update-O365DistributionGroup $Group
            }
            else{
                       "Create Group with ManagedBy"
            New-Cloud_DistributionGroup -Name $Group.Name -DisplayName $Group.DisplayName -PrimarySmtpAddress $Group.PrimarySmtpAddress.ToString() -ManagedBy $ManagedBy.Alias
            Update-O365DistributionGroup $Group
            }

            }
        }

    }
}

function Update-O365DistributionGroup
{
Param($Group)
#Write DistributionGroup Note
"Update Group-Notes"
            Set-Cloud_Group -Identity $Group.Name -Notes (Get-Group -Identity $Group.Name).Notes
#Generate ManagedBy
[Array]$ManagedBy = $Group.ManagedBy
 $ManagedBy = $ManagedBy | foreach {(get-recipient $_)}
 $ManagedBy = $ManagedBy.Alias
 if (!($ManagedBy)){$ManagedBy=$defaultManagedby}

#Write DistributionGroup Settings
"Update Group-Settings"
            Set-Cloud_DistributionGroup -Identity $Group.Name `
            -MailTip $Group.MailTip `
            -EmailAddresses $Group.EmailAddresses.ProxyAddressString `
            -CustomAttribute1 $Group.CustomAttribute1 `
            -CustomAttribute2 $Group.CustomAttribute2  `
            -CustomAttribute3 $Group.CustomAttribute3  `
            -CustomAttribute4 $Group.CustomAttribute4  `
            -CustomAttribute5 $Group.CustomAttribute5  `
            -CustomAttribute6 $Group.CustomAttribute6  `
            -CustomAttribute7 $Group.CustomAttribute7 `
            -CustomAttribute8 $Group.CustomAttribute8  `
            -CustomAttribute9 $Group.CustomAttribute9  `
            -CustomAttribute10 $Group.CustomAttribute10  `
            -CustomAttribute11 $Group.CustomAttribute11  `
            -CustomAttribute12 $Group.CustomAttribute12  `
            -CustomAttribute13 $Group.CustomAttribute13  `
            -CustomAttribute14 $Group.CustomAttribute14  `
            -CustomAttribute15 $Group.CustomAttribute15 `
            -ExtensionCustomAttribute2 $Group.ExtensionCustomAttribute2 `
            -ExtensionCustomAttribute3 $Group.ExtensionCustomAttribute3 `
            -ExtensionCustomAttribute4 $Group.ExtensionCustomAttribute4 `
            -HiddenFromAddressListsEnabled $Group.HiddenFromAddressListsEnabled `
            -BypassNestedModerationEnabled $Group.BypassNestedModerationEnabled `
            -ReportToManagerEnabled $Group.ReportToManagerEnabled `
            -ReportToOriginatorEnabled $Group.ReportToOriginatorEnabled `
            -SendOofMessageToOriginatorEnabled $Group.SendOofMessageToOriginatorEnabled `
            -ExtensionCustomAttribute5 "$($Group.Guid);$($Group.WhenChanged)" `
            -RequireSenderAuthenticationEnabled $Group.RequireSenderAuthenticationEnabled `
            -RejectMessagesFromDLMembers $Group.RejectMessagesFromDLMembers `
            -GrantSendOnBehalfTo $Group.GrantSendOnBehalfTo `
            -MemberJoinRestriction $group.MemberJoinRestriction `
            -MemberDepartRestriction $Group.MemberDepartRestriction `
            -RejectMessagesFrom $Group.RejectMessagesFrom `
            -ModeratedBy $Group.ModeratedBy `
            -ModerationEnabled $Group.ModerationEnabled

#Add X500 Address
            Set-Cloud_DistributionGroup -Identity $Group.Name -EmailAddresses @{Add = "X500:$($Group.legacyExchangeDN)"}
#Add Member
"Update Group-Member"
            $Member = Get-DistributionGroupMember $Group.Name
            $Member.PrimarySmtpAddress | % {
            try{
            Add-cloud_DistributionGroupMember $Group.Name -Member $_.tostring()| out-null
            }
            catch{}
            }
            }

main