Giter VIP home page Giter VIP logo

ews-office365-contact-sync's Introduction

EWS Contact Sync

Utilizes both Exchange Web Services and Office 365 Remote PowerShell Services to sync your Global Address List to any/every user in the directory.

Why would I want to use this? iPhone/Android devices don't currently support offline Global Address List synchronization. By loading the Global Address List contacts into a folder within user's mailbox, you can circumvent this limitation.

Features

  • Fetch a list of contacts using the Office 365 Directory
  • Import the list of contacts into a specified user's Office 365 mailbox
  • You can run the sync for any number of users
  • Specify a custom contact folder
  • Authenticates using a AzureApp & certificate based authenication (See guide below)

Getting Started

  1. Install the Exchange Online Powershell V3.2.0

    Install-Module -Name ExchangeOnlineManagement -RequiredVersion 3.2.0 -Force
    
  2. Create an Azure app & certificate file using the tutorial here, taking note of the differences below.

    • The app will require Global Reader permission (Referenced in tutorial).
    • Take a record of the Azure app's Application (client) ID as you'll need this later.
    • Enable Public Client Flows in the Azure App (Authenication -> Allow public client flows)
    • Specify a redirect URI (Authenication -> Platform Configurations -> Add a platform -> Mobile and desktop applications -> Enable 'https://login.microsoftonline.com/common/oauth2/nativeclient' as a redirect URI.)
    • When updating the app's Manifest, insert the below code for requiredResourceAccess instead of following what the tutorial suggests. The below version also includes permissions for acting as an EWS Application. We'll need EWS to manage the contacts in each user's mailbox.
          "requiredResourceAccess": [
          {
              "resourceAppId": "00000002-0000-0ff1-ce00-000000000000",
              "resourceAccess": [
                  {
                      "id": "dc50a0fb-09a3-484d-be87-e023b12c6440",
                      "type": "Role"
                  },
                  {
                      "id": "dc890d15-9560-4a4c-9b7f-a736ec74ec40",
                      "type": "Role"
                  }
              ]
          }
      ]
      
  3. Export your certificate password to a CliXml SecureString file. See Create-SecureCertificatePassword.ps1 in the Getting Started folder for an example on how to do this.

  4. You'll also need your Office 365 organization URL (Ends in .onmicrosoft.com). Do find this, navigate to the Office 365 Admin Center -> Setup -> Domains

  5. Download the latest version of the script here.

  6. You may need to unblock the script's included .dll files. To do this, navigate to EWSContacts\Module\bin -> For each .dll file, right click on the file -> Check 'Unblock'

  7. To test the script, run for a single mailbox in your directory. See below for an example (batch file)

    @echo off
    cd "%~dp0EWS-Office365-Contact-Sync"
    
    PowerShell.exe -ExecutionPolicy Bypass ^
    -File "%CD%\EWSContactSync.ps1" ^
    -CertificatePath "C:\Users\johndoe\Desktop\automation-cert.pfx" ^
    -CertificatePasswordPath "C:\Users\johndoe\Desktop\SecureCertificatePassword.cred" ^
    -ClientID "36ee4c6c-0812-40a2-b820-b22ebd02bce3" ^
    -FolderName "Directory Contacts" ^
    -LogPath "%~dp0Logs" ^
    -MailboxList [email protected] ^
    -ExchangeOrg "mycompany.onmicrosoft.com" ^
    -ModernAuth
    pause
    
  8. Once you're ready, specify DIRECTORY for MailboxList. This will sync the contacts for all users in your directory. See below for an example (batch file)

    @echo off
    cd "%~dp0EWS-Office365-Contact-Sync"
    
    PowerShell.exe -ExecutionPolicy Bypass ^
    -File "%CD%\EWSContactSync.ps1" ^
    -CertificatePath "C:\Users\johndoe\Desktop\automation-cert.pfx" ^
    -CertificatePasswordPath "C:\Users\johndoe\Desktop\SecureCertificatePassword.cred" ^
    -ClientID "36ee4c6c-0812-40a2-b820-b22ebd02bce3" ^
    -FolderName "Directory Contacts" ^
    -LogPath "%~dp0Logs" ^
    -MailboxList DIRECTORY ^
    -ExchangeOrg "mycompany.onmicrosoft.com" ^
    -ModernAuth
    pause
    

