Office 365 groups Write back without Azure AD Premium

As discussed in previous post on Office 365 group that there are customer requirements where they want that on-premise users should be able to send email to office 365 groups but they need Group write-back feature which is part of Azure ad premium & they need to be at-least on Exchange 2013.

There is workaround of creating a corresponding mail contact for each office 365 group in on-premise Environment.(Target address would be .mail.onmicrosft.com)

If we follow the work around than admins have to monitor manually and than ADD/Delete the corresponding mail contacts in their On-premise Environment which is kind of a PAIN.

Thanks to Powershell, with some innovation I was able to built the first version of Office 365 Group Write Back that can be scheduled via task Scheduler. This will monitor any New Office 365 groups and Create a corresponding mail contacts , also if Office 365 group is deleted it will perform the delete.

Requirements for this Solution:

  • Separate OU Named “Office 365 Groups” (you can pick your own name)
  • Remove this OU from AAD synchronization.
  • One of the CustomAttribute (I am using CustomAttribute1 for storing GUID)
  • Rights on Exchange Online.
  • Rights on On-premise for creating/removing mail contacts in the above OU.

Solution Logic:

  • Fetch all Office 365 groups from Exchange Online.
  • Fetch all Mail contacts in Office 365 groups OU in On-premise.
  • Compare the GUID with Onpremsie mail contact.
  • If group contact is not present in onpremise than create it.
  • ADD Alias@domain.mail.onmicrosoft.com to office 365 group if not already present.
  • If group contact is present in onpremise but no corresponding group on cloud than delete it.
  • Any exceptions/errors are captured
  • Count of changes in a day if exceed certain value code will exit.
  • Report of Changes will be generated & sent on email.

Download the Solution ZIP file from below Link:

https://github.com/VikasSukhija/Downloads/blob/master/O365GroupsWriteBack.zip

capture

Update O365GrpWrtBack.ps1

LaunchEOL -user “EolAdmin@domain.com” -Encrypted “01000000d”

I have included the encryptpass inside the solution, just run the batch file & encrypt the password that you can use above to schedule the script.(encrypted password will get stored in securepassword.txt)

Note: This encryption step needs to be done from account/server from which you will schedule the script.

capture

$hybmaildomain = “@domain.mail.onmicrosoft.com” ##for target Address (mail routing)

$o365groupsOU = “domain.com/o365Groups” ##OU for Creating/deleting mail Contacts
$countofchanges = “10” ## count of changes.

$email1 = “VikasS@labtest.com”
$from = “o365GroupWriteBack@labtest.com”
$smtpserver = “smtpserver”

After changing all these as per your environment , we are all set.

Schedule the Batch file & don’t forget to fill start in folder.

capture

You will notice that All mail contacts corresponding to office 365 groups will be created.

If you have any that you have manually created, please update the GUID for them in cutomattribute1 so that these are not deleted.
capture

PowerShell Code:

