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
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.
$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.
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.
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