Prerequisites

  • Azure app with EWS and User read permissions (See above guide on how to set this up.)
  • Verify the neccessary Office 365 URLs are whitelisted in your environment. All Microsoft 365 Common URLs with ID#56 on this page should be allowed.
  • Powershell Version 5.0+
  • Think of a unique folder name (Any contacts not in the Global Address List will be deleted from the folder, so I don't recommend using 'Contacts' as the name.)

Deployment

See EWSContactSync.ps1 for documentation on optional parameters for filtering conatcts, mailboxes, etc...

Built With

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

  • Ryan Graham - Initial work - grahamr975
  • Glenn Scales - EWSContacts Powershell Module - gscales

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Acknowledgments

ews-office365-contact-sync's People

Contributors

grahamr975 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ews-office365-contact-sync's Issues

Parameters for ModernAuth

Hello,

can someone explain, how to correctly use ModernAuth with this script?
We would like to keep BasicAuth disabled for our O365-Tenant, because Microsoft will disable it in 2022.

Any suggestion will be appreciated. Thank you very much in advance.

Not working with error message

Dear,

I have follow the steps but still geting an error:

  1. create an .cred file for my admin account.
  2. Create an bat file with following rules:
    @echo off
    cd "%~dp0EWS-Office365-Contact-Sync"

PowerShell.exe -ExecutionPolicy Bypass ^
-File "C:\Users\cade\Desktop\EWS-Office365-Contact-Sync-master\EWSContactSync.ps1" ^
-CredentialPath "C:\temp\caglar.cred" ^
-FolderName "TEST Caglar" ^ name for the outlook contact folder. This folder does not exist. So it will create by it self on the user contact folder ?
-LogPath "%~dp0Logs" ^
-MailboxList icttest@.....,nl ^
-ModernAuth
pause

VERBOSE: Loading module from path 'C:\Users\cade\Desktop\EWS-Office365-Contact-Sync-master\EWSContacts\Module\bin\Microsoft.Exchange.WebServices.dll'.

TerminatingError(Import-Module): "Could not load file or assembly 'file:///C:\Users\cade\Desktop\EWS-Office365-Contact-Sync-master\EWSContacts\Module\bin\Microsoft.Exchange.WebServices.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)"

Error running script

Hi, I'm trying to run the script as is with my global admin account on my regular user account, gets the following. You have any tip?

2020-10-12 09:33:43 INFO Beginning contact sync for myname@domain's mailbox
VERBOSE: Loading module from path 'C:\scripts\EWS-Office365-Contact-Sync-master\EWSContacts\Module\bin\Microsoft.Exchange.WebServices.dll'.
VERBOSE: Using EWS dll from Local Directory
VERBOSE: Using Modern Auth
VERBOSE: Loading module from path 'C:\scripts\EWS-Office365-Contact-Sync-master\EWSContacts\Module\bin\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'.
PS>TerminatingError(New-Object): "A constructor was not found. Cannot find an appropriate constructor for type Microsoft.Exchange.WebServices.Data.OAuthCredentials."

TerminatingError(New-Object): "A constructor was not found. Cannot find an appropriate constructor for type Microsoft.Exchange.WebServices.Data.OAuthCredentials."
TerminatingError(New-Object): "A constructor was not found. Cannot find an appropriate constructor for type Microsoft.Exchange.WebServices.Data.OAuthCredentials."
2020-10-12 09:33:44 ERROR Failed to Sync-ContactList for [email protected] A constructor was not found. Cannot find an appropriate constructor for type Microsoft.Exchange.WebServices.Data.OAuthCredentials.


Windows PowerShell transcript end
End time: 20201012093344


Attributes cant be found

Hello Ryan,

first of all, thanks for the great Code.

I´m getting following message when i try to run your script for some users:
2021.03.03 16:15:38 INFO Updating Contact: [email protected]
2021.03.03 16:15:38 ERROR Failed to sync [email protected] contact to [email protected]'s mailbox Die Eigenschaft "GivenName" wurde für dieses Objekt nicht gefunden.
Vergewissern Sie sich, dass die Eigenschaft vorhanden ist und festgelegt werden kann.
(The Attribute "givenname" wasn´t found for this object.
Check if the attribute exists and can be allocated.) this may derive a little from my translation, but basically that.

The tricky part seems to be, that those contacts can be synched to most of the mailboxes.

Maybe you could give me a hint where to look for the missing configuration or why it wouldnt find those attributes.

Best regards
Adrian

DIRECTORY Error

Hello :)