<#     
    .NOTES 
    =========================================================================== 
     Created on:       1/6/2017 10:46 AM 
     Created by:       Vikas Sukhija (http://syscloudpro.com) 
     Organization:      
     Filename:         O365GrpWrtBack.ps1 
    =========================================================================== 
    .DESCRIPTION 
        This Script will writeback the Office 365 Groups as Mailcontacts 
        to onpremise enviornment so that email routing can happen from onpremise  
        Users to Office365 Groups 
#> 
##############Load Functions & modules################# 
$Error.clear() 
. .\LoadFunctions.ps1 
 
If ((Get-PSSnapin | where { $_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010" }) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
 
LaunchEOL -user "EolAdmin@domain.com" -Encrypted "01000000d" 
if ($error) { ProgressBar -title "Error loading Functions" -timer 10; exit } 
 
#########Variables and Logs ######### 
$log = Write-Log -Name "Transcript_o365group""o365_group_log" -Ext log -folder logs 
$report = Write-Log -Name "Report_o365groups""Report_Contacts" -Ext csv -folder report 
$hybmaildomain = "@domain.mail.onmicrosoft.com" 
$Collection = @() 
$o365groupsOU = "domain.com/o365Groups" 
$countofchanges = "10" 
 
$email1 = "VikasS@labtest.com" 
$from = "o365GroupWriteBack@labtest.com" 
$smtpserver = "smtpserver" 
 
Start-Transcript -Path $log[0] 
#######Fetch all office 365 groups#### 
try 
{ 
    $o365groups = Get-EOLUnifiedGroup -ResultSize:unlimited | select Alias, DisplayName, Guid, EmailAddresses, PrimarySmtpAddress, RequireSenderAuthenticationEnabled, AccessType, ManagedBy, ManagedByDetails -ErrorAction Stop 
} 
catch 
{ 
    $_ 
    $exception = $_.Exception.Message 
    $date = get-date 
    Add-Content $log[1] "$date - Error Fetching all Unified groups" 
    Add-Content $log[1] $exception 
    Send-Email -From $from -To $email1 -subject "O365 group writeback Error fetching Groups" -smtpserver $smtpserver -body $exception 
    break 
} 
############Fetch All Mail Contacts#### 
try 
{ 
    $o365onpremContacts = Get-MailContact -OrganizationalUnit $o365groupsOU -ResultSize:unlimited | select Alias, DisplayName, CustomAttribute1, EmailAddresses, PrimarySmtpAddress, RequireSenderAuthenticationEnabled -ErrorAction Stop 
} 
catch 
{ 
    $_ 
    $exception = $_.Exception.Message 
    $date = get-date 
    Add-Content $log[1] "$date - Error Fetching all Unified groups" 
    Add-Content $log[1] $exception 
    Send-Email -From $from -To $email1 -subject "O365 group writeback Error fetching Contacts" -smtpserver $smtpserver -body $exception 
    break 
} 
 
if ($o365onpremContacts) 
{ 
    try 
    { 
        ######################Find Additions and Deletions########### 
        $cmpo365groups = $o365groups | select Alias, guid 
        $cmpo365onpremContacts = $o365onpremContacts | select Alias, @{ n = 'guid'; e = { $_.customattribute1 } } 
         
        $Changes = Compare-Object $cmpo365groups $cmpo365onpremContacts -property guid | 
        Select-Object guid, @{ 
            n = 'State'; e = { 
                If ($_.SideIndicator -eq "=>") { "Delete" } 
                elseif ($_.SideIndicator -eq "<=") { "ADD" } 
                else { "Ignore" } 
            } 
        } 
        if ($changes) 
        { 
            $Changes | Export-Csv $report[0] -NoTypeInformation 
        } 
    } 
    catch 
    { 
        $_ 
        $exception = $_.Exception.Message 
        $date = get-date 
        Add-Content $log[1] "$date - Error Finding Changes" 
        Add-Content $log[1] $exception 
        Send-Email -From $from -To $email1 -subject "O365 group writeback Error Finding Changes" -smtpserver $smtpserver -body $exception 
        break 
    } 
 
####Process Changes######### 
    if ($changes) 
    { 
        if ($Changes.count -ge $countofchanges) 
        { 
            Write-Host "Exit as Changes are more than $countofchanges" 
            ProgressBar -Title "Exit as Changes are more than $countofchanges" -Timer 10 
            Send-Email -From $from -To $email1 -subject "O365 group writeback Exit - Changes are more than $countofchanges" -smtpserver $smtpserver 
            Exit 
        } 
        else 
        { 
            $Changes | ForEach-Object{ 
                $uniqueid = $_.guid 
                $getgrp = $o365groups | where{ $_.guid -eq $uniqueid } 
                $getmailcontact = $o365onpremContacts | where{ $_.customattribute1 -eq $uniqueid } 
                $alscontact = $getmailcontact.Alias 
                $Als = $getgrp.Alias 
                $Disp = $getgrp.DisplayName 
                $hybemail = $Als + $hybmaildomain 
                $umeamil = $getgrp.emailaddresses 
                $prim = $getgrp.primarysmtpaddress 
                $sendout = $getgrp.RequireSenderAuthenticationEnabled 
                $mcoll = "" | select Alias, DisplayName, guid, PrimarySmtp, Status 
                if ($_.state -eq "ADD") 
                { 
                    ####ADD the mail.onmicrosft address to Unified group/create Contact#### 
                    Try 
                    { 
                        if ($umeamil -contains "smtp:$hybemail") 
                        { 
                             
                            New-MailContact -Name $Disp -Alias $Als -ExternalEmailAddress $hybemail -OrganizationalUnit $o365groupsOU 
                            ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            while (!(Get-MailContact $Als -ErrorAction SilentlyContinue)) 
                            { 
                                ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            } 
                            Set-MailContact -Identity $Als -RequireSenderAuthenticationEnabled:$sendout -customattribute1:$uniqueid 
                            $chckpem = (get-mailcontact $als).emailaddresses | Select -ExpandProperty addressstring 
                            if ($chckpem -contains $prim) 
                            { 
                                Write-Host "Primary $prim Address is alredy Present in $Als" -ForegroundColor Green 
                            } 
                            else 
                            { 
                                Write-Host "Primary $prim Address will be added to $Als" -ForegroundColor Green 
                                Set-MailContact -Identity $Als -EmailAddresses @{ add = $prim } 
                            } 
                        } 
                        else 
                        { 
                            set-eolunifiedgroup -identity $Als -EmailAddresses @{ add = $hybemail } 
                            New-MailContact -Name $Disp -Alias $Als -ExternalEmailAddress $hybemail -OrganizationalUnit $o365groupsOU 
                            ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            while (!(Get-MailContact $Als -ErrorAction SilentlyContinue)) 
                            { 
                                ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            } 
                            Set-MailContact -Identity $Als -RequireSenderAuthenticationEnabled:$sendout -customattribute1:$uniqueid 
                            $chckpem = (get-mailcontact $als).emailaddresses | Select -ExpandProperty addressstring 
                            if ($chckpem -contains $prim) 
                            { 
                                Write-Host "Primary $prim Address is alredy Present in $Als" -ForegroundColor Green 
                            } 
                            else 
                            { 
                                Write-Host "Primary $prim Address will be added to $Als" -ForegroundColor Green 
                                Set-MailContact -Identity $Als -EmailAddresses @{ add = $prim } 
                            } 
                        } 
                        $mcoll.Alias = $als 
                        $mcoll.DisplayName = $disp 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $prim 
                        $mcoll.status = "Created" 
                    } 
                    catch 
                    { 
                        $exception = $_.Exception.Message 
                        $date = get-date 
                        Add-Content $log[1] "$date - Exception occured Processing $Disp" 
                        Add-Content $log[1] $exception 
                        Send-Email -From $from -To $email1 -subject "O365 group writeback Exception occured Processing $Disp" -smtpserver $smtpserver -body $exception 
                        $mcoll.Alias = $als 
                        $mcoll.DisplayName = $disp 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $prim 
                        $mcoll.status = "Error" 
                    } 
                     
                } 
                if ($_.state -eq "Delete") 
                { 
                    try 
                    { 
                        Remove-MailContact -Identity $alscontact -Confirm:$false 
                        $mcoll.Alias = $alscontact 
                        $mcoll.DisplayName = $getmailcontact.DisplayName 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $getmailcontact.PrimarySMTPAddress 
                        $mcoll.status = "Removed" 
                        ProgressBar -Title "Removing Mail contact $alscontact" -Timer 10 
                    } 
                    catch 
                    { 
                        $exception = $_.Exception.Message 
                        $date = get-date 
                        Add-Content $log[1] "$date - Exception occured deleting $alscontact" 
                        Add-Content $log[1] $exception 
                        Send-Email -From $from -To $email1 -subject "O365 group writeback Exception occured deleting $alscontact" -smtpserver $smtpserver -body $exception 
                        $mcoll.Alias = $alscontact 
                        $mcoll.DisplayName = $getmailcontact.DisplayName 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $getmailcontact.PrimarySMTPAddress 
                        $mcoll.status = "Error" 
                    } 
                } 
                $Collection +$mcoll 
            } 
        } 
    } 
    if ($Collection) 
    { 
        $Collection | Export-Csv $report[1] -NoTypeInformation 
        Send-Email -From $from -To $email1 -subject "O365 group writeback Report" -smtpserver $smtpserver -attachment $report[1] 
    } 
} 
else 
{ 
    Write-Host "All Contacts will be Created" -ForegroundColor Green 
    try 
    { 
 $o365groups | ForEach-Object{ 
 $Disp = $_.DisplayName
 $Als = $_.Alias
 $hybemail = $Als + $hybmaildomain
 $uniqueid = $_.guid
 $sendout = $_.RequireSenderAuthenticationEnabled
 $prim = $_.primarysmtpaddress
 $umeamil = $_.emailaddresses
 if ($umeamil -notcontains "smtp:$hybemail")
 {
 set-eolunifiedgroup -identity $Als -EmailAddresses @{ add = $hybemail }
 }
            New-MailContact -Name $Disp -Alias $Als -ExternalEmailAddress $hybemail -OrganizationalUnit $o365groupsOU 
            while (!(Get-MailContact $Als -ErrorAction SilentlyContinue)) 
            { 
                ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
            } 
            Set-MailContact -Identity $Als -RequireSenderAuthenticationEnabled:$sendout -customattribute1:$uniqueid 
            $chckpem = (get-mailcontact $als).emailaddresses | Select -ExpandProperty addressstring 
            if ($chckpem -contains $prim) 
            { 
                Write-Host "Primary $prim Address is alredy Present in $Als" -ForegroundColor Green 
            } 
            else 
            { 
                Write-Host "Primary $prim Address will be added to $Als" -ForegroundColor Green 
                Set-MailContact -Identity $Als -EmailAddresses @{ add = $prim } 
            } 
        } 
         
    } 
    catch 
    { 
        $_ 
        $date = get-date 
        Add-Content $log[1] "$date - Error Creating All Contacts" 
        Add-Content $log[1] $exception 
        Send-Email -From $from -To $email1 -subject "O365 group writeback Error Creating All Contacts" -smtpserver $smtpserver -body $exception 
    } 
     
} 
RemoveEOL 
Stop-Transcript 
############################################################# 

Thanks for Reading

Sukhija Vikas

http://syscloudpro.com

 

 

 

 

Leave a comment