Problématique:
Si vous avez plusieurs GAL dans l'environnement de messagerie séparées à l'aide de politiques de carnet d'adresses, un utilisateur de la GAL1 peut afficher les informations de contact de l'utilisateur GAL2. Pour éviter ça, vous pouvez activer l'agent de routage ABP.
Le routage des stratégies de carnet d’adresses contrôle la façon dont les destinataires sont résolus dans les organisations utilisant des stratégies de carnet d’adresses. Lorsque l'agent de routage ABP (Address Book Policy) est installé et configuré, les utilisateurs affectés à différentes listes d’adresses globales (GAL) apparaissent en tant que destinataires externes.
Pour Installer l'agent de routage des stratégies de carnet d'adresses :
- Exécuter la commande suivante dans un environnement Exchange powershell :
Install-TransportAgent -Name "ABP Routing Agent" -TransportAgentFactory "Microsoft.Exchange.Transport.Agent.AddressBookPolicyRoutingAgent.AddressBookPolicyRoutingAgentFactory" -AssemblyPath $env:ExchangeInstallPath\TransportRoles\agents\AddressBookPolicyRoutingAgent\Microsoft.Exchange.Transport.Agent.AddressBookPolicyRoutingAgent.dll

Ignorer pour le moment le message d’avertissement indiquant que le service de transport doit être redémarré pour que vos modifications soient appliquées et passer à l'étape 2 de manière à ne redémarrer le service de transport qu'une seule fois.
- Activer l’agent en exécutant la commande suivante :
Enable-TransportAgent "ABP Routing Agent"

- Redémarrer le service de transport en exécutant la commande suivante :
Restart-Service MSExchangeTransport
- Après le redémarrage du service, vérifier que l'agent de routage des stratégies de carnet d'adresses est installé et activé en exécutant la cmdlet suivante :
Get-TransportAgent

Si l’agent de routage de carnet d’adresses est répertorié, donc il a été correctement installé.
- Activer par la suite le routage des stratégies de carnet d'adresses pour l'organisation en exécutant la commande suivante :
Set-TransportConfig -AddressBookPolicyRoutingEnabled $true