I'm getting the following error when I wish to apply the GAL to DIRECTORY.

image

but works when I specify what mailbox should get GAL contacts

The Autodiscover service couldn't be loaded

When I try to run the script and to the part where it start to load the EWSContact module.
I get the following error:
ERROR Failed to Sync-Contactlist for [email protected]. Exception on calling "AutodiscoverURL" with "2" arguments: The Autodiscover service couldn't be located.

"The account does not have permission to impersonate the requested user."

Good afternoon.

I keep running into this issue no matter what user I use. And they're all global admins. It errors out while it's trying to create a new folder. Can you offer some assistance? Thanks!

VERBOSE: Loading module from path 'C:\Scripts\EWS-Office365-Contact-Sync-master\EWSContacts\Module\bin\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'.
PS>TerminatingError(Get-EXCContactFolder): "Exception calling "Bind" with "2" argument(s): "The account does not have permission to impersonate the requested user.""
VERBOSE: Phone not found, attempting to create now...
2020/08/21 15:39:08 FATAL Failed verify that Phone exists for [email protected] Exception calling "Save" with "1" argument(s): "The account does not have permission to impersonate the requested user."
PS>TerminatingError(Write-Log): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Failed verify that Phone exists for [email protected]"

TerminatingError(Write-Log): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Failed verify that Phone exists for [email protected]"
TerminatingError(Write-Log): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Failed verify that Phone exists for [email protected]"
TerminatingError(Write-Log): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Failed verify that Phone exists for [email protected]"
2020/08/21 15:39:08 ERROR Failed to Sync-ContactList for [email protected] Failed verify that Phone exists for [email protected]

Sync only enabled user accounts

Hi Ryan!

If possible how can I reach that only AD enabled user accounts create as contacts with your script?
Currently if a user left the company and the phone number which was belinging to him/her moved to another user the same phone number will present on both contacts. Thats why I would like to create contacts only for AD enabled users as those who left the company are in disabled state.

Cheers!

Failed to fetch Global Address List Contacts from Office 365

When i try to use the script, i've the error :

`Write-Log : Failed to fetch Global Address List Contacts from Office 365
Directory
Au caractère Ligne:50 : 3

  •     Write-Log -Level "FATAL" -Message "Failed to fetch Global Address
    

List Contact ...

    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorExcep
   tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
   n,Write-Log`

Contacts in GAL are not Sync

Hello !

I'm using the script with O365 and it's working well for me and create a contacts from all users that have mailbox .

