Jan 28 2019 06:12 PM
Dear Adam.,
I want to share my address book between two tenants . I am confusing something about the term : address book and contacts.
Dear all friends and experts
As my understand:
In contact have all address book ? or in address have all contact ? or address book is same contacts
In my case. I want to share ( address book ) to other tenants, actually, I need share address book or contacts ?
Please give me some advise, and how to do that. Thank you so much.
Lee Nguyen
Jan 28 2019 09:25 PM
Jan 28 2019 09:30 PM
Thank you Admin,
So, actually, when people say : Share address book in O356 is share contact right ?
So this is guide for share contact ? and will I follow the the this one ?
https://support.microsoft.com/en-ca/help/10157/sharing-calendar-and-contacts-in-office-365
Thank you so much,
Lee Nguyen,
Jan 28 2019 09:36 PM
Jan 28 2019 10:20 PM
Dear Admin.,
Thank for your advises.
From your link. I know that, I need share address book to external. But, O365 do not support share address book, to do that, we need have a tool from third-party.
How to do that, my customer, they want us provide a solution for that?, So can we share address-book in O365 at the moment.
Thank you so much.,
Lee Nguyen
Jan 28 2019 10:34 PM
Jan 28 2019 10:40 PM
SolutionJan 28 2019 10:43 PM
Thank you Adam.,
In this case.
Can we create list of contact ( external ), end share to individual user in external ? , is this possible. ?
Thank you so much !
Lee Nguyen
Jan 28 2019 10:45 PM
Jan 29 2019 03:59 PM
Dear Adam.,
Thank you for your advices.,
So if i follow as the guide to share contact its mean : End-user will share contact to external ? ( individual people)
Is there any solution for share contact from server side ?
Best and regards,
Lee Nguyen
Dec 19 2019 11:27 AM
Do you have any doc's around how to do it for 2 companies that are merging? We are buying a company and I see how to setup shared free/busy but not contact list.
We will eventually use bitTitan to migrate the users to 1 main tennant but for now I would like to shared GAL and Cal not just CAL..
I was going to do this manually with CSV files for the time being but if there is an easier way that would be great.
Mar 11 2020 02:28 AM
Hi @CarlosSolrac did you ever get it to work for your 2 merging companies?
Do you have any documentation you could share?
Thank you
Mirela
Jun 16 2020 11:54 PM
Hello Techno1795,
I was searching for a solution a long time.
Here the scenario:
- company holding with 3 child companies
- all 4 companies have their own tenant
- holding is AD domain synced to O365, only cloud mailboxes
- 1 child is plain O365
- 2 childs are hybrid Exchange organizations
- organizations with local ADs are bidirectional trusted
Goal is, that all organizations see the contacts in the other ones.
I finally used Azure Automation Powershell scripts for that.
- I created multiple scripts that run once a day
- read the mailboxes from one Exchange organization or O365 tenant
- add a suffix to the display name like "(Organization One)" (for users belonging to multiple orgs.)
- use one attribute to identify the organization
- create a contact in each other organization, update if already exists
- run a second script or add a section to the first script that parses all contacts in the tenants and checks, if the mailbox still exists in the organization. If not, delete the contact. That cleans up your contacts. But be careful an check, if the connection to the organization is OK. Otherwise during connection problems, you'll lose all contacts till next run. 😉
Not nice, but it works.
Jul 17 2020 11:21 AM
@Bernd_SchneiderI have a similar issue that I'm dealing with and would appreciate if you could share a detailed insight on the script used and steps taken.
Jul 17 2020 11:28 AM
@Mirela_MM what I ended up doing was this:
I enabled the free/busy sharing via the documented MS way. I then created a contact for every user in the new company in the existing company and vice versa so it is a date and time solution, it solved my problem as we only needed about 30-45 days to move all the users.
I hope that helps.
Jul 20 2020 12:17 AM
@Sunil50 Hi, that's the script.
It could be optimized, but it works:
# Publish O365 Users as Contacts in another tenant
# BSSE GmbH, Bernd Schneider
#
# Note:
# The text “ (Source-Tenant)” is appended to every contact to mark the contacts
# of the source company.
# Use at own risk!
# Connect Source-Tenant
Write-Output "Connect Source-Tenant"
$credObject = Get-AutomationPSCredential -Name "Source-Tenant-Admin"
Connect-MsolService -Credential $credObject
# Get Source-Tenant Users Excluding Guest Accounts
Write-Output "Read Source-Tenant MSOLUser"
$mySourceUsers=Get-MSOLUser -all|Where-Object {($_.UserPrincipalName -LIKE "*@Source-Tenant.*") -AND (-NOT ($_.UserPrincipalName -LIKE ("*#EXT#*"))) }
Get-PSSession | Remove-PSSession
# Create AzureRunAsConnection
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
Write-Output "Logging in to Azure..."
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch
{
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
# Connect Target-Tenant
Write-Output "Connect Target-Tenant"
$credObject = Get-AutomationPSCredential -Name "Target-Tenant-Admin"
Connect-MsolService -Credential $credObject
# Function: Update-ExchangeOnlineContact
function Update-ExchangeOnlineContact {
param (
$User
)
$NameAndOrg=$User.DisplayName+" (Source-Tenant)"
Set-Mailcontact $User.UserPrincipalName -Name $NameAndOrg -DisplayName $NameAndOrg -FirstName $User.FirstName -LastName $User.Lastname `
-CustomAttribute9 "BSSE Office 365 Synchronisation"
}
# Function: Update-ExchangeOnlineContactEmail
function Update-ExchangeOnlineContactEmail {
param (
$User
)
$NameAndOrg=$User.DisplayName+" (Source-Tenant)"
Get-MailContact -resultsize 99999|where-object {$User.DisplayName -eq $NameAndOrg}| ´
Set-Mailcontact -ExternalEmailAddress $User.UserPrincipalName -CustomAttribute9 "BSSE Office 365 Synchronisation"
}
# Function: New-ExchangeOnlineContact
function New-ExchangeOnlineContact {
param (
$User
)
$NameAndOrg=$User.DisplayName+" (Source-Tenant)"
New-Mailcontact -Name $NameAndOrg -DisplayName $NameAndOrg -FirstName $User.FirstName -LastName $User.LastName `
-ExternalEmailAddress $User.UserPrincipalName
Set-Mailcontact -Identity $User.UserPrincipalName -CustomAttribute9 "BSSE Office 365 Synchronisation"
}
# Function: Connect to Exchange Online
function Connect-ExchangeOnline {
param (
$Creds
)
Write-Output "Connecting to Exchange Online"
Get-PSSession | Remove-PSSession
$Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Creds -Authentication Basic -AllowRedi...
$Commands = @("Get-Recipient","New-Mailcontact","Set-Mailcontact","Set-Mailbox","Get-Mailbox","Get-Contact","Get-MailContact", "Remove-Mailcontact", "Get-MailUser")
Import-PSSession -Session $Session -DisableNameChecking:$true -AllowClobber:$true -CommandName $Commands | Out-Null
}
# Connect to Exchange Online
Write-Output "Connect Target-Tenant Exchange"
Connect-ExchangeOnline -Creds $credObject
# Load Data in Buffer
$SourceDisplay=Get-MailContact -resultsize 99999|where-object {$_.DisplayName -like "*(Source-Tenant)"}
$SourceContacts=Get-MailContact -resultsize 99999|where-object {$_.PrimarySMTPAddress -like "*Source-Tenant.*"}
$SourceExternal=Get-MailUser -resultsize 99999|where-object {$_.PrimarySMTPAddress -like "*Source-Tenant.*" -and $_.RecipientTypeDetails -eq "GuestMailUser"}
# Check if new Account using Email address
ForEach($User in $MySourceUsers) {
$TempContact = $SourceContacts|where {$SourceContacts.PrimarySMTPAddress -eq ($User.UserPrincipalName)}
if ($TempContact) {
Write-Output ("Existing Contact: "+$User.DisplayName)
# Check for Update using time last changed
if ($User.Value.WhenModified.addday -gt (get-date).adddays(-2)) {
Write-Output ("Update Contact: "+$User.DisplayName)
Update-ExchangeOnlineContact -User $User
}
}
else {
$TempContact = $SourceExternal|where {$SourceExternal.PrimarySMTPAddress -like $User.UserPrincipalName}
# Check if external contact, if yes, ignore
if ($TempContact) {
Write-Output ("External Contact: "+$User.UserPrincipalName)
}
else {
$TempDisplay = $SourceDisplay|where {$SourceDisplay.DisplayName -eq ($User.DisplayName + " (Source-Tenant)")}
# Check, if same Displayname exists
if ($TempDisplay) {
# Change Email-Address
Write-Output ("New Email Address: "+$User.DisplayName+", "+$User.UserPrincipalName)
Update-ExchangeOnlineContactEmail -User $User
}
else {
# Create new Contact
Write-Output ("New Contact: "+$User.DisplayName)
New-ExchangeOnlineContact -User $User
}
}
}
}
$MySourceUsers|ft UserPrincipalName, DisplayName
# Check Account deletion
ForEach($Contact in $SourceContacts) {
$TempUser = $MySourceUsers|where {($MySourceUsers.UserPrincipalName) -like $Contact.PrimarySMTPAddress}
if ($TempUser) {
Write-Output ("Do not delete: "+$Contact.identity)
}
else {
Write-Warning ("Delete Contact: "+$Contact.identity)
Write-Output ($Contact.PrimarySMTPAddress)
$contact|Remove-MailContact -confirm:$false
}
}
# Close Session
Get-PSSession | Remove-PSSession
Write-Output "Script Completed!"
Jul 20 2020 12:22 AM
Jul 20 2020 05:04 AM
Apr 05 2022 05:54 AM
Jan 28 2019 10:40 PM
Solution