EWS-Office365-Contact-Sync
EWS-Office365-Contact-Sync copied to clipboard
ModernAuth Update
Hello,
i currently can't get the Contacts List and also can't execute the Contact Sync due to Basic auth deactivation. (Errors in particular: "Can't fetch Data" "Autodiscover failed") Is there a way, to update the Script, without making a Azure AD App? Thank you Kind regards
@benj288
Are you using the -ModernAuth flag?
Yes, i get this error however, when the script is trying to fetch the Contact info
Hey, got the same error. Is there an easy way to fix this? Thanks :)
I have so far resolved the issue regarding the fetching of the Contact info after implementing an Azure app and adapting the Get-GALContacts Module (Issue #46) However, I get following error when it is trying to Sync to the Mailbox.
VERBOSE: Loading module from path 'C:\Kontaktesynchronisierung\Skripts\SyncModul\EWSContacts\Module\bin\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'. 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.07.18 15:27:13 ERROR Kontakte Sync fehlgeschlagen fuer [email protected] Exception calling "AutodiscoverUrl" with "2" argument(s): "The Autodiscover service couldn't be located."
Is there a updated version of the Connect-EXCExchange Module and the Sync-ContactList module?
Which version of PowerShell you are using?
Can you try to run this command prior and then try again? I currently using PowerShell 4.0 on Server 2012 R2 and this helped me
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
I fixed it by installing the new [Exchange Online Powershell V2 Module ]
(https://docs.microsoft.com/en-us/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps)
and editing the "Get-GALContacts.ps1" script. (See below)
EDIT: I got the flag for "DIRECTORY" working. You need to modify the script "Get-Mailboxes.ps1" (See very bottom)
function Get-GALContacts {
<#
.SYNOPSIS
Uses Office 365 services to generate a list of contacts. Only includes contacts with an email address.
.PARAMETER ConnectionUri
Used to connect to Office 365, by default this is https://outlook.office365.com/powershell-liveid/.
.PARAMETER Credentials
Office 365 Admin Credentials
.PARAMETER ExcludeContactsWithoutPhoneNumber
Switch; Only return contacts that have a phone or mobile number
.PARAMETER ExcludeSharedMailboxContacts
Switch; Excludes contacts that are a shared mailbox, or a mailbox without a liscense
.PARAMETER IncludeNonUserContacts
Switch; Also return contacts that aren't users/mailboxes in your directory. These contacts must still have an email address.
.EXAMPLE
PS C:\> Get-GALContacts -ConnectionUri 'https://outlook.office365.com/powershell-liveid/' -Credentials $Credentials
#>
[CmdletBinding()]
param (
[Parameter(Position = 0, Mandatory = $true)]
[string]
$ConnectionUri,
[Parameter(Position = 1, Mandatory = $true)]
[System.Management.Automation.PSCredential]
$Credentials,
[Parameter(Position = 2, Mandatory = $false)]
[bool]
$ExcludeContactsWithoutPhoneNumber,
[Parameter(Position = 3, Mandatory = $false)]
[bool]
$ExcludeSharedMailboxContacts,
[Parameter(Position = 4, Mandatory = $false)]
[bool]
$IncludeNonUserContacts
)
process {
try {
# Connect to Office 365 Exchange Server using a Remote Session
Connect-ExchangeOnline -ConnectionUri $ConnectionUri -Credential $Credentials
# Import Global Address List into Powershell from Office 365 Exchange as an array
$ContactList = Get-User -ResultSize unlimited
# If the ExcludeSharedMailboxContacts switch is enabled, exclude contacts that are a shared mailbox or mailbox with no liscense
if ($ExcludeSharedMailboxContacts) {
$DirectoryList = $(Get-EXOMailbox -ResultSize unlimited | Where-Object {$_.HiddenFromAddressListsEnabled -Match "False"})
$EmailAddressList = $DirectoryList.PrimarySMTPAddress
$ContactList = $ContactList | Select-Object DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,MobilePhone | Where-Object {$EmailAddressList.Contains($_.WindowsEmailAddress)}
} else {
$ContactList = $ContactList | Select-Object DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,MobilePhone
}
# If the IncludeNonUserContacts switch is enabled, also include contacts that aren't actual users in the directory
if ($IncludeNonUserContacts) {
$ContactList += Get-Contact -ResultSize unlimited | Select-Object DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,MobilePhone
}
# If the ExcludeContactsWithoutPhoneNumber switch is enabled, exclude contacts that don't have a phone or mobile number
if ($ExcludeContactsWithoutPhoneNumber) {
$ContactList = $ContactList | Where-Object {$_.Phone -or $_.MobilePhone}
}
Disconnect-ExchangeOnline -Confirm:$false
# Only return contacts with email addresses
return $ContactList | Where-Object {$null -ne $_.WindowsEmailAddress -and "" -ne $_.WindowsEmailAddress}
} catch {
Write-Log -Level "FATAL" -Message "Failed to fetch Global Address List Contacts from Office 365 Directory" -exception $_.Exception.Message
}
}
}
This is the Get-Mailboxes.ps1 script
function Get-Mailboxes {
<#
.SYNOPSIS
Uses Office 365 services to generate a list of contacts
.PARAMETER ConnectionUri
Used to connect to Office 365, by default this is https://outlook.office365.com/powershell-liveid/.
.PARAMETER Credentials
Office 365 Admin Credentials
.EXAMPLE
PS C:\> Get-GALContacts -ConnectionUri 'https://outlook.office365.com/powershell-liveid/' -Credentials $Credentials
#>
[CmdletBinding()]
param (
[Parameter(Position = 0, Mandatory = $true)]
[string]
$ConnectionUri,
[Parameter(Position = 1, Mandatory = $true)]
[System.Management.Automation.PSCredential]
$Credentials
)
process {
try {
# $Null = @() is a workaround for this function returning a random filename such as "tmp_z1ci55dv.kke" at the start of the output....
$Null = @(
# Connect to Office 365 Exchange Server using a Remote Session
Connect-ExchangeOnline -ConnectionUri $ConnectionUri -Credential $Credentials
$DirectoryList = $(Get-Mailbox -ResultSize unlimited | Where-Object {$_.HiddenFromAddressListsEnabled -Match "False"}).PrimarySMTPAddress
Disconnect-ExchangeOnline -Confirm:$false
)
} catch {
Write-Log -Level "FATAL" -Message "Failed to fetch user mailbox list from Office 365 directory" -exception $_.Exception.Message
}
return $DirectoryList | Where-Object {$null -ne $_ -and "" -ne $_}
}
}
Which version of PowerShell you are using?
Can you try to run this command prior and then try again? I currently using PowerShell 4.0 on Server 2012 R2 and this helped me
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Where have you added this line?
Sorry for writing again - i have made our script finally work. However, in my Azure AD Sign-in logs, there is still an entry coming up from the script. Since basic auth will be disabled on October 1st, i need to adjust the script to this.
My only problem is the Sync-ContactList.ps1 Has anyone adjusted this script for an Azure APP? If so, could you please share this with me? I would be grateful.
Kind regards Ben
@benj288 Could you source the website where you found the basic authentication depreciation date? I thought it was next year, rather than October 1st. Thanks
@benj288 Could you source the website where you found the basic authentication depreciation date? I thought it was next year, rather than October 1st. Thanks
You will find the informations here: https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online
Yes they announced it last year Did anybody adjust their scripts?
@christianneeb Where have you added the [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 In your Scripts?
@benj288 Several users have had success with setting up an Azure app for ExchangeOnline in issue #46. I'm working on an update for the main script with a tutorial for setting this up.
As for the EWS portion of the script, I don't think this needs to be changed as it's already coded to generate an OAuth token from the user credentials when using the -ModernAuth flag.
I run the script via a scheduled Task and therefor created a small script that referenced to this script here. Script is running on a Windows Server 2012 R2 with PowerShell 4.0. If you have any newer version, you wont need to add this line.
@benj288 Several users have had success with setting up an Azure app for ExchangeOnline in issue #46. I'm working on an update for the main script with a tutorial for setting this up.
As for the EWS portion of the script, I don't think this needs to be changed as it's already coded to generate an OAuth token from the user credentials when using the -ModernAuth flag.
Thank you for your info. Is there new version of the Main script working?
@benj288 I'm still working on the new version + a guide for setting up an Azure app cert. Once it's available, I'll publish it for everyone.
@benj288 and others,
I published the new OAuth script version & guide in commit 9fcfe1f06192848882564615dd9aa05e71d69970. All basic authentication has been upgraded to certificate based. If anyone has any questions, please reach out.