But in my GAL I also have contacts (they doesn't require a licence), this is just a contact with a mail and a number, but no mailbox attached, so, in outlook I can browse them in the GAL subsection named "All Contacts" .

image

Theses contacts seems to be avoided / not synced in the folder where the script is creating local contacts.

Is this a known issue ? did I miss a configuration ? or any plans to implement that also ?

Regards !

Folder not found in Mailbox

I have the problem that the created folder is not found in the personal contacts in the mailbox.
the public autodiscover points to Exchange Online, but it cannot find two arguments.
enclosed the error message when running the script:

FATAL Failed verify that "" exists for "[email protected]" Exception when calling "AutodiscoverUrl" with 2 argument(s): "The Autodiscover service could not be located."
Write log : Failed verify that "GAL" exists for [email protected]
In line:56 characters:4

how can i solve this issue?

Sync doesn't work

I was expecting this script would remove accounts that are no longer listed in the GAL. Do I have the wrong assumption, or isn't it working as it supposed to work?

Need to add exclusion list

Good morning.
I have the script working in my environment, but I was curious if there was a way to put in an exclude list? I have about 15 numbers that we don't want to sync, but their AD accounts have phone numbers that need to stay.

Thanks!

Contact sync android/ios not working

This script was created for contact sync on android/ios but the contact sync is only working if I override the default contact folder, creating a secondary/ sub-folder works but the IOS / Android device does not sync the contacts.

is this known? or am I missing something?

Filter the sync to specific domains

Hi

Is it possible to filter the sync to only hit a certain domain?

fx domain.dk only get the DK contacts
domain.se only gets the SE contacts?

When we have changes to the users numbers, they doesnt get updated in the users folders? - is there a way to make this happen?

folder not found

Hello

I'm getting the following error after running the script.
VERBOSE: Importing function 'Write-AdminAuditLog'.
2020/01/16 23.32.45 INFO Beginning contact sync for [email protected]'s mailbox
Error Folder Not Found check path and try again
2020/01/16 23.33.12 INFO Creating Contact: [email protected]
Contact Created
2020/01/16 23.33.14 INFO Creating Contact: [email protected]
Contact Created
2020/01/16 23.33.14 INFO Creating Contact: [email protected]
Contact Created
Transcript stopped, output file is C:\Users\jonas.DESKTOP-U02QVVD\OneDrive\Skrivebord\EWS-Office365-Contact-Sync-master\logs\PowerShell_transcript.DESKTOP
-U02QVVD.FZkCu_R5.20200116233231.txt

Photo sync

Hello

Photos are not showing on mobile ? i have to goto my outlook account, clik on each user i have synced. Then clik on update.
After the update is finish, it showing the picture of user on my computer. After about 15 min it works on my mobil.

But why does the photo not showing up auto?

Understanding the Script

Hello everyone,

I came across the script here. This is my first post at Github.

I have to implement it for my employer as it is written in the script and unfortunately I have some problems with understanding.

Basically it works. Many thanks to the author.

Problem no 1:
In the mailboxlist I can enter an address or DIRECTORY. Both works. But I have to fill a handful of addresses. As in the example of the description with $MailboxList = @("[email protected]", "[email protected]", "[email protected]") it does not work. I tried some variants, unfortunately without success.

Problem no 2:
I would like to use the optional parameters ExcludeContactsWithoutPhoneNumber and ExcludeSharedMailboxContacts In the script I set the parameters to $true. Unfortunately the script does not run anymore. I have tried some variants here as well, unfortunately without success.

It would be great if someone could help me with this. I am not the fittest in scripting and programming.

Thanks and best regards
Alex

Feature Request: Add parameter to not delete old contacts

Hi there,

I am wondering if a parameter can be added so that when called, the script doesn't delete contacts that don't exist in the GAL?

A little background, our organization for a few reasons uses the Outlook app exclusively on all phones, with the contact sync feature turned on. This feature unfortunately only syncs from the default Contacts folder, not any custom folders. Running the script against the contacts folder results in any custom contacts being bulldozed over.

A workaround I implemented myself was to simply change Line 63 of Sync-ContactList.ps1 to $MailboxContactsToBeDeleted = $null.

The end result is that custom contacts are retained, and actual employees are kept up-to-date with the latest information. This was pretty easy to communicate to employees what to expect.

Anyways, if this could be an official parameter to not delete contacts, that would be great. My worry is updating to a newer release in the future and forgetting about that line, and end up forgetting to reset it and deleting people's contacts.

Thanks for reading!

"Access is denied" M365 with MFA

I cannot seem to get the settings to work, but I do have the Azure Active Directory Security defaults turned on.
(https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults)
I'm getting the following error:

TerminatingError(New-PSSession): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: [outlook.office365.com] Connecting to remote server outlook.office365.com failed with the following error message : Access is denied. For more information, see the about_Remote_Troubleshooting Help topic."
At line:77 char:3

  •     Write-Log -Level "FATAL" -Message "Failed to fetch Global Add ...
    
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    • FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Write-Log

Run this in Azure with Automation Account

Hi,

Is it possible to get this scripts running in an "Automation Account" service in Azure?
I didn't find it in the Modules gallery, but it is possible to upload module through a zip file.

Only accounts with a mailbox are included

Hi Ryan,
thanks for the script.

Is it possible to get all users in Office 365 with an email adress?

In your old script you used "$Users = Get-User -Filter {WindowsEmailAddress -ne $null} -ResultSize unlimited", it seems that in your new script only users with a mailbox in Exchange Online are included.
We have an Exchange Hybrid environment and not all users are migrated to Exchange Online.

Thanks for response

Script stopped working

This script stopped working for me at the end of september. MFA has been enabled in our tenant, but the user that I'm using to for the script has been excluded. But no matter what I do I cannot seem to get the script to work. Has anyone else seen this issue?
Capture

Can't update contact extended properties

tried to change code to GetGALcontacts.ps1

$ContactList += Get-Contact | Select-Object DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,Country,City,Street

Outlook have these rows which i would like to update, how it can be achieved ? thanks

Business Address Street: 
Business Address City: 
Business Address Postal Code: 
Business Address Country/Region: 

EDIT 2021-02-13 16:00: Outlook mobile shows only City property, there is no problem if we could enable data import from only City property. So then i could update all contact with all address properties in one line and i think it is a good solution and less hardwork to update all these code lines.

maybe in the future release there will be a switch to enable extended properties like Photo,Country,City,Street,Department ??

Also i checked all yours PS modules and i see that all extended properties are written with such variables Photo,Country,City,Address,Department and a lot more.. more than 20.

I like to test things, if there is something i could try to do it myself let me know where i need to update powershell code to have such properties included while importing data to all employee Contacts folder because in some code if i write these variables like previous are written in some format i get an error about bad object contruction... so i think these information must be updated not just in one file but also on others...

Slow to run

The script runs without error in our environment, creates the folder for the mailbox then starts importing contacts but at a rate of about one every 4 minutes. No errors or additional information seemed to be logged.

Exception calling Autodiscoverurl

Having a little issue. Any idea what would cause this to stall at "Using Negotiate Auth" then error with the below message?

VERBOSE: Importing function 'Write-AdminAuditLog'.
2022/01/11 14:22:17 INFO Beginning contact sync for [email protected]'s mailbox
VERBOSE: Loading module from path 'C:\Users\user\OneDrive - Construction Company, Inc\Documents\Scripts\EWS-Office365-Contact-Sync-master\EWSContacts\Module\bin\Microsoft.Exchange.WebServices.dll'.
VERBOSE: Using EWS dll from Local Directory
VERBOSE: Using Negotiate Auth
PS>TerminatingError(Connect-EXCExchange): "Exception calling "AutodiscoverUrl" with "2" argument(s): "The Autodiscover service couldn't be located.""

TerminatingError(Connect-EXCExchange): "Exception calling "AutodiscoverUrl" with "2" argument(s): "The Autodiscover service couldn't be located.""
2022/01/11 14:24:28 ERROR Failed to Sync-ContactList for [email protected] Exception calling "AutodiscoverUrl" with "2" argument(s): "The Autodiscover service couldn't be located."


Windows PowerShell transcript end
End time: 20220111142428

Sync with AD Group

Hello everyone,

I would like to deploy script on AD Group. So i changed Mailbox Parameter code:

[Parameter(Mandatory=$False)]
[String[]]
$MailboxList = @(Get-ADGroupMember -Identity ExampleName -recursive | get-aduser -Properties mail | select mail),

in powersahell when i check only: Get-ADGroupMember -Identity ExampleName -recursive | get-aduser -Properties mail | select mail, i got list of users but when i use it in parameter i got mail adres in format: @{mail=[email protected]} after that i got error that email adres is in bad format. What should i do? Any sugesstions?

Contacts only seen on mobile if in "default contact" folder

Hello :)

