Vue lecture

Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
✇SharePoint & Products Technologies

La gouvernance des accès utilisateurs

Très souvent, on me demande quel est la marche à suivre pour retirer les accès d’un collaborateur qui quitte une société. Alors voici une checklist rapide des éléments à prendre en considération.

  1. Bloquer la connexion : Désactivez le compte pour empêcher les nouvelles connexions. Utilisez la commande cmdlet Revoke-MgUserSignInSession pour forcer la déconnexion de toutes les sessions immédiatement.
  2. Désactiver le compte AD local : Si votre entreprise utilise Active Directory, désactivez le compte dans l’AD local.
  3. Réinitialiser le mot de passe de l’utilisateur : Mettez à jour le compte avec un mot de passe aléatoire pour empêcher l’employé de continuer à accéder au tenant.
  4. Soumettre une demande d’effacement sélectif des applications/effacement des appareils : Si Intune est déployé, soumettez une demande d’effacement pour tous les appareils enregistrés.
  5. Soumettre une demande d’effacement ActiveSync : Si Intune n’est pas déployé, soumettez une demande d’effacement pour les appareils utilisant ActiveSync.
    • Clear-MobileDevice -AccountOnly -Identity User -NotificationEmailAddresses "admin@domain.com"
  6. Désactiver les appareils de l’utilisateur : Invalidez toute authentification basée sur un compte d’ordinateur en utilisant les cmdlets du Microsoft Graph PowerShell SDK.
    • $Device = Get-MgUserRegisteredDevice -UserId "user@domain.com"
    • Update-MgDevice -DeviceId $Device.Id -AccountEnabled:$false
  7. Activer la délégation sur OneDrive for Business : Déléguez l’accès au OneDrive for Business de l’employé à un utilisateur autorisé.
  8. Conserver la boîte aux lettres de l’utilisateur : Convertissez la boîte aux lettres de l’utilisateur en boîte aux lettres partagée ou utilisez des rétentions pour conserver la boîte aux lettres en tant que boîte aux lettres inactive.
    • L’impact sur les éléments chiffrés, tels que les emails ou les documents, peut être significatif lorsqu’un utilisateur est supprimé. Avec l’adoption croissante des étiquettes de sensibilité, des problèmes peuvent survenir pour les éléments stockés dans Microsoft 365. Les étiquettes de sensibilité appliquent des restrictions d’accès et/ou un chiffrement à ces éléments. Si les étiquettes restreignent l’accès de manière à ce qu’un seul utilisateur soit le propriétaire d’un document, et que cet utilisateur est celui qui est supprimé, il n’y a pas de moyen facile d’identifier quels documents ou éléments sont impactés par la suppression du compte utilisateur.
    • Pour résoudre ce problème, il existe une configuration appelée Super User dans Azure Rights Management Service (RMS), qui est la technologie utilisée par les étiquettes de sensibilité pour appliquer le chiffrement et/ou le contrôle d’accès. Le Super User est un compte administratif spécial qui a des droits de propriétaire sur tous les éléments protégés par Azure RMS
  9. Supprimer la licence de l’utilisateur : Réduisez les coûts de licence en supprimant la licence de l’utilisateur.
  10. Supprimer le compte utilisateur : Après une période de grâce, supprimez le compte utilisateur du système.
  11. Services avancés : Cette liste couvre les étapes de base pour les tenants Microsoft 365. Si vous avez des services avancés comme Defender for Cloud Apps, des étapes supplémentaires peuvent être nécessaires.
    • Ajouter les utilisateurs aux politiques de Defender for Cloud Apps : Cela permet de surveiller les téléchargements massifs de fichiers inexpliqués depuis Teams/SharePoint.
    • Configurer les notifications de flux de travail : Configurez un flux de travail de notification dans votre tenant pour que votre équipe IT soit informée lorsque des actions sont nécessaires.
    • Utiliser PowerAutomate pour automatiser le processus : Envisagez d’automatiser le processus en utilisant PowerAutomate cloud flow pour minimiser les interventions manuelles.

✇Office 365 for IT Pros

Microsoft Limits Graph API Requests for User Account Data

Old Limit with SignInActivity was 999 – New Limit for Azure AD Accounts is 120

Because it retrieves details of Azure AD accounts, the List Users API is one of the most heavily used of the Microsoft Graph APIs. It also underpins the Get-MgUser cmdlet from the Microsoft Graph PowerShell SDK. Microsoft generates the cmdlet from the API using a process called AutoRest, which means that changes made to the API show up soon afterward in the cmdlet.

I’ve documented some of the issues that developers must deal with when coding with the cmdlets from the Microsoft Graph PowerShell SDK. The cmdlets have been stable recently, which is a relief because tenants are migrating scripts from the Azure AD and MSOL modules. However, last week an issue erupted in a GitHub discussion that caused a lot of disruption.

In a nutshell, if you use List Users to fetch Azure AD accounts and include the SignInActivity property, the API limits the page size for results to 120 items. Calls made without specifying SignInActivity can set the page size to be anything up to 999 items.

An Unannounced Change

To help manage demand on the service, all Graph API requests limit the number of items that they return. To retrieve all matching items for a request, developers must fetch pages of results until nothing remains. When a developer knows that large numbers of items must be fetched, they often increase the page size to reduce the number of requests.

Microsoft didn’t say anything about the new restriction on requests that fetch Azure AD account data with sign-in activity. Developers only discovered the problem when programs and scripts failed. I first learned of the issue when some of the users of the Office 365 for IT Pros GitHub repository reported that a Graph request which included a $top query parameter to increase the page size to 999 items failed. For example:

$uri = "https://graph.microsoft.com/beta/users?`$select=displayName,userPrincipalName,mail,id,CreatedDateTime,signInActivity,UserType&`$top=999"
[array]$Data = Invoke-RestMethod -Method GET -Uri $Uri -ContentType "application/json" -Headers $Headers
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At line:1 char:16
+ ... ray]$Data = Invoke-RestMethod -Method GET -Uri $Uri -ContentType "app ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest)
   [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.I

As shown in Figure 2, testing with the Get-MgUser cmdlet revealed some more information in the error (“Cannot query data for more than 120 users at a time”). This was the first time I learned about a query limit:

Get-MgUser reports more useful error information

Cannot query data for more than 120 users at a time (SignInActivity)
Figure 2: Get-MgUser reports more useful error information

According to a response reported in the GitHub discussion, Microsoft support reported

The PG have confirmed that this endpoint will be transitioning from beta to General Availability (GA).

As part of this transition, changes to its behavior has been made, this includes not requesting more than 120 results per call. They recommend requesting less than 120 results per call, which can be done by setting the top parameter to, say 100.”

It’s likely that Microsoft made the change because retrieving sign-in activity data for Azure AD accounts is an expensive operation. Reducing the page size to 120 possibly makes it easier to process a request than if it asked for 999 items.

Beta Version of List Users Moving to Production

When the product group (PG) says that the endpoint is transitioning from beta to GA, it means that instead of needing to use https://graph.microsoft.com/beta/users to access sign-in activity, the data will be available through https://graph.microsoft.com/V1.0/users. If you use the Microsoft Graph PowerShell SDK, you won’t have to run the Select-MgProfile cmdlet to choose the beta endpoint. Moving the beta version of the API to the production endpoint is a good thing because there are many other account properties now only available through the beta endpoint (like license assignments).

If you use the Microsoft Graph PowerShell SDK, the Get-MgUser cmdlet is unaffected by the change if you specify the All parameter. This is because the cmdlet handles pagination internally and fetches all pages automatically without the need to specify a page size. For instance, this works:

$AccountProperties = @( ‘Id’, ‘DisplayName’, ‘SignInActivity’)
[array]$Users = Get-MgUser -All -Property $AccountProperties | Select-Object $AccountProperties

Moving to Production

Although it’s good that Microsoft is (slowly) moving the beta versions of the List Users API towards production, it’s a pity that they introduced a change that broke so many scripts and programs without any warning. At worse, this so exhibits a certain contempt for the developer community. At best, it’s a bad sign when communication with the developer community is not a priority. That’s just sad.


Insight like this doesn’t come easily. You’ve got to know the technology and understand how to look behind the scenes. Benefit from the knowledge and experience of the Office 365 for IT Pros team by subscribing to the best eBook covering Office 365 and the wider Microsoft 365 ecosystem.

✇Site Root

Blog Post: [Microsoft Teams] Consentement explicite d'enregistrement pour les réunions sur Teams.

Microsoft Teams est en constante évolution Le consentement explicite d'enregistrement pour les réunions sur Teams est désormais disponible. Teams prend désormais en charge une politique de réunion de consentement explicite d'enregistrement. Lorsque la politique est appliquée, la fenêtre de réunion Teams demandera un consentement explicite de tous les participants pour être enregistré. Avant qu'un utilisateur ne donne son consentement, l'audio, la vidéo et le partage d'écran/partage de consentement de l'utilisateur ne seront pas capturés dans l'enregistrement de la réunion. Feuille de route: https://www.microsoft.com/en-US/microsoft-365/roadmap?filters=&searchterms=107781 Disponibilité globale: Mars 2023 Le consentement explicite d'enregistrement est désactivé par défaut, il est nécessaire de mettre à jour les politiques de réunion Teams avec PowerShell, Set-CsTeamsMeetingPolicy -Identity Global -ExplicitRecordingConsent "Enabled" il sera prochainement possible de gérer ce paramètre de stratégie avec le centre d'administration Microsoft Teams. En date du blog, fonctionnalité de consentement pour activer l'enregistrement dépend du rapport de participation à la réunion pour suivre quand les utilisateurs donnent leur consentement, il est nécessaire de s'assurer que la fonctionnalité est activé pour les personnes concernées. Naviguer dans Réunions puis Stratégies de réunions , et activer Rapport de participation Après l'activation de la fonctionnalité dans une politique de réunion, toute réunion organisée par des comptes auxquels la politique est assignée nécessitera un consentement explicite pour l'enregistrement des réunions. Cette fonctionnalité est rétroactive et s'applique aux réunions organisées par les utilisateurs relevant de la portée de la politique. Pour les réunions organisées par des utilisateurs ayant le paramètre activé, les réunions Teams organisées par ces personnes demanderont le consentement explicite de tous les participants pour être enregistrées. Lorsque l'enregistrement commence, les utilisateurs voient que Teams a désactivé leur microphone et leur vidéo sur l'écran de connexion. Après avoir rejoint l'appel, Teams les informe qu'ils doivent donner leur consentement pour être enregistrés. Lorsque la politique de consentement explicite d'enregistrement est activée, la fenêtre de réunion Teams demandera à chaque participant une autorisation explicite pour enregistrer sa vidéo, sa voix, ses ressources partagées, etc. Les personnes qui n'ont pas donné leur consentement ne seront pas enregistrées. Cette fonctionnalité est une excellente amélioration pour Teams, car elle permet de répondre aux préoccupations de confidentialité liées aux enregistrements de réunions et donne aux participants un plus grand contrôle sur leurs données personnelles. L'utilisateur est notifié avoir accepté l'enregistrement. Le consentement des participants est consigné et peut être consulté dans le cadre du rapport de présence. Limitations actuelles avec l'utilisation de la fonctionnalité d'enregistrement explicite: La fonctionnalité repose sur le rapport de présence ; pour les clients qui ont désactivé le rapport de présence, les utilisateurs finaux ne pourront pas activer leur micro, leur caméra ou leur partage d’écran/partage de contenu lorsqu’un enregistrement est démarré. Si vous ne parvenez pas à activer le rapport de présence, nous vous recommandons d’attendre une mise à jour ultérieure. Pour éviter des interruptions pour les utilisateurs finaux, ils doivent utiliser la version la plus récente de Teams. Dans les réunions nécessitant un consentement explicite, les utilisateurs qui se joignent à partir de points de terminaison non pris en charge, tels que les anciennes versions client et CarPlay, ne pourront pas activer leur micro, leur caméra ou leur partage d’écran/partage de contenu pendant l’enregistrement. Les utilisateurs des salles de réunion Teams et les utilisateurs utilisant les ponts de conférences téléphoniques peuvent toujours recevoir des notifications d’enregistrement à partir d’aujourd’hui, mais ils ne peuvent pas fournir de consentement explicite à l’enregistrement et leurs données de consentement seront enregistrées comme « non applicable » ou « consentement automatique ».
✇Site Root

Blog Post: [Microsoft Teams] Changement important dans le mode de fonctionnement des licences "Teams Phone Resource Account"

Pour utiliser les réceptions automatiques et les files d'attente d'appels dans Microsoft Teams, il est nécessaire d'associer un compte de ressource à chacune de vos instances. Auparavant, une licence "Teams Phone Resource Account" devait être associé avec un compte de ressource uniquement dans le contexte dans lequel un numéro de téléphone est attribué avec cette identité. Cette licence "Teams Phone Resource Account" est anciennement connu sous le nom "Téléphonie Microsoft Teams Standard - Utilisateur virtuel". Ces licences sont gratuites, mais elles sont attribuées en fonction du nombre de licences Teams Phone Standard achetées. Les organisations disposant d'un abonnement Teams Phone reçoivent automatiquement un certain nombre de licences Teams Phone Resource Account sans frais supplémentaires. L'achat d'un plan d'appel Microsoft n'est requis que si vous souhaitez utiliser le compte de ressource pour passer des appels sortants. En fonction de la taille de votre organisation, celle-ci se voit attribuer un certain nombre de licences pour les comptes de ressources Teams Phone. Si votre organisation dispose d'un abonnement avec des fonctionnalités de système téléphonique telles que les licences Teams Phone Standard et Teams Phone avec un plan d'appel, elle bénéficie de 25 licences de compte de ressource Teams Phone sans frais supplémentaires. De plus, pour chaque tranche de 10 licences d'utilisateur de Teams Phone Standard ou de Teams Phone avec un plan d'appel dans votre organisation, une licence supplémentaire de compte de ressource Teams Phone est disponible. Il semblerait qu'il y ait eu un changement dans la licence des comptes de ressources, la licence Teams Phone Resource Account est désormais requise pour tous les comptes de ressources utilisés avec Microsoft Teams. Chacun de ces comptes de ressources doit être associés avec d'une licence Microsoft Teams Phone Resource Account pour que le système l'identifie correctement et que l'instance soit opérationnelle, qu'un numéro de téléphone y soit affecté ou non. Si vous utilisez actuellement des comptes de ressources qui ne sont pas affectés à une licence, il est important de les revoir pour vous assurer qu'ils disposent d'une licence Teams Phone Resource Account. Il ne faut pas support d'associer une licence Teams Phone Standard à un compte de ressource. L'annonce n'est pas disponible dans le centre de messagerie, mais "subtilement" partagée dans une note sur la page suivante: https://learn.microsoft.com/en-us/microsoftteams/teams-add-on-licensing/virtual-user Dans la même page, une nouvelle information précise que dans le cas où vous auriez besoin de davantage de licences de compte de ressource Teams Phone, vous pouvez en acheter au-delà de l'allocation standard des licences supplémentaires, je n'ai pas d'informations sur le prix à l'unité en date du blog.
✇Office 365 for IT Pros

Microsoft Releases Version 5 of the Microsoft Teams PowerShell Module

Major Update for the Get-CsOnlineUser Cmdlet

I don’t normally write about a new version of the Microsoft Teams PowerShell module and confine myself to updating the post covering recent module updates. However, the release of a major version is worth comment, which is the case with V5.0 of the Teams module, now available from the PowerShell Gallery (Figure 1).

V5.0 of the Microsoft Teams PowerShell module

Get-CsOnlineUser
Figure 1: V5.0 of the Microsoft Teams PowerShell module

Over the past few releases, Microsoft concentrated on “modernizing” the policy management cmdlets that Teams inherited from the Skype for Business connector. Modernization is a term to describe updating the cmdlets to recent standards to make them more reliable and robust. The Get-CsOnlineUser cmdlet is the focus for the V5.0 release.

The Use of Get-CsOnlineUser

Get-CsOnlineUser fetches details of user accounts enabled for Teams. I only use this cmdlet when I need to view details of the Teams policies assigned to accounts as I prefer using the Get-MgUser cmdlet to retrieve information about user accounts. The Get-CsOnlineUser cmdlet can return details of the Teams service plans assigned to an account (like the MCO_VIRTUAL_APPT and TEAMS_WEBINAR service plans assigned to accounts with the Teams Premium license), but these are also retrievable with Get-MgUser.

In the past, Get-CsOnlineUser hasn’t been very performant or flexible when retrieving accounts. Microsoft says that they’ve improved performance, especially when using filters to find accounts. In addition, a set of new filterable properties are available (Alias, City, CompanyName, CompanyName, HostingProvider, UserValidationErrors, OnPremEnterpriseVoiceEnabled, OnPremHostingProvider, OnPremLineURI, OnPremSIPEnabled, SipAddress, SoftDeletionTimestamp, State, Street, TeamsOwnersPolicy, WhenChanged, WhenCreated, FeatureTypes, PreferredDataLocation, andLastName).

Changes to Filtering

Another improvement is in the support of filtering operators to bring the cmdlet in line with other cmdlets that fetch user information like Get-ExoMailbox. This is server-side filtering, meaning that the server only returns items that match the filter. It’s faster to retrieve data with a server-side filter than it is to fetch items and then apply a filter on the workstation (client-side filtering).

For instance, this use of the like operator now works:

Get-CsOnlineUser -Filter {City -like "*York*"} | Format-Table DisplayName, City

DisplayName   City
-----------   ----
Terry Hegarty New York

Previous versions of the module generate the error: Get-CsOnlineUser : The filter attribute ‘city’ is not supported.

Get-CsOnlineUser now supports use of the gt (greater than), lt (less than), and le (less than or equal to) operators to filter against string properties. For instance, this works:

Get-CsOnlineUser -Filter {DisplayName -gt "James"} | Sort-Object DisplayName | Format-Table DisplayName, City

DisplayName                             City
-----------                             ----
James Abrahams                          Foxrock
James Ryan                              Foxrock
Jane Sixsmith                           Dublin

The contains operator now supports properties that contain arrays. For instance, this command returns the set of accounts enabled for Teams:

Get-CsOnlineUser -Filter {FeatureTypes -contains "Teams"} | Format-Table DisplayName

The ge operator supports filters against Teams policies (previous versions only support the eq and ne operators):

Get-CsOnlineUser -Filter {TeamsFilesPolicy -ge "*NoSP*"} | Format-Table DisplayName, TeamsFilesPolicy

My attempts to use the cmdlet to filter against the Teams Channel policy failed. I also saw inconsistent results when filtering against other policies. For instance, this returns no accounts:

Get-CsOnlineUser -Filter {TeamsMessagingPolicy -ge "B"}

Adding wildcards generates some results, but it’s hard to accept that a policy called “Advanced” has a name greater or equal to “B”:

Get-CsOnlineUser -Filter {TeamsMessagingPolicy -ge "*B*"} | Format-Table DisplayName, TeamsMessagingPolicy

DisplayName                 TeamsMessagingPolicy
-----------                 --------------------
Jane Sixsmith               Advanced
Marc Vigneau                Advanced

Interestingly, a client-side filter has problems too:

$Users = Get-CsOnlineUser | Where-Object {$_.TeamsMessagingPolicy -ge "B"} | Format-Table DisplayName
Where-Object : Cannot compare "Advanced" because it is not IComparable.
At line:1 char:29

I might be doing things in a way unanticipated by the Teams PowerShell developers, but I have been around PowerShell long enough to know when things don’t work quite the way they should. Some tweaks might still be necessary to make sure that filters work against all Teams policies in the same way.

Soft Deleted Users

Apart from the filtering changes, Get-CsOnlineUser now returns details of unlicensed users for 30 days after license removal and indicates soft-deleted users (accounts in the Azure AD recycle bin awaiting permanent removal) by showing the date and time of deletion in the SoftDeletionTimestamp property. You can find the soft-deleted users with:

Get-CsOnlineUser -Filter {SoftDeletionTimestamp -ne $Null} | Format-Table DisplayName, SoftDeletionTimestamp

DisplayName SoftDeletionTimestamp
----------- ---------------------
Ben James   04/03/2023 23:11:41

Work Still to Do

Get-CsOnlineUser is an important cmdlet used in many scripts to automate administrative processes. It’s good that Microsoft invested effort to make the Get-CsOnlineUser cmdlet work better, even if some issues still exist. Crack out the update procedure you use to refresh Microsoft 365 modules (or use my script, which handles Exchange Online, SharePoint Online, and the Microsoft Graph PowerShell SDK too) and upgrade to V5.0 of the Microsoft Teams module.


Support the work of the Office 365 for IT Pros team by subscribing to the Office 365 for IT Pros eBook. Your support pays for the time we need to track, analyze, and document the changing world of Microsoft 365 and Office 365.

✇Office 365 for IT Pros

Comparing Azure AD Guest Accounts and Exchange Online Mail Contacts

Are Guest Accounts Better Than Mail Contacts?

During an online discussion following publication of my article about how to purge guest accounts with unredeemed invitations from Azure AD, Microsoft’s Jef Kazimer said that he sees many Microsoft 365 organizations using guest accounts instead of mail contacts because guest accounts have better lifecycle management, even if the guests never sign in.

That idea got me thinking. Exchange Online is the largest Microsoft 365 workload and some organizations create many thousands of mail contacts for different reasons. For instance, they might have contacts for people in partner organizations so that users can easily find those contacts in the Global Address List (GAL). Mail contacts also exist in Exchange Server and many of the contacts now in Exchange Online originated. Hybrid organizations can synchronize on-premises contacts to Azure AD, but the management of those objects must be done on-premises.

Understanding Mail Contacts

Before comparing mail contacts with Azure AD guest accounts, we need to understand what a mail contact is. Mail contact objects exist in both the Exchange directory (EXODS) and Azure AD. For example, to create a mail contact, you run the New-MailContact cmdlet:

New-MailContact -Name Jef.Kazimer -DisplayName "Jef Kazimer" -ExternalEmailAddress "Jef.Kazimer@contoso.com" -FirstName "Jef" -LastName "Kazimer"

This action creates a contact object in both Exchange Online and Azure AD. The Exchange object is what people think of when they think about a mail contact. The Azure AD object exists to hold properties unrelated to email processing. Because it uses mail contacts as addressable email recipients, all Exchange Online really cares about is the email address. Once an object has an email address, Exchange can route messages to it and allow the object to participate in distribution lists. The Get-MailContact cmdlet confirms the details of the new contact object:

Get-MailContact -Identity Jef.Kazimer | Format-Table DisplayName, ExternalEmailAddress

DisplayName ExternalEmailAddress
----------- --------------------
Jef Kazimer SMTP:Jef.Kazimer@contoso.com

The external directory object identifier stored in the mail contact points to the Azure AD object, which we can retrieve using the Get-MgContact cmdlet from the Microsoft Graph PowerShell SDK:

Get-MgContact -OrgContactId (Get-MailContact -Identity Jef.Kazimer).ExternalDirectoryObjectId | Format-Table displayName, proxyAddresses

DisplayName ProxyAddresses
----------- --------------
Jef Kazimer {SMTP:Jef.Kazimer@contoso.com}

The mail contact is a sparse object so far. To populate the other properties that you might want users to see in the GAL (Figure 1), you must run the Set-Contact cmdlet to update the Azure AD object:

Set-Contact -Identity Jef.Kazimer -StreetAddress "14, Preston Villas" -City "Bellevue" -StateorProvince "Washington" -PostalCode "98004" -Phone "+1 425-214-765" -MobilePhone "+1 425-214-705" -Pager $Null -HomePhone "+1 425-270-765" -Company "Contoso" -Title "Azure AD Guru" -Department "Information Technology" -Fax "+1 425-214-761" -Initials "JK" -Notes "Distinguished Person" -Office "Liberty Square" -CountryOrRegion "United States"
A fully-populated mail contact as seen by Outlook for Windows
Figure 1: A fully-populated mail contact as seen by Outlook for Windows

The Get-MgContact cmdlet reports the newly-populated properties as does the Get-ExoRecipient cmdlet. There are some exceptions and caveats:

  • Remember to include the PropertySet All parameter to force Get-ExoRecipient to retrieve the full set of properties.
  • Get-ExoRecipient doesn’t retrieve the street address because it’s not included in the GAL.
  • Get-MgContact uses compound properties to hold some information. For instance, to see the elements of a contact’s address, you must expand the properties stored in the Addresses property:
Get-MgContact -OrgContactId (Get-MailContact -Identity Jef.Kazimer).ExternalDirectoryObjectId | Select-Object -ExpandProperty Addresses


City     CountryOrRegion OfficeLocation PostalCode State      Street
----     --------------- -------------- ---------- -----      ------
Bellevue United States   Liberty Square 98004      Washington 14, Preston Villas

Managing Mail Contacts

A Set-MailContact cmdlet is available to update properties of the Exchange objects, including the set of custom attributes available for all mail-enabled objects. The Set-Contact cmdlet updates the information held in Azure AD contact objects such as the address data shown above.

When administrators manage mail contacts through the Microsoft 365 admin center or Exchange admin center, they can work with both Exchange Online and Azure AD object properties. The GUI hides the fact that the settings presented to the administrator come from two directories, much like it disguises the interaction between Azure AD and Exchange when managing mailbox-enabled user accounts.

Guest Accounts and Guest Mail Users

Now that we understand mail contacts, let’s discuss the relationship between Exchange Online and Azure AD guest accounts. Following the creation of a guest account, a background process creates a special type of mail user object with a RecipientTypeDetails setting of GuestMailUser based on the properties of the guest account. The mail user object allows:

  • Guest members of Outlook groups to participate in group conversations via email.
  • Mail routing to guest accounts.
  • Guest accounts to appear in the GAL and other Exchange address lists.

Guest mail user objects exist in the Exchange directory until the removal of their linked guest accounts from Azure AD. Although you can view guest mail user objects through the Exchange admin center, the GUI won’t allow you to update their properties.Changes must be made to the guest account using the Azure AD admin center or with a Graph API (including the Microsoft Graph PowerShell SDK cmdlets). You can update the Exchange-specific properties with the Set-MailUser cmdlet.

To see the set of guest mail user objects, run the Get-ExoRecipient cmdlet:

Get-ExoRecipient -RecipientTypeDetails GuestMailUser | Format-Table DisplayName, PrimarySmtpAddress, HiddenFromAddressListsEnabled

The last property is True (the default) if the guest account isn’t visible to Exchange address lists. Run the Set-MailUser cmdlet to update HiddenFromAddressListsEnabled to True to expose the object. Here’s an example:

Set-MailUser -Identity warren.gatland@o365maestro.onmicrosoft.com -HiddenFromAddressListsEnabled $False

Note that it takes at least a day before newly exposed objects show up in the offline address look (OAB).

Adding Guest Mail Users to Distribution Lists

Because the guest mail users are routable objects, they can be added to distribution lists. This example spells things out, but it’s possible to add a guest mail user to a distribution list by passing its display name or email address without going to the bother of fetching the object with Get-MailUser.

$GuestMailUser = Get-MailUser Get-MailUser -Filter {DisplayName -eq "Warren Gatland" -and RecipientTypeDetails -eq "GuestMailUser"}
Add-DistributionGroupMember -Identity "o365maestro Contacts" -Member $GuestMailUser.Name

Move to Guest Accounts or Stay with Mail Contacts

Getting back to the original point, Jef says that guest accounts have better lifecycle management. In other words, if an organization invests in creating guest accounts instead of mail contacts, they’ll benefit from the work Microsoft does to improve how Azure AD manages external identities.

There’s some truth here. An Azure AD guest account supports more properties, including custom security attributes and support dynamic Azure AD Groups and dynamic Azure AD administrative units. They’re a Microsoft 365 entity rather than being restricted to just Exchange Online. Azure AD development for external identities, including guest accounts, is active whereas I suspect the development effort for Exchange mail contacts entered an “only fix bugs” maintenance stage years ago. On the other hand, mail contacts are simple and effective and work across hybrid Exchange organizations.

If you’re a cloud-only organization, the choice exists to use either. If you decide to use Azure AD guest accounts, the existence of guest mail user objects smoothen the transition and make sure that address lists, distribution lists, an email routing continue working. Azure AD guest accounts are a better long-term bet, but that doesn’t mean that anyone should switch anytime soon.


Learn more about how the Microsoft 365 applications like Exchange Online and Azure AD really work on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.

✇Office 365 for IT Pros

Mastering the Foibles of the Microsoft Graph PowerShell SDK

He looks happy, but he hasn't hit some of the Microsoft Graph PowerShell SDK foibles yet...
He looks happy, but he hasn’t hit some of the SDK foibles yet…

Translating Graph API Requests to PowerShell Cmdlets Sometimes Doesn’t Go So Well

The longer you work with a technology, the more you come to know about its strengths and weaknesses. I’ve been working with the Microsoft Graph PowerShell SDK for about two years now. I like the way that the SDK makes Graph APIs more accessible to people accustomed to developing PowerShell scripts, but I hate some of the SDK’s foibles.

This article describes the Microsoft Graph PowerShell SDK idiosyncrasies that cause me most heartburn. All are things to look out for when converting scripts from the Azure AD and MSOL modules before their deprecation (speaking of which, here’s an interesting tool that might help with this work).

No Respect for $Null

Sometimes you just don’t want to write something into a property and that’s what PowerShell’s $Null variable is for. But the Microsoft Graph PowerShell SDK cmdlets don’t like it when you use $Null. For example, let’s assume you want to create a new Azure AD user account. This code creates a hash table with the properties of the new account and then runs the New-MgUser cmdlet.

$NewUserProperties = @{
    GivenName = $FirstName
    Surname = $LastName
    DisplayName = $DisplayName
    JobTitle = $JobTitle
    Department = $Null
    MailNickname = $NickName
    Mail = $PrimarySmtpAddress
    UserPrincipalName = $UPN
    Country = $Country
    PasswordProfile = $NewPasswordProfile
    AccountEnabled = $true }
$NewGuestAccount = New-MgUser @NewUserProperties

New-MgUser fails because of an invalid value for the department property, even though $Null is a valid PowerShell value.

New-MgUser : Invalid value specified for property 'department' of resource 'User'.
At line:1 char:2
+  $NewGuestAccount = New-MgUser @NewUserProperties
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: ({ body = Micros...oftGraphUser1 }:<>f__AnonymousType64`1) [New-MgUser
   _CreateExpanded], RestException`1
    + FullyQualifiedErrorId : Request_BadRequest,Microsoft.Graph.PowerShell.Cmdlets.NewMgUser_CreateExpanded

One solution is to use a variable that holds a single space. Another is to pass $Null by running the equivalent Graph request using the Invoke-MgGraphRequest cmdlet. Neither are good answers to what should not happen (and we haven’t even mentioned the inability to filter on null values).

Ignoring the Pipeline

The pipeline is a fundamental building block of PowerShell. It allows objects retrieve by a cmdlet to pass to another cmdlet for processing. But despite the usefulness of the pipeline, the SDK cmdlets don’t support it and the pipeline stops stone dead whenever an SDK cmdlet is asked to process incoming objects. For example:

Get-MgUser -Filter "userType eq 'Guest'" -All | Update-MgUser -Department "Guest Accounts"
Update-MgUser : The pipeline has been stopped

Why does this happen? The cmdlet that receives objects must be able to distinguish between the different objects before it can work on them. In this instance, Get-MgUser delivers a set of guest accounts, but the Update-MgUser cmdlet does not know how to process each object because it identifies an object is through the UserId parameter whereas the inbound objects offer an identity in the Id property.

The workaround is to store the set of objects in an array and then process the objects with a ForEach loop.

Property Casing and Fetching Data

I’ve used DisplayName to refer to the display name of objects since I started to use PowerShell with Exchange Server 2007. I never had a problem with uppercasing the D and N in the property name until the Microsoft Graph PowerShell SDK came along only to find that sometimes SDK cmdlets insist on a specific form of casing for property names. Fail to comply, and you don’t get your data.

What’s irritating is that the restriction is inconsistent. For instance, both these commands work:

Get-MgGroup -Filter "DisplayName eq 'Ultra Fans'"
Get-MgGroup -Filter "displayName eq 'Ultra Fans'"

But let’s say that I want to find the group members with the Get-MgGroupMember cmdlet:

[array]$GroupMembers = Get-MgGroupMember -GroupId (Get-MgGroup -Filter "DisplayName eq 'Ultra Fans'" | Select-Object -ExpandProperty Id)

This works, but I end up with a set of identifiers pointing to individual group members. Then I remember from experience gained from building scripts to report group membership that Get-MgGroupMember (like other cmdlets dealing with membership like Get-MgAdministrationUnitMember) returns a property called AdditionalProperties holding extra information about members. So I try:

$GroupMembers.AdditionalProperties.DisplayName

Nope! But if I change the formatting to displayName, I get the member names:

$GroupMembers.AdditionalProperties.displayName
Tony Redmond
Kim Akers
James Ryan
Ben James
John C. Adams
Chris Bishop

Talk about frustrating confusion! It’s not just display names. Reference to any property in AdditionalProperties must use the same casing as used the output, like userPrincipalName and assignedLicenses.

Another example is when looking for sign-in logs. This command works because the format of the user principal name is the same way as stored in the sign-in log data:

[array]$Logs = Get-MgAuditLogSignIn -Filter "UserPrincipalName eq 'james.ryan@office365itpros.com'" -All

Uppercasing part of the user principal name causes the command to return zero hits:

[array]$Logs = Get-MgAuditLogSignIn -Filter "UserPrincipalName eq 'James.Ryan@office365itpros.com'" -All

Two SDK foibles are on show here. First, the way that cmdlets return sets of identifiers and stuff information into AdditionalProperties (something often overlooked by developers who don’t expect this to be the case). Second, the inconsistent insistence by cmdlets on exact matching for property casing.

I’m told that this is all due to the way Graph APIs work. My response is that it’s not beyond the ability of software engineering to hide complexities from end users by ironing out these kinds of issues.

GUIDs and User Principal Names

Object identification for Graph requests depends on globally unique identifiers (GUIDs). Everything has a GUID. Both Graph requests and SDK cmdlets use GUIDs to find information. But some SDK cmdlets can pass user principal names instead of GUIDs when looking for user accounts. For instance, this works:

Get-MgUser -UserId Tony.Redmond@office365itpros.com

Unless you want to include the latest sign-in activity date for the account.

Get-MgUser -UserId Tony.Redmond@office365itpros.com -Property signInActivity
Get-MgUser :
{"@odata.context":"http://reportingservice.activedirectory.windowsazure.com/$metadata#Edm.String","value":"Get By Key
only supports UserId and the key has to be a valid Guid"}

The reason is that the sign-in data comes from a different source which requires a GUID to lookup the sign-in activity for the account, so we must pass the object identifier for the account for the command to work:

Get-MgUser -UserId "eff4cd58-1bb8-4899-94de-795f656b4a18" -Property signInActivity

It’s safer to use GUIDs everywhere. Don’t depend on user principal names because a cmdlet might object – and user principal names can change.

No Fix for Problems in V2 of the Microsoft Graph PowerShell SDK

V2.0 of the Microsoft Graph PowerShell SDK is now in preview. The good news is that V2.0 delivers some nice advances. The bad news is that it does nothing to cure the weaknesses outlined here. I’ve expressed a strong opinion that Microsoft should fix the fundamental problems in the SDK before doing anything else.

I’m told that the root cause of many of the issues is the AutoRest process Microsoft uses to generate the Microsoft Graph PowerShell SDK cmdlets from Graph API metadata. It looks like we’re stuck between a rock and a hard place. We benefit enormously by having the SDK cmdlets but the process that makes the cmdlets available introduces its own issues. Let’s hope that Microsoft gets to fix (or replace) AutoRest and deliver an SDK that’s better aligned with PowerShell standards before our remaining hair falls out due to the frustration of dealing with unpredictable cmdlet behavior.


Insight like this doesn’t come easily. You’ve got to know the technology and understand how to look behind the scenes. Benefit from the knowledge and experience of the Office 365 for IT Pros team by subscribing to the best eBook covering Office 365 and the wider Microsoft 365 ecosystem.

✇Office 365 for IT Pros

Reporting Group Membership for Azure AD Guest Accounts with the Microsoft Graph PowerShell SDK

Finding Azure AD Guest Accounts in Microsoft 365 Groups

The article explaining how to report old guest accounts and their membership of Microsoft 365 Groups (and teams) in a tenant is very popular and many people use its accompanying script. The idea is to find guest accounts above a certain age (365 days – configurable in the script) and report the groups these guests are members of. Any old guest accounts that aren’t in any groups are candidates for removal.

The script uses an old technique featuring the distinguished name of guest accounts to scan for group memberships using the Get-Recipient cmdlet. The approach works, but the variation of values that can exist in distinguished names due to the inclusion of characters like apostrophes and vertical lines means that some special processing is needed to make sure that lookups work. Achieving consistency in distinguished names might be one of the reasons for Microsoft’s plan to make Exchange Online mailbox identification more effective.

In any case, time moves on and code degrades. I wanted to investigate how to use the Microsoft Graph PowerShell SDK to replace Get-Recipient. The script already uses the SDK to find Azure AD guest accounts with the Get-MgUser cmdlet.

The Graph Foundation

Graph APIs provide the foundation for all SDK cmdlets. Graph APIs provide the foundation for all SDK cmdlets. The first thing to find is an appropriate API to find group membership. I started off with getMemberGroups. The PowerShell example for the API suggests that the Get-MgDirectoryObjectMemberGroup cmdlet is the one to use. For example:

$UserId = (Get-MgUser -UserId Terry.Hegarty@Office365itpros.com).id 
[array]$Groups = Get-MgDirectoryObjectMemberGroup  -DirectoryObjectId $UserId -SecurityEnabledOnly:$False

The cmdlet works and returns a list of group identifiers that can be used to retrieve information about the groups that the user belongs to. For example:

Get-MgGroup -GroupId $Groups[0] | Format-Table DisplayName, Id, GroupTypes

DisplayName                     Id                                   GroupTypes
-----------                     --                                   ----------
All Tenant Member User Accounts 05ecf033-b39a-422c-8d30-0605965e29da {DynamicMembership, Unified}

However, because Get-MgDirectoryObjectMemberGroup returns a simple list of group identifiers, the developer must do extra work to call Get-MgGroup for each group to retrieve group properties. Not only is this extra work, calling Get-MgGroup repeatedly becomes very inefficient as the number of guests and their membership in groups increase.

Looking Behind the Scenes with Graph X-Ray

The Azure AD admin center (and the Entra admin center) both list the groups that user accounts (tenant and guests) belong to. Performance is snappy and it seemed unlikely that the code used was making multiple calls to retrieve the properties for each group. Many of the sections in these admin centers use Graph API requests to fetch information, and the Graph X-Ray tool reveals those requests. Looking at the output, it’s interesting to see that the admin center uses the beta Graph endpoint with the groups memberOf API (Figure 1).

Using the Graph X-Ray tool to find the Graph API for group membership

Azure AD Guest Accounts
Figure 1: Using the Graph X-Ray tool to find the Graph API for group membership

We can reuse the call used by the Azure AD center to create the query (containing the object identifier for the user account) and run the query using the SDK Invoke-MgGraphRequest cmdlet. One change made to the command is to include a filter to select only Microsoft 365 groups. If you omit the filter, the Graph returns all the groups a user belongs to, including security groups and distribution lists. The group information is in an array that’s in the Value property returned by the Graph request. For convenience, we put the data into a separate array.

$Uri = ("https://graph.microsoft.com/beta/users/{0}/memberOf/microsoft.graph.group?`$filter=groupTypes/any(a:a eq 'unified')&`$top=200&$`orderby=displayName&`$count=true" -f $Guest.Id)
[array]$Data = Invoke-MgGraphRequest -Uri $Uri
[array]$GuestGroups = $Data.Value

Using the Get-MgUserMemberOf Cmdlet

The equivalent SDK cmdlet is Get-MgUserMemberOf. To return the set of groups an account belongs to, the command is:

[array]$Data = Get-MgUserMemberOf -UserId $Guest.Id -All
[array]$GuestGroups = $Data.AdditionalProperties

The format of returned data marks a big difference between the SDK cmdlet and the Graph API request. The cmdlet returns group information in a hash table in the AdditionalProperties array while the Graph API request returns a simple array called Value. To retrieve group properties from the hash table, we must enumerate through its values. For instance, to return the names of the Microsoft 365 groups in the hash table, we do something like this:

[Array]$GroupNames = $Null
ForEach ($Item in $GuestGroups.GetEnumerator() ) {
   If ($Item.groupTypes -eq "unified") { $GroupNames+= $Item.displayName }
}
$GroupNames= $GroupNames -join ", "

SDK cmdlets can be inconsistent in how they return data. It’s just one of the charms of working with cmdlets that are automatically generated from code. Hopefully, Microsoft will do a better job of ironing out inconsistencies when they release V2.0 of the SDK sometime later in 2023.

A Get-MgUserTransitiveMemberOf cmdlet is also available to return the membership of nested groups. We don’t need to do this because we’re only interested in Microsoft 365 groups, which don’t support nesting. The cmdlet works in much the same way:

[array]$TransitiveData = Get-MgUserTransitiveMemberOf -UserId Kim.Akers@office365itpros.com -All

The Script Based on the SDK

Because of the extra complexity in accessing group properties, I decided to use a modified version of the Graph API request from the Azure AD admin center. It’s executed using the Invoke-MgGraphRequest cmdlet, so I think the decision is justified.

When revising the script, I made some other improvements, including adding a basic assessment of whether a guest account is stale or very stale. The assessment is intended to highlight if I should consider removing these accounts because they’re obviously not being used. Figure 2 shows the output of the report.

Report highlighting potentially obsolete guest accounts
Figure 2: Report highlighting potentially obsolete Azure AD guest accounts

You can download a copy of the script from GitHub.

Cleaning up Obsolete Azure AD Guest Accounts

Reporting obsolete Azure AD guest accounts is nice. Cleaning up old junk from Azure AD is even better. The script generates a PowerShell list with details of all guests over a certain age and the groups they belong to. To generate a list of the very stale guest accounts, filter the list:

[array]$DeleteAccounts = $Report | Where-Object {$_.StaleNess -eq "Very Stale"}

To complete the job and remove the obsolete guest accounts, a simple loop to call Remove-MgUser to process each account:

ForEach ($Account in $DeleteAccounts) {
   Write-Host ("Removing guest account for {0} with UPN {1}" -f $Account.Name, $Account.UPN) 
   Remove-MgUser -UserId $Account.Id }

Obsolete or stale guest accounts are not harmful, but their presence slows down processing like PowerShell scripts. For that reason, it’s a good idea to clean out unwanted guests periodically.


Learn about mastering the Microsoft Graph PowerShell SDK and the Microsoft 365 PowerShell modules by subscribing to the Office 365 for IT Pros eBook. Use our experience to understand what’s important and how best to protect your tenant.

✇Collabmania

SharePoint List and Microsoft List 💥 Form 💥 Formatting

sharepoint online form formatting

This is a summary of the GitHub repository to format Microsoft List Forms in SharePoint Online or to format Microsoft List in Microsoft Teams.

This is the list as per 18/03/2023. I’ll update it regularly.

Getting started with : wrapped-body

Link

Wrapped Form Body

By default, uncustomized list forms display the fields in a single column. This is generally fine, but sometimes you may want to use more horizontal space and have your fields wrap. This is not technically a format but rather a body layout. No columns or sections are specified meaning that this can be applied to any form and it won’t change the order of display or what columns are visible it simply adds the wrapping.

screenshot of the sample

Wave header and footer

This sample demonstrates how to display waves in the header and footer of a form. Waves are displayed using SVG.

screenshot of the sample

Status Header and Footer

This sample shows a customized header and footer for a form with a Status column with possible values ‘Thinking about it’, ‘Working on it’, ‘Done’, and ‘Nevermind’.

This format is intended for the Header Format and Footer Format of the form body in the Configure Layout panel. Depending on the value of the Status column, a corresponding icon and colour scheme are used.

This sample shows a customized header and footer for a form with a Status column with possible values ‘Thinking about it’, ‘Working on it’, ‘Done’, and ‘Nevermind’.

This format is intended for the Header Format and Footer Format of the form body in the Configure Layout panel. Depending on the value of the Status column, a corresponding icon and colour scheme are used.

screenshot of the sample

Ribbon Header

This sample demonstrates displaying a ribbon in the header. The values of the Title column are displayed in the ribbon.

screenshot of the sample

Event Itinerary Header

This sample shows a customized header for the item form used in the “Event itinerary” list template.

screenshot of the sample

This format is intended for the Header Format of the form body in the Configure Layout panel. The body layout shown in the screenshot can be obtained by configuring sections within the Body panel (not included in this format).

Dashed Line Header

This sample displays the Title and Description values in the heading and decorates them with dashed lines. If the Description value is empty, it will be hidden.

dashed-line-header-text-left.json 

Blank header

Link

The post SharePoint List and Microsoft List 💥 Form 💥 Formatting appeared first on Collabmania.

✇Collabmania

Model Driven ou Canvas Apps ?

model driven powerapps or canvas apps

Suite à la conférence Modern Workplace Conference 2021 à Paris, voici le support de présentation de ma session où je vous éclaire sur le choix des Canvas Apps ou Model Driven Apps.

Tout d’abord regardons les licences nécessaires puis les usages / fonctionnalités de chaque application

J’espère que cette comparaison entre les Model Driven et Canvas apps vous permettra de choisir la bonne technologie.

Sachez que depuis 2021 il est possible d’ajouter une CANVAS Apps dans une model driven sur toute la page

The post Model Driven ou Canvas Apps ? appeared first on Collabmania.

✇Collabmania

Power Automate Meeting Reminder

Problématique :

Je rate parfois les rappels d’une réunion Teams. Notification perdue parmi toutes les notifications Windows.

Solution :

Un automatisme Power Automate qui m’envoie un message dans Teams 5min avant une réunion. Cela permet, de mon téléphone ou PC, de voir le rappel sans avoir Outlook ouvert.

Je suis notifié avant une réunion

Recette :

  1. Un Power Automate qui se déclenche toutes les 5 minutes
  2. Il récupère les meeting de ma journée
  3. Compare l’heure actuelle à l’heure de début de chaque réunion
    • Si l’heure de début est dans moins de 5min, alors envoie de message via Teams à l’utilisateur

Télécharger la solution

Télécharger la recette Power Automate

Comment l’installer ?

  • Aller sur Power Automate (via www.office.com)
  • Importer le Power Automate (importer le zip précédemment téléchargé)
  • Éditer le Power automate et configurer votre Email

Vérifier que votre calendrier est sélectionné :

  • Sauvegarder
  • Activer le power automate

C’est tout bon !

Laissez vos suggestions dans les commentaires pour améliorer le Power automate !

Qu’en pensez-vous ?

The post Power Automate Meeting Reminder appeared first on Collabmania.

✇Collabmania

Programmatically remove every Teams except some by PowerShell Script

Why such script ?

My customer was a school, each year they need to recreate the Teams classroom, to reset the content and canal

The solution was to remove every Teams except the permanent one (workgroup Teams)

Below is the PowerShell Script. I use an xml file to connect easily to the Microsoft 365, avoiding re entering login / password

#By Jeff ANGAMA
#02.09.2020

#************GOAL************#
#This script remove every TEAMS except the one specified in variable $keepThoseTeams
#Write the list of TEAMS without ACCENT !!!

#************PRE REQUISITE - Run those commands to save your creds************#
#$pathToCred = "C:\credTenant.xml"
# $credential = Get-Credential
# $credential | Export-CliXml -Path $pathToCred

#************CONFIG************#
$keepThoseTeams = (
    'IT Team',
    'Support Informatique',
    'Training',
    'Administration',
    'College',
    'Coordinateurs lycee',
    'Documents de suivi lycee',
    'Budget',
    'Demande de creation de classe'
    )

#LOGS
$currentFolder = Get-Location
$timeStamp = $(((get-date).ToUniversalTime()).ToString("yyyyMMddThhmmssZ"))
$logFileName = "$currentFolder\logs\logDeleteTeams_" + $timeStamp + ".txt"
Start-Transcript -path $logFileName -append

#Connect
$pathToCred = "C:\credTenant.xml"
$credential = Import-CliXml -Path $pathToCred
Connect-MicrosoftTeams -Credential $credential

#remove accent from text, to avoid issue with contains or eq function containing accents
function get-sanitizedUTF8Input{   
    Param(
        [String]$inputString
    )
    #replace diacritics
    $sb = [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($inputString))
    
    #remove spaces and anything the above function may have missed
    return $sb
}

Get-Team | ForEach-Object { 
    $valueToCheck = get-sanitizedUTF8Input -inputString $_.DisplayName

    if($keepThoseTeams -contains $valueToCheck){
        Write-Host -ForeGroundColor Green "Do not delete this Team " $_.DisplayName $_.GroupId
    }else {
        Write-Host "Deleting Team " $_.DisplayName $_.GroupId
        #Remove-Team -GroupId $_.GroupId
    }
}

Stop-Transcript

Write-Host -ForeGroundColor Green "END OF SCRIPT"

The post Programmatically remove every Teams except some by PowerShell Script appeared first on Collabmania.

✇Collabmania

Teams – Mise à jour de l’expérience de Réunion et Mode Ensemble / Together

Microsoft a annoncé le 22 juillet de nouvelles fonctionnalités d’expérience de réunions

D’ici quelques mois ce “Together Mode” BETA des réunions sera actifs pour tous, en attendant vous pouvez l’activer dans vos paramètres. Relancer Teams après l’avoir changé.

Aperçu du mode Together (Ensemble)

L’interface de la nouvelle expérience de réunion

La barre de contrôle passe en haut

Les réunions se lancent dans une fenêtre séparée

Dans les options vous pouvez désormais activer le mode grande galerie (4 à 49 participants max) ou le mode Ensemble (Minimum 5 participants)

Nouveauté : Vous pouvez accepter plusieurs participants dans la salle d’attente

The post Teams – Mise à jour de l’expérience de Réunion et Mode Ensemble / Together appeared first on Collabmania.

✇Collabmania

Stop aux Excel partagés, utilisez Microsoft List ?

Késako ?

Microsoft List a été annoncé durant la conférence Build (19-20 Mai), est en cours de déploiement sur votre environnement Microsoft 365. Pour les environnements en Target Release, vous pouvez déjà y accéder en suivant l’astuce ci dessous

Aperçu de Microsoft List

Comment y accéder sur mon environnement (Astuce !)

Allez sur votre One Drive, changez l’adresse OneDrive.aspx

https://xxx-my.sharepoint.com/personal/prenom_nom_xx_mc/_layouts/15/onedrive.aspx

en Lists.aspx

https://xxx.sharepoint.com/personal/prenom_nom_xxx_mc/_layouts/15/lists.aspx

C’est quoi les Microsoft list ?

Les listes SharePoint existent depuis les toutes premières versions de SharePoint, cependant elles étaient réservées à une population de néophytes SharePoint, demandant une formation de 2h pour comprendre comment les créer etc.

MSLists_M365_001_Create-a-list-collage.jpg
Utilisable dans Teams ou en mode web depuis www.office.com

Avec Microsoft List, l’utilisateur crée sa liste depuis un modèle, d’une liste existante ou de zéro puis la publie pour soi (dans son One Drive) ou bien dans un groupe Office 365 Group (Teams, SharePoint etc) pour la mettre à disposition de son équipe.

La liste est partageable en interne et en externe !!!

Quoi ? Je peux partager la liste en externe ?

Tout à fait !

Oui mais la personne externe doit se créer un compte chez Microsoft ou si vous avez utilisé son compte M365, elle y accède avec ses identifiants M365.

Email reçu par la personne externe

Quel intérêt d’utiliser une liste plutôt qu’un fichier Excel partagé ou Planner ?

Vous pouvez importer une liste depuis un fichier Excel, reconfigurer les colonnes disponibles en allant dans paramètres de la liste, et la partager.

Quel intérêt par rapport à un Excel ?

  • La collaboration est sécurisée, on peut restaurer une ligne supprimée
  • Un utilisateur peut s’abonner et etre notifié des modifications, suppressions, ajouts
  • Comme dans Excel on peut mettre en forme les cellules selon des valeurs (ok c’est plus complexe ici)
  • Vous pouvez paramétrer le formulaire avec PowerApps
  • PowerAutomate permet de rajouter des automatismes à votre liste : alimenter un rapport, prévenir quelqu’un via Teams
  • La gestion des tâches peut être plus poussée, ce qui manquait à Planner

Comment ça marche ?

Une fois que vous arrivez sur la page adéquate (via office.com > Lists) ou via l’astuce que j’ai partagé plus haut, vous arrivez sur le guide de démarrage

Puis vous créez une liste depuis un modèle pour commencer à tester les fonctionnalités !

Je choisis ici “Suivi des problèmes” pour suivre le développement d’un projet informatique

Aperçu d’un ajout d’un problème

C’est le même fonctionnement que les listes SharePoint

Les listes sont configurables comme toute liste SharePoint en cliquant sur paramètres de la liste :

On peut par exemple, changer les valeurs des statuts du modèle de liste Problème que nous avons créé précédemment :

Les options de partage de la liste :

À vos collègues ou à l’extérieur ! La liste étant stockée dans votre One Drive, Microsoft permet ainsi le partage vers une personne externe à votre entreprise :

Partage de la liste à un employé ou un externe

Pour aller plus loin : Editer le formulaire de la liste dans PowerApps !

Pour aller plus loin : Déclencher une action avec Power Automate selon un événement

Par exemple pour configurer un rappel quand la tâche arrive à échéance ou envoyer un email lorsqu’un problème est urgent ?

Pour aller encore plus loin (formattage de colonnes)

On peut pour chaque colonne configurer l’affichage. Les développeurs de la communauté mettent à disposition des code JSON à appliquer aux colonnes, ainsi on peut appliquer tout type de mise en forme, voir cet article pour des exemples que j’ai référencés.

Une fonctionnalité qui simplifie l’essence de SharePoint

Les listes et les bibliothèques de documents sont les fondamentaux de Microsoft SharePoint.

En rendant la création des listes en quelques clics, Microsoft espère pousser l’adoption de ces listes qui permettent plus d’interactions qu’un simple Excel, via la Power Platform. Aussi l’historique des version et la corbeille sécurise l’information (qui n’a jamais perdu des infos d’un excel ? 👍👍✌✌)

Votre avis ?

Pensez vous remplacer certains de vos fichiers excel ou autres type de listes que vous partagez avec vos collègues ?

Que pensez vous de cette nouvelle fonctionnalité, quelles sont vos attentes ?

The post Stop aux Excel partagés, utilisez Microsoft List ? appeared first on Collabmania.

✇SharePoint & Products Technologies

OnPremise / Online / Hybride – Identité & Messagerie

Hi Folks, j’espère que vous allez bien,

Vous avez sans doute mis en place Teams pour pouvoir continuer de travailler à distance, la réservation des salles de réunion étant devenu des salles virtuelles Teams pour la plupart des sociétés qui ont déployée la solution rapidement face à cette pandémie, voir peut-être trop rapidement pour diverses questions techniques, financières, voire organisationelles. Et vous souhaitez aujourd’hui pouvoir rapprocher les deux monde (OnPremise / Legacy et celui du Cloud)

Dans cet article je vais m’attacher au fait de pouvoir rapprocher une identité Online avec une identité Cloud, et y rattacher la boite mail.

Vous avez / allez créer des comptes directement dans le cloud, et porter vos applications soit via Azure soit via 365 ou encore du PowerPlateform en low code. Mais attention, car si vous aviez des comptes existant OnPremise, vous vous retrouverez à devoir gérer alors deux environnements (un en local avec une identité, et un en online avec une autre identité, avec ou pas le même UPN) C’est ici que les choses deviennent plus complexes.

Dans ce cas de figure vous avez le besoin de rapprocher vos identités onpremise avec celle online, cela reste possible via une mécanique de « Hard Matching » – What ?

Le concept est le suivant, une fois votre système de synchronisation d’identité en place, il vous faudra faire « matcher » les identités cloud avec celle online.

Partons donc du principe suivant :

  • Vous disposez d’un AD non synchronisé
  • Vous disposez d’un Office365 avec des comptes créés à la main ou pas directement dans le Cloud
  • Donc ici vous avez 2 systèmes différents qu’il va falloir rapprocher (tant au niveau identité, que messagerie – tant qu’à faire autant profiter 🙂 )

En d’autres termes, comment passer d’un compte full cloud à un compte synchronisé ? Voyons cela ensemble

  1. Création d’une OU non synchronisée
  2. Ajout du compte utilisateur avec le même UPN que dans 365 (s’il n’existe pas, s’il existe passer cette étape)
  3. Exporter ensuite le GUID de l’utilisateur AD pour le transformer en ImmutableID (C’est ici que la magie opère)
    • ldifde -f c:\export.txt -r "(Userprincipalname=username@domain.com)" -l "objectGuid, userPrincipalName"
  4. Définissez ensuite l’ImmutableID de votre utilisateur dans 365
    • Set-MsolUser -UserPrincipalName username@domain.com -ImmutableId <ImmutableID>DRhSCJyOPAdhzoiunR8Z4Q==
  5. Déplacer votre utilisateurs dans une OU synchronisée, ou bien modifier Azure AD Connect afin de synchroniser l’OU qui contient vos utilisateurs

Votre utilisateur full cloud, est maintenant synchronisé avec votre AD local.

Oké, mais les boites aux lettres sont toujours séparées … effectivement, donc pour les migrer en cloud il y a plusieurs options, et nous allons nous attacher ici sur la synchronisation via une hybridation ce qui pourrait vous poser le plus de soucis.

Mais pourquoi est-il nécessaire de faire un reset de la BAL Online ?

Je prends comme hypothèse que l’hybridation de votre Exchange est conforme aux recommandations de l’éditeur, c’est à dire, que les connecteurs sont publiés (entrant et sortant), que les proxyaddress sont bien positionnées pour chaque utilisateur (attention à la différence entre SMTP et smtp) et que les mécanismes de coexistence sont bien en place et bien appliqués

Car rappelons le, vous avez une BAL OnPremise et une BAL Online et vous ne pourrez pas les synchroniser car la BAL Online est déjà existante. C’est la différence entre un UserMailbox et un MailUser. Ici nous recherchons à avoir cela dans 365 :

Pour avoir cela, il est nécessaire que votre utilisateur synchronisé ne soit pas de ce type :

BAL Online et non synchronisable

Mais plutôt de ce type là :

Utilisateur qui peut-être migré

Une fois que vous êtes de nouveau dans ce cas de figure, la victoire est proche 😉

Vous aurez deux cas de figures :

  • Conserver la BAL Online
    • via export PST et le centre de protection 365 (c’est long et lourd)
    • via l’utilisateur (well pourquoi pas)
    • via un outil de backup / restore (type Cloud Backup de AvePoint, Veeam, ou autres)
  • Ne pas conserver la BAL Online
    • Plus rapide (mais perte des infos de la BALs)

Ici je vais choisir de conserver les infos de la BAL 365 pour les restorer par la suite, puis faire un reset de la BAL Online, la synchroniser (ce qui deviendra alors possible), puis restorer le contenu de la BAL Online avec le backup dont je dispose, pour ne pas avoir de perte d’information.

Voici donc la timeline des actions, pour mieux situer

Il est possible que les actions de Clear ne fonctionne pas, si tel est le cas, je vous invite à vérifier que vous ne disposez d’aucunes adhérences au niveau conformité des boites aux lettres, notamment au niveau de la rétention des données. Si ces dernières sont actives, vous ne pourrez alors pas faire de clear de la BAL et d’autres alternatives seront alors à considérer.

Hope this helps,

Stay tuned & safe

mickey75019

❌