Désormais, les autres utilisateurs de la liste d’adresses globale GAL1 ne peuvent plus afficher les autres utilisateurs de la liste d’adresses globale GAL2
Attention au côté juridique de cette opération.
Dans certain cas de figure nous sommes amenés à devoir faire une liste de tout accès externe à différents types de ressources, dans le cas présent nous allons lister l'ensemble des OneDrives avec un partage externe, pour ce faire vous aurez besoin de :
- Powershell 5.1,
- Le module Sharepoint Online,
- un accès Sharepoint Admin.
Vous pouvez maintenant lancer le script en prenant soin de modifier les url de connexion (L2 et L59)
# Connection to Sharepoint Online
Connect-SPOService -Url https://contoso-admin.sharepoint.com # (Please change the connection URL)
# Get the list of All OneDrives
$AllOneDrive = Get-SPOSite -IncludePersonalSite $true -Limit all -Filter "Url -like '-my.sharepoint.com/personal/'"
# Define variables
$ArrayOneDriveMembers = @()
$SortOneDrive = $AllOneDrive | sort Url
$X = 0
$SortOneDrive | foreach {
$OneDriveUrl = $_.Url
$OneDriveOwner = $_.Owner
$OneDriveStorageQuota = $_."Storage Quota"
$OneDriveTitle = $_.Title
# Get Member of current OneDrive
Try {
$OneDriveMembers = Get-SPOUser -Site $OneDriveUrl -ErrorAction stop
}
Catch {
Write-Warning $($_)
Write-Output "$OneDriveUrl;$OneDriveTitle" | Add-Content C:\temp\Onedriveerrors.txt
}
# Get External members
$OneDriveExternal = $OneDriveMembers.where({$_.Usertype -eq "Guest"})
If ($OneDriveExternal.count -ne 0) {
Write-Host "External Users are present in $OneDriveTitle" -ForegroundColor Green
$OneDriveExternal.count
$OneDriveExternal | foreach {
$DisplayName = $_.DisplayName
$LoginName = $_.LoginName
# Store Data
$ArrayOneDriveMembers += New-Object psobject -Property @{
OneDriveUrl = $OneDriveUrl
OneDriveOwner = $OneDriveOwner
OneDriveStorageQuota = $OneDriveStorageQuota
OneDriveTitle = $OneDriveTitle
DisplayName = $DisplayName
LoginName = $LoginName
}
# Release
$DisplayName = $null
$LoginName = $null
}
}
# Release
$OneDriveUrl = $null
$OneDriveOwner = $null
$OneDriveStorageQuota = $null
$OneDriveTitle = $null
$OneDriveMembers = $null
# After 500 connection, reconnect to Sharepoint
If ($x -eq 500) {
# Connect to Sharepoint
Connect-SPOService -Url https://contoso-admin.sharepoint.com
$x =0
}
$x++
}
# Export Data
$ArrayOneDriveMembers | Export-Csv c:\temp\ExternalOneDriveMembers.csv -Encoding UTF8 -Delimiter ";" -NoTypeInformation
Dans certain cas de figure nous sommes amenés à devoir faire une liste de tout accès externe à différents types de ressources, dans le cas présent nous allons lister l'ensemble des sites Sharepoint avec un partage externe, pour ce faire vous aurez besoin de :
- Powershell 5.1,
- Le module Sharepoint Online,
- un accès Sharepoint Admin.
Vous pouvez maintenant lancer le script en prenant soin de modifier les url et identifiants (L2, L21, L74 et L88).
# Connection to Sharepoint Online
Connect-SPOService -Url https://contoso-admin.sharepoint.com # (Please change the connection URL)
# Define variables
$ArraySP = @()
$i = 0
$x = 0
# Get the list of All
$AllSPSite = Get-SPOSite -Limit All
$AllSPSite = $AllSPSite | sort Url
$AllSPSite | foreach {
$I++
$Url = $_.Url
$Owner = $_.Owner
$Title = $_.title
# If you are not in the Admin Group you will need to Grant your account as Admin
Try {
Set-SPOUser -Site $Url -LoginName "mathieu@contoso.com" -IsSiteCollectionAdmin:$true -ErrorAction Stop
$Result = $true
}
Catch {
Write-Warning $($_)
Write-Output $Url | Add-Content C:\temp\SPError.txt
$Result = $false
}
# If you're Admin you can check
If ($Result -eq $true) {
# Check Guest Access
Try {
# Get Members
$Members = Get-SPOUser -Site $Url -Limit All -ErrorAction stop
$External = $Members.where({$_.Usertype -eq "Guest"})
If ($External.count -ne 0) {
Write-Host "External found on $Title" -ForegroundColor Cyan
$External.count
$External | ForEach {
$DisplayName = $_.DisplayName
$LoginName = $_.LoginName
$Groups = $_.Groups
# Store Data
$ArraySP += New-Object psobject -Property @{
Url = $Url
Owner = $Owner
Title = $title
DisplayName = $DisplayName
LoginName = $LoginName
Groups = $Groups
}
# Release
$DisplayName = $null
$LoginName = $null
$Groups = $null
}
}
# Release
$Members = $null
$External = $null
}
Catch {
Write-Warning $($_)
Write-Host "$Title not Accessible" -ForegroundColor Yellow
Write-Host "$Url not Accessible" -ForegroundColor Magenta
Write-Output $Url | Add-Content C:\temp\SPError.txt
}
# Remove Admin Rights
Try {
Set-SPOUser -Site $Url -LoginName "mathieu@contoso.com" -IsSiteCollectionAdmin:$false
}
Catch {
Write-Warning $($_)
Write-Output $Url | Add-Content C:\temp\SPError.txt
}
}
# Release
$Url = $null
$Owner = $null
# After 200 connection, reconnect to Sharepoint
If ($x -eq 200) {
Connect-SPOService -Url https://contoso-admin.sharepoint.com # (Please change the connection URL)
$x = 0
}
$x++
}
$ArraySP | Export-Csv c:\temp\ExternalSharepointMembers.csv -Encoding UTF8 -Delimiter ";" -NoTypeInformation
Par défaut lorsque vous créez un utilisateur sur Azure AD et que vous lui attribuez une licence Office (F3, E3, E5) le OneDrive n'est pas créé directement; en effet ce dernier n'est provisionné que lorsque l'utilisateur cliquera sur Onedrive lors de sa connexion.
Lorsque vous souhaitez réaliser une migration O365 ce sujet peut être une problématique, car si les Onedrive ne sont pas créés vous pourrez difficilement lancer une migration en amont.
Il est possible de contourner ce sujet en utilisant les commandes Powershell suivantes (avec les droits minimum de "SharePoint Online administrator") :
# Conect To Sharepoint Online
Connect-SPOService -Credential $Credential -Url https://XXXXX-admin.sharepoint.com
Prenez soin de remplacer l'url de connexion par la votre.
Ensuite vous pouvez soit fournir une liste d'utilisateur, soit récupérer l'ensemble des utilisateurs possédant une licence (ici nous importons une liste) et, lancer les requêtes de création.
# Import Users
$users = Import-Csv C:\Temp\Users.csv
# Start Request
foreach ($u in $users) {
$upn = $u.userprincipalname
$list += $upn
if ($i -eq 199) {
#We reached the limit
Request-SPOPersonalSite -UserEmails $list -NoWait
Start-Sleep -Milliseconds 655
$list = @()
$i = 0
}
}
Besoin d'avoir un état des lieux de vos licences O365 (voir de l'automatiser) ?
Voici quelques lignes Powershell qui vous remontrons les informations.
Prérequis:
Vous aurez besoin de:
- Powershell 5.1
- Le module Azure AD
Code :
Connect-AzureAD
$Array = @()
$AllSKU = Get-AzureADSubscribedSku
$AllSKU | sort SkuPartNumber | foreach {
$SkuPartNumber = $_.SkuPartNumber
$Bought = $_.PrepaidUnits.enabled
$Suspended = $_.PrepaidUnits.Suspended
$Warning = $_.PrepaidUnits.Warning
$Assigned = $_.ConsumedUnits
$Rest = $Bought - $Assigned
$Array += New-Object psobject -Property @{
License = $SkuPartNumber
Bought = $Bought
Assigned = $Assigned
Will_Expired = $Warning
Suspended = $Suspended
Rest = $Rest
}
$SkuPartNumber = $null
$Bought = $null
$Assigned = $null
$Warning = $null
$Suspended = $null
$Rest = $null
}
$Array | FT License,Bought,Assigned,Will_Expired,Suspended,Rest
$Array | Export-Csv C:\temp\Licenses.csv -Delimiter ";" -Encoding UTF8 -NoTypeInformation
Bien entendu, pour l'automatiser il faudra modifier l'authentification et passer par de la moderne authentification (via un SPN).
Problème
Lorsqu'un utilisateur On premises tente de partager son calendrier avec un utilisateur Office 365, il reçoit le message d’erreur suivant :