Are you aware that contacts who are not in the "default contacts" is not seen on IOS/Android?

Right now I don't see any of my contacts from my custom folder(created with the script) to appear in my native contact app.
Sync/save is enabled inside Outlook (Mobile app)

Script ignoring parameters

Hi, first of all, this script is great and is doing a great job in getting the GAL onto our users iPhones.

However, I am trying to add some of the parameters (see below from the BAT file) but it is ignoring them. Is there anything I am doing wrong?

Thanks

Alex


@echo off

PowerShell.exe -ExecutionPolicy Bypass ^
-File "C:\Scripts\CopyGALContacts\EWSContactSync.ps1" ^
-CredentialPath "C:\Scripts\CopyGALContacts\credentials.xml" ^
-FolderName "iPhoneGAL" ^
-ExcludeContactsWithoutPhoneNumber ^
-IncludeNonUserContacts ^
-ExcludeContactsWithoutPhoneNumber ^
-LogPath "C:\Scripts\CopyGALContacts\Logs" ^

Request: Validation on Phone number

Hello

Possible to validate if the contact has a "Phone number" in any kind
if yes
SYNC to the contacts folder
if no
Throw.

So we don't end up with service accounts with no phone number

Sync-ContactList doesn't remove field from contacts detination if source field is emptied.

Hi there,
I've found an issue, say if John Smith has a phone number in his GAL in 'Business Phone' field. I pull that data into an array and push to users Contacts folders. Later John Smith stops having a work phone number and we empty the 'Business Phone' field from the GAL and do another sync.
The current processing of Sync-ContactList doesn't replicate the empty field to the end users contacts when doing a sync.

Hope that makes sense.

Sync contacts from a public folder

Hi,
using this script it would be possible to synchronize contacts from a public folder ??
what changes should be made to this line of code ??
$GALContacts = Get-GALContacts -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credentials $Credential -ExcludeContactsWithoutPhoneNumber $ExcludeContactsWithoutPhoneNumber -ExcludeSharedMailboxContacts $ExcludeSharedMailboxContacts -IncludeNonUserContacts $IncludeNonUserContacts

Error 404 and 503 since 28.April.2021

Hi,

since 28.April 2021 i have the following errors:

2021.04.29 08:03:08 FATAL Failed verify that XXX exists for [email protected] Ausnahme beim Aufrufen von "Save" mit 1 Argument(en): "The request failed. Der Remoteserver hat einen Fehler zurückgegeben: (404) Nicht gefunden."

2021.04.29 08:03:09 FATAL Failed verify that XXX exists for [email protected] Ausnahme beim Aufrufen von "Save" mit 1 Argument(en): "The request failed. Der Remoteserver hat einen Fehler zurückgegeben: (503) Server nicht verfügbar."

the script worked fine for a few weeks before.
i did not change anything on my site.

any hints?

Script stopped working

Hi, The script seems to stop working for me. Same tenant, tested with 2 accounts on different machines.
Below is a part of the log, but I can't seem to find what is causing it?

VERBOSE: The 'Troubleshoot-AgendaMail' command in the tmp_ddxde542.na3' module was imported, but because its name does not include an approved verb, it might be difficult to find. For a list of approved verbs, type Get-Verb.
VERBOSE: Importing function 'Troubleshoot-AgendaMail'.
VERBOSE: Importing function 'Undo-SoftDeletedMailbox'.
VERBOSE: Importing function 'Undo-SoftDeletedUnifiedGroup'.
VERBOSE: Importing function 'Update-DistributionGroupMember'.
VERBOSE: Importing function 'Update-HybridConfiguration'.
VERBOSE: Importing function 'Update-MaskingIndex'.
VERBOSE: Importing function 'Update-PublicFolderMailbox'.
VERBOSE: Importing function 'Update-Recipient'.
VERBOSE: Importing function 'Update-RoleGroupMember'.
VERBOSE: Importing function 'Update-SiteMailbox'.
VERBOSE: The 'Upgrade-DistributionGroup' command in the tmp_ddxde542.na3' module was imported, but because its name does not include an approved verb, it might be difficult to find. For a list of approved verbs, type Get-Verb.
VERBOSE: Importing function 'Upgrade-DistributionGroup'.
VERBOSE: The 'Validate-OutboundConnector' command in the tmp_ddxde542.na3' module was imported, but because its name does not include an approved verb, it might be difficult to find. For a list of approved verbs, type Get-Verb.
VERBOSE: Importing function 'Validate-OutboundConnector'.
VERBOSE: The 'Validate-RetentionRuleQuery' command in the tmp_ddxde542.na3' module was imported, but because its name does not include an approved verb, it might be difficult to find. For a list of approved verbs, type Get-Verb.
VERBOSE: Importing function 'Validate-RetentionRuleQuery'.
VERBOSE: The 'Validate-ShadowCalendar' command in the tmp_ddxde542.na3' module was imported, but because its name does not include an approved verb, it might be difficult to find. For a list of approved verbs, type Get-Verb.
VERBOSE: Importing function 'Validate-ShadowCalendar'.
VERBOSE: Importing function 'Write-AdminAuditLog'.
2021-03-19 09:35:41 INFO Beginning contact sync for [email protected] mailbox
VERBOSE: Loading module from path 'C:\EWSContacts\EWSContacts\Module\bin\Microsoft.Exchange.WebServices.dll'.
VERBOSE: Using EWS dll from Local Directory
VERBOSE: Using Modern Auth
VERBOSE: Loading module from path 'C:\EWSContacts\EWSContacts\Module\bin\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'.