Cause
Ce problème se produit si la stratégie de partage n’autorise pas l’utilisateur à partager le niveau de détails que l’utilisateur a défini dans l’invitation de partage.
Solution
Pour résoudre ce problème, suivez les étapes suivantes :
- Ouvrez le Centre d’administration Exchange, cliquez sur Organization --> Sharing
- Double-cliquez sur "Default Sharing Policy (DEFAULT)"

- Cette règle indique que vous ne pouvez partager que l'autorisation « Disponibilité uniquement » avec les autres organisations.
Vous pouvez soit modifier la règle de partage « Toutes les informations de calendrier, notamment l'heure, l'objet, l'emplacement et le titre » pour tous les domaines
- Ou vous créez une nouvelle règle de partage pour votre domaine smtp qui est partagé dans Office 365 et attribuez "Toutes les informations de calendrier, notamment l'heure, l'objet, l'emplacement et le titre".

- Cliquez ensuite sur "Enregistrer"
Si un jour vous souhaitez faire un état des lieux de ce qui est déjà en place en terme de partage, voici quelques liges de Powershell qui permettent de sortir la liste des OneDrive ayant un partage avec un invité.
Prenez soin de remplacer l'url de connexion au portail d'admin Sharepoint.
# Connect to Sharepoint Online
Connect-SPOService -Url https://MonTenant-admin.sharepoint.com/
# Collect all Sharepoint Sites and filter on OneDrive
$AllOneDrive = Get-SPOSite -IncludePersonalSite $true -Limit all -Filter "Url -like '-my.sharepoint.com/personal/'"
# Define variabes
$ArrayOneDriveMembers = @()
$SortOneDrive = $AllOneDrive | sort Url
$SortOneDrive | foreach {
$OneDriveUrl = $_.Url
$OneDriveOwner = $_.Owner
$OneDriveStorageQuota = $_."Storage Quota"
$OneDriveTitle = $_.Title
# Get the list of members for the current OneDrive
Try {
$OneDriveMembers = Get-SPOUser -Site $OneDriveUrl -ErrorAction stop
}
Catch {
Write-Output "$OneDriveUrl;$OneDriveTitle" | Add-Content C:\temp\Onedriveerrors.txt
}
# Define a new variable
$OneDriveExternal = $OneDriveMembers.where({$_.Usertype -eq "Guest"})
# Check if the new variable is empty, if not collect logs
If ($OneDriveExternal.count -ne 0) {
# Display some informations
Write-Host "External Users are present in $OneDriveTitle" -ForegroundColor Green
$OneDriveExternal.count
# Store Data
$OneDriveExternal | foreach {
$DisplayName = $_.DisplayName
$LoginName = $_.LoginName
$ArrayOneDriveMembers += New-Object psobject -Property @{
OneDriveUrl = $OneDriveUrl
OneDriveOwner = $OneDriveOwner
OneDriveStorageQuota = $OneDriveStorageQuota
OneDriveTitle = $OneDriveTitle
DisplayName = $DisplayName
LoginName = $LoginName
}
# Release Variables
$DisplayName = $null
$LoginName = $null
}
}
# Release variables
$OneDriveUrl = $null
$OneDriveOwner = $null
$OneDriveStorageQuota = $null
$OneDriveTitle = $null
$OneDriveMembers = $null
}
$ArrayOneDriveMembers | Export-Csv c:\temp\ExternalOneDriveMembers.csv -Encoding UTF8 -Delimiter ";" -NoTypeInformation
Lorsque vous synchronisez vos utilisateurs via "Azure Ad Connect" et, que vous avez des utilisateurs dans différents pays, la langue par défaut pour chacun des utilisateurs dépend d'un attribut de votre Active Directory OnPremise, cet attribut est le "preferredLanguage".
Il devra être construit en suivant la nomenclature "Language Culture Name" du lien ci-dessous :
https://docs.microsoft.com/en-us/previous-versions/commerce-server/ee825488(v=cs.20)?redirectedfrom=MSDN
Vous pouvez fixer cet attribut à l'aide de Powershell via la commande ci-dessous (en prenant soin de remplacer "Mathieu" par le nom de votre utilisateur) :
Get-ADUser Mathieu | Set-ADUser -Replace @{‘preferredLanguage’=”en-US”}
Ou alors en important un fichier csv pour une modification en masse, exemple de code ci-dessous.
# Import Csv and Set PreferredLanguage Attribute for each user
Import-csv C:\Temp\ToFixed.csv | foreach {
$SamAccountName = $_.SamAccountName
$Attribute = $_.Attribute
Try {
# Modifying PreferredLanguage Attribute
Set-ADUser -Identity $SamAccountName -Replace @{‘preferredLanguage’=$Attribute} -ErrorAction Stop
}
Catch {
$SamAccountName | Add-Content C:\temp\ErrorPreferredLanguage.txt
}
# Release
$SamAccountName = $null
$Attribute = $null
}
Lorsque l'on utilise Active Direcotry et Azure Active Directory, il se peut que l'on soit confronter à des conflits car l'utilisateur existe déjà dans les deux environnements (selon divers scénarios).
Quand il s'agit bien du même utilisateur (et non pas un homonyme) il est important de créer un "matching" entre les deux comptes pour que l'AD Connect puisse les voir comme un seul et même compte et les synchroniser.
Pour ce faire il existe deux méthodes:
- Le Soft Match appelé aussi SMTP Matching
- Et le Hard Match (basé sur l'ImmutableID)
Le Soft Match
Le soft match appelé aussi "smpt matching" consiste à s'appuyer sur l'adresse SMTP de l'utilisateur pour faire l'association entre les deux comptes.
Ce dernier est censé fonctionner dans la plupart des cas, mais pour cela il y a quelques conditions à respecter.
- L'utilisateur doit posseder une adresse email sur Microsoft Exchange Online.
- s'il s'agit d'un contact ou d'un groupe à extension de messagerie le soft match sera basé sur l'attribt "proxyaddresses"
- Vous ne devrez pas modifier l'adresse SMTP principale de l'utilisateur durant l'opération.
- Les adresses SMTP sont considérées comme unique assurez vous que seul cet utilisateur possède cette adresse.
Le Hard Match
Le hard match entre en action lorsque le soft match n'a pas réussi, ce dernier consiste à récupérer le GUID du compte Active Directory pour le transformer en ImmutableID et enfin l'appliquer au compte Azure Active Directory.
Cette opération permettera de faire la liaison entre les deux comptes pour n'en faire qu'un synchronisé.
"Peut-on savoir si des externes ont accès aux sites Teams ? Et si oui lesquels ?" est une question qui revient souvent quand on parle droits d'accès et O365.
Pour le savoir rien de plus simple, Powershell et de la patience.
#Connect-MicrosoftTeams
Connect-MicrosoftTeams
# Define Variables
$ArrayTeamsMembers = @()
$AllTeams = Get-Team
$AllTeams | foreach {
$GroupId = $_.GroupId
$DisplayName = $_.DisplayName
$Visibility = $_.Visibility
$Archived = $_.Archived
$MailNickName = $_.MailNickName
$Description = $_.Description
# Search External members
$Members = Get-TeamUser -GroupId $GroupId
$External = $Members.where({$_.Role -eq "Guest"})
If ($External.count -ne 0) {
Write-Host "External User(s) are present in $DisplayName" -ForegroundColor Green
$External.count
$External | foreach {
$UserId = $_.UserId
$User = $_.User
$ArrayTeamsMembers += New-Object psobject -Property @{
GroupId = $GroupId
DisplayName = $DisplayName
Visibility = $Visibility
Archived = $Archived
MailNickName = $MailNickName
Description = $Description
UserId = $UserId
User = $User
}
$UserId = $null
$User = $null
}
}
$GroupId = $null
$DisplayName = $null
$Visibility = $null
$Archived = $null
$MailNickName = $null
$Description = $null
$Members = $null
$External = $null
}
$ArrayTeamsMembers | Export-Csv c:\temp\ExternalTeamsMembers.csv -Encoding UTF8 -Delimiter ";" -NoTypeInformation