Windows PowerShell transcript end
End time: 20210319093610


Exclude users with "Hide from address lists"

Hi!
I'm executing the script with the switch -ExcludeContactWithoutPhoneNumber and it works fine but I'm also getting users that are hidden from the gal. Any ideas on how to exclude those as well?

Script stops synching contacts after 4-5 minutes

Hi,

Currently I'm trying to synchronize our GAL (around 3000 contacts) to our users contacts folder (a custom one) but it always stops after the letter "G" (which takes 4-5 minutes) to get there. The script doesn't crash but just goes to the next "mailbox" in the $MailboxList and then start importing/updating the same amount of contacts. I don't see any error in the logs.

Do you have any idea what can cause this issue? I tried to run the same script on a VM but I'm getting experiencing the same issue there.

Kind regards,
Mats

Only internal contacts (Users/Mailboxes) showing

Hi, I've been trying to get this working. I've had to tweak a few parts of it to work for what I need, but after running it's leaving a folder (with the name I specified) and the only contacts inside are those that are actual users. No contacts added to the exchange contact list appear to have synchronised. Please can you assist? :)

MailContact Sync

Hi,
I'm trying to use the script but instead of syncing only MailUser and UserMailbox (RecipientType), i want to sync the GAL with MailUser + MailContact.
I can list MailContact with Get-MailContact
I'm trying to add the required commands to the script but I'm having difficulties.

Firewall needs to make it work

Hello, if you try to use this script behind a restrictive firewall. Probably you will get an error like this:

Write-Log : Failed to fetch Global Address List Contacts from Office 365 Directory En línea: 77 Carácter: 3 Write-Log -Level "FATAL" -Message "Failed to fetch Global Add ... CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Write Log

But if you go to: https://docs.microsoft.com/en-us/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide

You can solve it whitelisting these domains and networks:

*.msftidentity.com, *.msidentity.com, account.activedirectory.windowsazure.com, accounts.accesscontrol.windows.net, adminwebservice.microsoftonline.com, api.passwordreset.microsoftonline.com, autologon.microsoftazuread-sso.com, becws.microsoftonline.com, clientconfig.microsoftonline-p.net, companymanager.microsoftonline.com, device.login.microsoftonline.com, graph.microsoft.com, graph.windows.net, login.microsoft.com, login.microsoftonline.com, login.microsoftonline-p.com, login.windows.net, logincert.microsoftonline.com, loginex.microsoftonline.com, login-us.microsoftonline.com, nexus.microsoftonline-p.com, passwordreset.microsoftonline.com, provisioningapi.microsoftonline.com 20.190.128.0/18, 40.126.0.0/18, 2603:1006:2000::/48, 2603:1007:200::/48, 2603:1016:1400::/48, 2603:1017::/48, 2603:1026:3000::/48, 2603:1027:1::/48, 2603:1036:3000::/48, 2603:1037:1::/48, 2603:1046:2000::/48, 2603:1047:1::/48, 2603:1056:2000::/48, 2603:1057:2::/48

By the way, thanks for the script!

FeatureRequest: Limit Sync to UserMailbox

Hi

i tried to find a way to limit the Sync applied to only UserMailboxes without Resource or Shared-Mailboxes.

Normaly this whould be like "Get-Mailbox -RecipientTypeDetails UserMailbox"
But this is of course not possible at the Get-Mailboxes -Connect... command if used "DIRECTORY".

# If 'DIRECTORY' is used for $MailboxList, fetch all Mailboxes from the administrator account's Office 365 directory if ($MailboxList -eq "DIRECTORY") { $MailboxList = Get-Mailboxes -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credentials $Credential }

Is it possible you add a "filter" like this to only apply to almost "real users"?
Regards and thank you very much for your engagement with this great script!

ERROR Failed to Sync-ContactList

Hello

I have tried multiple times to use this script but I always face the same issue, no matter the way to connect (classic or Oauth). This is the ERROR message i get :

2020/07/29 15:59:07 INFO Beginning contact sync for [email protected]'s mailbox
EN CLAIR : Chargement du module à partir du chemin « C:\Scripts\GALSync2\EWSContacts\Module\bin\Microsoft.Exchange.WebServices.dll ».
EN CLAIR : Using EWS dll from Local Directory
EN CLAIR : Using Negotiate Auth
PS>Erreur de terminaison (Connect-EXCExchange) : « Exception lors de l'appel de « AutodiscoverUrl » avec « 2 » argument(s) : « The expected XML node type was XmlDeclaration, but the actual type is Element. » »

Erreur de terminaison (Connect-EXCExchange) : « Exception lors de l'appel de « AutodiscoverUrl » avec « 2 » argument(s) : « The expected XML node type was XmlDeclaration, but the actual type is Element. » »
2020/07/29 15:59:11 ERROR Failed to Sync-ContactList for [email protected] Exception lors de l'appel de « AutodiscoverUrl » avec « 2 » argument(s) : « The expected XML node type was XmlDeclaration, but the actual type is Element. »

I have the exact same error with the previous version of the script, excep with a little more details :

2020/07/29 15:40:39 INFO Beginning contact sync for [email protected]'s mailbox
EN CLAIR : Chargement du module à partir du chemin « C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll ».
PS>Erreur de terminaison (Connect-EXCExchange) : « Exception lors de l'appel de « AutodiscoverUrl » avec « 2 » argument(s) : « The expected XML node type was XmlDeclaration, but the actual type is Element. » »
2020/07/29 15:40:41 FATAL Failed verify that CSH exists for [email protected] Exception lors de l'appel de « AutodiscoverUrl » avec « 2 » argument(s) : « The expected XML node type was XmlDeclaration, but the actual type is Element. »
PS>Erreur de terminaison (Write-Log) : « L’exécution de la commande s’est arrêtée, car la variable de préférence « ErrorActionPreference » ou le paramètre courant a la valeur Stop : Failed verify that CSH exists for [email protected] »

Erreur de terminaison (Write-Log) : « L’exécution de la commande s’est arrêtée, car la variable de préférence « ErrorActionPreference » ou le paramètre courant a la valeur Stop : Failed verify that CSH exists for [email protected] »
Erreur de terminaison (Write-Log) : « L’exécution de la commande s’est arrêtée, car la variable de préférence « ErrorActionPreference » ou le paramètre courant a la valeur Stop : Failed verify that CSH exists for [email protected] »
Erreur de terminaison (Write-Log) : « L’exécution de la commande s’est arrêtée, car la variable de préférence « ErrorActionPreference » ou le paramètre courant a la valeur Stop : Failed verify that CSH exists for [email protected] »
Erreur de terminaison (Write-Log) : « L’exécution de la commande s’est arrêtée, car la variable de préférence « ErrorActionPreference » ou le paramètre courant a la valeur Stop : Failed verify that CSH exists for [email protected] »
L’exécution de la commande s’est arrêtée, car la variable de préférence « ErrorActionPreference » ou le paramètre courant a la valeur Stop : Failed verify that CSH exists for [email protected]
Write-Log : Failed verify that CSH exists for [email protected]
Au caractère Ligne:56 : 4

  •         Write-Log -Level "FATAL" -Message "Failed verify that $($ ...
    
  •         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    • FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Write-Log

I have double checked and rights are fine, impersonation, script, Credentials, etc...

thanks for your feedback !

Exclude Country Code or Area Code in Phone number

Hi @grahamr975,

Is there an option to exclude an prefix in the phone number ?

Now its adding our Area code in the contacts. Its not an big issue but android does not get it correctly

So it adds the users number as : +31(0)61234567

I want to be able to add the number as : +3161234567

So exclude (0). Do you think this is possible to write this in the Set-exccontact.ps1 or other ps1 ?

Thank you for your time.

Performance / Speed Issue

Hello !
I'm not sure if this is an issue or expected / standard behavior but each contact take ~4 minutes to create . The script is currently running for 24hours and I have only 417 contacts created on my exchange specified folder.
I think the GAL is about 1200 users so it would take a very long time to run this script on DIRECTORY option (or I should take a loop on a csv file with all users adresses and run this script at the same time on all my accounts ) .

I read you run this on DIRECTORY once a week so i'd like to know if you just have few users on your directory or my contact creation speed is abnormal ?

No expected time is written in the readme so I think writting an issue about this is ok ?

Except this, this script is wonderfull and I want to thank you a lot about this, this is so usefull when you need to manage a lot of company mobile devices on Android or iPhones. (native exchange offline gal sync is an option missed from a lot of years now) .

Regards !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.